I have the following code
const SelectSizesDemo = () => {
const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
const errorMsg = "please provide valid email!";
const [emailArr, setEmailArr] = useState([]);
const [error, setError] = useState(false);
return (
<div>
<Select
style={{ width: "90%" }}
mode="tags"
onChange={(e) => setEmailArr(e)}
></Select>
{error && errorMsg}
</div>
);
};
I am trying to do the following. The user should input some email, if its email is valid with my pattern
then I should add it to my emailArr
, if it's not correct then I should show the error message errorMsg
, clear from the selected items and not allow the user to add it to the array.
In this code, I successfully can add any string to my array, so I want your help to understand how can I check that string with my pattern
.
Please help me to resolve this problem.
Thanks
I have the following code
const SelectSizesDemo = () => {
const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
const errorMsg = "please provide valid email!";
const [emailArr, setEmailArr] = useState([]);
const [error, setError] = useState(false);
return (
<div>
<Select
style={{ width: "90%" }}
mode="tags"
onChange={(e) => setEmailArr(e)}
></Select>
{error && errorMsg}
</div>
);
};
I am trying to do the following. The user should input some email, if its email is valid with my pattern
then I should add it to my emailArr
, if it's not correct then I should show the error message errorMsg
, clear from the selected items and not allow the user to add it to the array.
In this code, I successfully can add any string to my array, so I want your help to understand how can I check that string with my pattern
.
Please help me to resolve this problem.
Thanks
Share Improve this question edited Oct 7, 2022 at 14:01 someone asked Oct 7, 2022 at 11:49 someonesomeone 6911 gold badge6 silver badges26 bronze badges 2- updated code but not working correctly – someone Commented Oct 7, 2022 at 14:03
- So do you actually have a "problem" or are you just unsure of how to implement this? – code Commented Oct 11, 2022 at 4:34
6 Answers
Reset to default 6 +200I've worked on your updated code and figured out what was the problem.
Here is my full code before I start explaining to you what I changed.
Explanations:
So first, in order to make the
select
always have the values of theemailArr
, you need to bind it to that state with thevalue
attribute. This way, any change in theemailArr
state will be applied to theselect
values too.So simply you add:
value = {emailArr}
in theselect
.Second, in the
onChange
event you get an array in thee
object which is the array of the current values that are in the select field. So in order to test the value, you need to check the validation of the current value that was inserted to that array, which is the last one in it.In your code you check the validation of the entire array which cause it to not work correctly:
Your code:
onChange={(e) => { if (pattern.test(e)) { setEmailArr(e); } else { setError(true); } }}
Should be:
onChange={(e) => { if (e.length !== 0) {//First check if the array is not empty const value = e[e.length - 1]; //get the last(current) value from the array if (pattern.test(value)) { setEmailArr(e); setError(false); } else { setError(true); } } }}
So Here, I first check if the
e
array is not empty. Because if I check the last value of an empty array it will beundefined
- which isfalse
, and this will go to theelse
block and set the error to true, which is wrong. So that's why I start these checks only if there's something to check in the array.Next, I check the current value, if it's valid you update the state (which need to be bined with the
select
) to the new array with the new value, otherwise - it won't. And by the way, I addedsetError(false)
in case that there was an invalid try before and I want to hide the previous error now.
And a note: The emails you enter in the select must be capitalized in order to match the pattern you chose. If you don't want it then just change it to this pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/g
.
Result:
So that's it. I hope everything was clear, and please check the full code.
You can validate string with regex using this code :
onChange={(e) => {
if(pattern.test(e.target.value)){
setEmailArr(e.target.value)
}else{
setError(true)
}
}}
The goal of this solution is to tell antd to use "our" email list instead of using "their" internal list.
onChange
is called when a new element is added to the list. Check the last element and see if it's valid and then update your internal email list with antd's email list.
I use Set which automatically handles duplicates, but you could do this with only lists if you prefer.
Whenever the emailSet changes I update the email list alphabetically, but you don't need to do this if you don't want. A simple [...emailSet]
is sufficient.
onDeselect
seems to be called when the last element is removed, so I just clear the rest of the elements.
const SelectSizesDemo = () => {
const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
const [error, setError] = useState(false);
const [emailSet, setEmailSet] = useState(new Set());
const emails = useMemo(() => {
return [...emailSet].sort((a, b) => a.localeCompare(b));
}, [emailSet]);
const addEmail = (e) => {
if(e.length === 0) {
return;
}
const email = e[e.length - 1];
if (!pattern.test(email)) {
setError(errorMsg);
return;
}
setEmailSet(new Set(e))
if (error) {
setError(false);
}
};
const clearAll = () => {
setEmailSet(new Set([]));
};
return (
<div>
<Select
style={{ width: "90%" }}
mode="tags"
onChange={addEmail}
onDeselect={clearAll}
value={emails}
></Select>
{error && errorMsg}
</div>
);
};
Full solution here.
As per my understanding, You want to test the email based on the input value enter by the user and if its a valid email as per the pattern you want to store that in an array else you want to show the error message. If Yes, Here you go :
To validate an email, You can use the RegEx test()
method which executes a search for a match between a regular expression and a specified string. Returns true
if the email is valid else returns false
.
Live Demo :
const {useState, useCallback} = React;
function Example() {
const [emailArr, setEmailArr] = useState([]);
const [error, setError] = useState(false);
function isValidEmail(email) {
const pattern = new RegExp(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i);
return pattern.test(email);
}
const handleEmailValidation = event => {
const errorMsg = "please provide valid email!";
if (!isValidEmail(event.target.value)) {
setError(errorMsg);
} else {
setEmailArr(oldArray => [...oldArray, event.target.value]);
setError(null);
}
};
return (
<div>
<input
id="email"
name="email"
onChange={handleEmailValidation}
/>
{error && <span class="error">{error}</span>}
<div>{emailArr.map(entry =>
<div>{entry}</div>
)}
</div>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
As answered by Moein, pattern.test(string)
is a valid way of checking if the user's input string matches your regex pattern.
Alternatively, you can use String.match(regex)
to get an array of matches or null. This can still be used to evaluate truthiness.
Comparison was discussed here: regex.test V.S. string.match to know if a string matches a regular expression
you just need to use regex method as pattern.test(yourString)