I have a task, I need to make a password mask for registration.
<Form.Item
name='password'
label='Password'
rules={[
{required: true, message: 'Please input your password!'},
{
validate: (_, value) => {
console.log(111)
if (/(?=.*[0-9])(?=.*[!##$%^&*])(?=.*[a-z])(?=.*[A-Z])[0-9!*+%-<>#[]{}_#a-zA-Z]{6,}/g.test(value)) {
return Promise.resolve()
}
return Promise.reject('The password must contain at least 8 characters (Latin letters, numbers and at least one character: ! * + % - < > # [ ] { } _ #)')
}
}
]}
>
<Input.Password/>
</Form.Item>
i did validate, but it doesn't work, i looked at examples, and it seems like i did an analog, but why doesn't it work...
The actual property for supplying a custom validation function for a rule is validator.
Change
validate: (_, value) => {
to:
validator: (_, value) => {
Related
Possible to validate multiple emails seperated by commas with react-hook-form .
So I have a material-ui text field which is uses react-hook-form for the validation..
Initial the input field takes a single email and it's being validated by the react-hook-form.
currently I want the user to be able to enter multiple emails separated by commas and also validates each one of them.
Currently what I'm able to do is validate when the user clicks on submit but , I want to be able to validate when the user is typing the emails.
<TextField
onChange={(e) => {
validateRecipientEmail(e.target.value);
}}
name='recipientEmail'
placeholder='sender#email.com'
fullWidth
inputRef={register({
required: true,
})}
error={errors.recipientEmail && true}
/>
{errors.recipientEmail && (
<Typography variant='caption' className={Type.textError}>
Invalid email address
</Typography>
)}
I found a way to kind of achieve the desire goal by doing the validation with onChange event listener.
but after doing the validation and populating the error on the screen. the error disappear when the input field is not focus.
Below is my validation
const validateRecipientEmail = (value) => {
let currentEmails = value.split(',').filter((e) => e && e.trim());
let regex = /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]+$/i;
for (let i = 0; i < currentEmails.length; i++) {
if (!regex.test(currentEmails[i].replace(/\s/g, ''))) {
setrecipientEmailErrorMessage(
`Enter valid Email(s) seperated by comma (,)`
);
setError('recipientEmail', {
type: 'manual',
});
}
}
if (currentEmails.length > 10) {
setrecipientEmailErrorMessage(`Emails should not be more than 10`);
setError('recipientEmail', {
type: 'manual',
});
}
};
so i found out you can pass a function to validate attribute which solves my problem
<TextField
name='recipientEmail'
placeholder='Eg. recipient#email.com'
inputRef={register({
required: true,
validate: {
validEmail: (value) => {
let currentEmails = value
.split(',')
.filter((e) => e && e.trim());
let regex = /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]+$/i;
for (let i = 0; i < currentEmails.length; i++) {
if (!regex.test(currentEmails[i].replace(/\s/g, ''))) {
return false;
}
}
},
emailLength: (value) => {
let currentEmails = value
.split(',')
.filter((e) => e && e.trim());
if (currentEmails.length > 10) {
return false;
}
},
},
})}
error={errors.recipientEmail && true}
fullWidth
/>
"validEmail" validate the email and
"emailLength" validate the email length
Thank You
Want to trim an input field when user onBlurs.
<Controller
...
onBlur={([e]) => {
const { value } = e.target;
const trimmedValue = value.trim();
console.log('trim here: ', value, value.length, trimmedValue.length);
if (trimmedValue === '') {
console.log('error!!!');
return trimmedValue;
}
return trimmedValue;
}} />
Rule:
rules={{
pattern: {
value: new RegExp(firstName.validationString, 'i'),
message: 'First name must be 2 - 100 characters with no numbers.',
},
required: firstName.mandatory && 'Must fill in first name',
}}
The function is triggered and reaching the if-statement. But is not triggering an error even though I have a rule set as required.
use this in your register or controller
validate: (value) => { return !!value.trim()}
Take a look here: https://github.com/react-hook-form/react-hook-form/issues/1650
I also want to limit the first character to just a number or a letter.
This is what I have so far to prevent the user from typing in special characters:
validate(event) {
const keycode = event.keyCode || event.which || event.type === 'paste';
const key = String.fromCharCode(keycode);
const pattern = new RegExp('^[a-zA-Z0-9\\_\\.\\-]$');
return pattern.test(key) ? key : event.preventDefault();
}
const validateMyField = (currentFieldValue, props) => {
if (currentFieldValue.match(/^[a-zA-Z0-9\\_\\.\\-]+$/)) {
return true;
}
return false;
};
const templateNameValidator = createValidator(
validateMyField,
'You are attempting to paste with characters that are not allowed. Please remove characters and try again. (special characters can only include "_","-",".")'
);
<Field
className="usaa-input"
component={Textarea}
label="Template Name"
name="name"
maxLength={128}
minRows={1}
placeholder="Enter Template Name..."
validate={composeValidators(required, templateNameValidator)}
onKeyPress={this.validate}
/>
It might be easier to use a controlled input. This is where we get and set the value to and from the state.
this.state = {inputValue: ""}
...
validateBeforeInput(e){
if(matches the chars we want){
this.setState({inputValue: e.target.value})
}
}
...
<input
value={this.state.inputValue}
onChange{validateBeforeInput} // where the magic happens
/>
I want the user to be able to type numbers up to 2000, and anything beyond 2000 would be simply fed back into the input as '2000'.
<input type="number" className="no-spin"
min="0" max="2000"
value={???}
{...eval(`${meal}_salt_amt_1`)} />
BTW, the 'max' attribute only stops the user from using the up-arrow to increment above 2000.
And redux-form's 'validate' function doesn't restrict what can be typed.
Here is how I'm restricting the value (in state) to 2000...
export function updateStats(values) {
for (var value in values){
if (value.search('salt_amt') >= 0) {
if ( values[value] > 2000) values[value] = 2000;
}
}
return {
type: UPDATE_STATS,
stats: JSON.parse(JSON.stringify(values))
};
}
... so far so good, because in my DevTools redux plugin, I can see the state of these values topping out at 2000.
But how do I force that state back into my redux-form input fields?
Mapping the state to props and using the prop isn't working. Doing so lets me type any number over 2000...
function mapStateToProps(state) {
return {
...
breakfast_salt_amt_1: state.stats.breakfast_salt_amt_1,
...
}
}
<input type="number" className="no-spin"
min="0" max="2000"
value={breakfast_salt_amt_1}
{...breakfast_salt_amt_1} />
And just using the state isn't working either...
<input type="number" className="no-spin"
min="0" max="2000"
value={state.stats.breakfast_salt_amt_1}
{...breakfast_salt_amt_1} />
// => Uncaught TypeError: Cannot read property 'stats' of null
What have I forgotten?
This is what Normalizing is for. Something like this (untested):
const under2k = value => {
if(value < 0) {
return 0
} else if(value > 2000) {
return 2000
} else {
return value
}
}
<Field
name="breakfastSaltAmt"
component="input"
type="number"
normalize={under2k}/>
export const maxLenght = max => value => {
let v;
let result = value.length > max;
if(result === false) {
v = value;
}
return v;
};
<Field
name="name"
type="text"
component={renderField}
label="Nome Completo *"
placeholder="Nome Completo"
normalize={maxLenght(10)}
/>
I think this can help you:
<input type="number" className="no-spin"
min="0" max="2000"
value={this.props.breakfast_salt_amt_1}
{...breakfast_salt_amt_1} />
I am using Parsley.js for validating a form submission on a project. One of my needs is to have Parsley require that at least one of three fields have data in them, and only fail validation if none of the three fields has data.
I am not sure from the documentation, how to accomplish this. I already have Parsley validation working on the rest of the form.
You can do that with a custom validator like so
var CheckReccursion = 0;
window.Parsley.addValidator('min3', {
validateString: function (value, requirement, instance) {
var notice =$('#notice').html(' ');
var group = $(requirement);//a class
var FieldsEmpty = 0;
var FieldsNotEmpty = 0;
var count = 0
group.each(function () {
var _val = $(this).val()
var length = _val.length
if (length > 0) {
FieldsNotEmpty++;
}
else {
FieldsEmpty++;
}
count++;
})
var isValid = (FieldsNotEmpty >=1)
//recursively execute
group.each(function (index) {
if (CheckReccursion === index) {
CheckReccursion++;
$(this).parsley().validate();
CheckReccursion = 0;
}
})
return isValid;
}
});
$(function () {
var ok=false;
var notice =$('#notice');
$('#form1').parsley().on('form:validated', function(formInstance) {
ok = formInstance.isValid({force: true});
})
.on('form:submit', function() {
if(!ok){
notice.html('Please fill at least 1 field');
return false;
}
else{
notice.html('okay');
return false;//change to true to submit form here
}
});
});
then add parsley attributes to the group of fields like so:
<form id="form1" data-parsley-validate="true">
<input type="text" name="field1"
data-parsley-min3 = ".group1"
data-parsley-min3-message = "At least 1 must be filled"
class="group1">
<input type="text" name="field2"
data-parsley-min3 = ".group1"
data-parsley-min3-message = "At least 1 must be filled"
class="group1">
<input type="text" name="field3"
data-parsley-min3 = ".group1"
data-parsley-min3-message = "At least 1 must be filled"
class="group1">
<span id="notice"></span>
<input type="submit" value="Submit">
</form>
Check out this fiddle https://jsfiddle.net/xcoL5Lur/6/
My advice is to add hidden checkbox element with the attribute:
data-parsley-mincheck="1"
now just add javascript code that checks the hidden checkbox attribute when your form input has value (and the opposite).
notice that you will need to add extra attribute to your hidden checkbox:
data-parsley-error-message="Please fill at least one input"
Another approach is to using data-parsley-group and the isValid({group,force}) method.
<input type="text" name="input1" data-parsley-group="group1">
<input type="text" name="input2" data-parsley-group="group2">
<input type="text" name="input3" data-parsley-group="group3">
$('#myform').parsley().on('form:validate', function (formInstance) {
if(formInstance.isValid({group: 'group1', force: true}) ||
formInstance.isValid({group: 'group2', force: true}) ||
formInstance.isValid({group: 'group3', force: true})) {
//do nothing
}
else {
$('#errorContainer').html('You must correctly fill at least one of these three groups!');
formInstance.validationResult = false;
}
});
you can add as many as parsley's attributes as you wish, like data-parsley-type="email" that will be validated when the given input is not empty.
we set the force: true because it it forces validation even on non-required.fields.
the html render for the errorContainer is needed because the isValid method does not affect UI nor fires events.