Redux-form validation based on field in other form - reactjs

I have 2 forms, in which the validation for a field in the second form is based on the value of a field in the first form. This works as expected when filling in the form top-down. However, when I change the value in the first form, the values object isn't updated in the validation.
My validate-function looks something like this:
const validate = values => {
const errors = {}
if (!values.username) {
errors.username = 'Required'
} else if (values.username.length < values.previous_field.length) {
errors.username = 'Your name can't be shorter than the previous field';
}
return errors;
}
When I change the previous field to a short value after filling in a valid username, the username-field never invalidates.

I decided to rename the forms so then would both have the same name. In this way the values do get updated, and you can use the validation in the way I would like.
Both forms are now named userdata, and the first one has all the validation logic:
#reduxForm({
form: 'userdata',
validate,
asyncValidate,
asyncBlurFields: ['car_licenceplate', 'user_zipcode']
})

Related

Is there a better way to dynamically set Values in react-hook-form on a next.ts project?

I am working on a next.ts project in which I need to dynamically set the fields of a react-hook-form form. The best way I've found to type the "name" parameter in literal string is with the as operator, as it follows:
type val = "businessName";
setValue(name as val, "Some businessName");
but I presume that there is a more elegant way to do it that maybe escapes me.
Here's the documentation about the setValue function:
https://react-hook-form.com/api/useform/setvalue
and here's a basic example of what I mean, any advice is welcome.
https://codesandbox.io/s/twilight-thunder-5ecnfu
This is actually the correct way to change your form values. But since you are using typescript you can use type definition to set the form names.
Here is an example.
Let's say you have a form with name and email. But it might be user and email. Then you can define a type like the following.
type LoginFormValues {
name: string,
email: string
} | {
user: string,
email: string
}
Then define this type with the useForm function.
const {} = useForm<LoginFormValues>()
Now, you can have dynamic form values.
There are other ways to do what you want, but this is the most elegant way.
Hope this helps.
key as any takes the error away and since I'm using the validation schema as the source, I'm not worried about it.
const data = {
"id": "somedata"
}
// Zod validation schema
const validationSchema = z.object({
id: z.string()
});
useEffect(() => {
Object.keys(validationSchema.keyof().Values).map((key) => {
if(key == 'xyz') return;
data?.[key] && setValue(key as any, data[key]);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [alerts]);

Antd: How to set nested field value using setFieldsValue

So I have a nested dynamic form, and I want to check its value using getFieldsValue. But whenever I do, it doesn't return me the values.
Using ant form hook, I create form list as <Form.List name="guests">
And assign the name to form input <FormInput name={[index, "firstName"]} label='FIRST NAME' />
I am trying to set its value using form.setFieldsValue({ [index, "firstName"]: [value]) but it doesnt works. Any suggestion regarding how to set path.
Strictly need to use setFieldsValue
First get the guests array using form.getFieldValue (You can also use getFieldsValue(['guests'])?.guests).
Then you can modify and set the value like this:
let guests = form.getFieldValue('guests');
// Check If `guests` exist & guest is an array & it's not empty
if (guests && Array.isArray(guests) && guests.length) {
// Check If firstName exists at that `index`
if (guests[index]?.firstName) {
guests[index].firstName = 'New Name';
form.setFieldsValue({ names: guests });
}
}

Required property in pnp/sp PeoplePicker not working

I have question about pnp/sp PeoplePicker.
PeoplePicker has property "required", but wen i use it in my form it is ignored.
This is my PeoplePicker code:
<PeoplePicker
required={true}
context={this.props.spContext}
personSelectionLimit={1}
onChange={this.hcRequestorPP}
showHiddenInUI={false}
principalTypes={[PrincipalType.User]}
ensureUser={true}
resolveDelay={1000}
defaultSelectedUsers={this.props.pRequestor}
disabled={false} />
What am I doing wrong?
Helo,
you are not doing anything wrong :-) Required property based on my knowledge puts asterisk next to people picker label - that's all.
If you want check in the form if user has put something into people picker field, you have to check it by yourself.
My version of form is:
every form value is stored in state.
every form field with its definition (name, type, required, ...) is stored in props (or state, or const, etc.).
before submitting form, I am checking if every required value is filled (code below)
if it is not filled I put error message under the field.
good example to start is here: https://github.com/pnp/sp-dev-fx-webparts/tree/master/samples/react-list-form
checking required
let requiredError: boolean = false;
let fieldErrors: { [fieldName: string]: string } = {...this.state.fieldErrors};
// check required
for (let i: number = 0; i < this.state.fieldsSchema.length; i++) {
if ((this.state.fieldsSchema[i].Required) && (!this.state.data[this.state.fieldsSchema[i].InternalName]) && (this.state.fieldsSchema[i].InternalName !== 'Aktivita')) {
requiredError = true;
fieldErrors = {
...fieldErrors,
[this.state.fieldsSchema[i].InternalName]: strings.FormFields.RequiredValueMessage
};
}
}
if (requiredError === true) {
this.setState({
...this.state,
fieldErrors: fieldErrors,
requiredFieldEmpty: requiredError
});
return;
}

Validate form inputs with conditional format checks

I have a function in React I am using to check the validation state of a form on submit.
The form contains 2 types of inputs.
Text and Number
However so I may have some control over the length of numbers in the field, the number input prop is set as text with a maxLength prop applied.
What I need to now do is validate that when submitting the form, the values in those inputs are indeed numbers.
My state is:
state = {
firstName: '',
lastName: '',
accountNumber: '',
sortCode1: '',
sortCode2: '',
sortCode3: ''
}
I am attempting to check this using the following....
checkValid = state => {
const rgx = new RegExp(/^[0-9]{0,9}$/)
const result = Object.keys(state).every(key => {
if (key.match(/(firstName|lastName|)/)) {
return !!state[key]
}
return rgx.test(state[key])
})
return result
}
What I am trying to achieve is a check if on firstName and lastName to ensure there are values and then a check on all other props to ensure they are numbers and numbers only.
I cannot seem to make this work though as the form either always returns true or always returns false depending on how I amend the code.
As soon as any field is invalid, I would like to simply return false.
Got some small errors with the regex. Below code should work. =) This one will return false as soon as one field is empty or the value isn't a number on the fields where you want a number.
checkValid = state => {
const rgx = new RegExp(/^[0-9]*$/)
const result = Object.keys(state).every(key => {
// If field is empty return false
if (state[key] === '') return false;
// If on firstName or lastName return true as we already know that the field isn’t empty
if (key.match(/^(firstName|lastName)$/)) return true;
// If not firstName or lastName test the field with rgx
return rgx.test(state[key])
})
return result;
}
It looks like you are trying to validate firstName and lastName based on their values simply being truthy and then the subsequent fields based on them being a number?
checkValid = ({ firstName, lastName, ...rest }) => {
const result = !!firstName && !!lastName && Object.keys(rest).every(key => !isNaN(rest[key]))
return result
}
By deconstructing state you can pick off properties and perform validation separately, with less complex code.
If your only concern is that the other fields are in fact a number, isNan should work.

How to view the ParsleyJS errors without blocking form submition

Is there a way to get the list of errors from parsley.js? I have a form that has one field that I want validate and give feedback to the user as a warning, but I don't want the error state for that field to block form submission. I am handling the form submission myself, so I'm looking for something like
$("form[name='client']").on('submit'), function(e) {
e.preventDefault();
var form = $(this);
form.parsley().validate();
// pseudo code as I don't know how to do this yet with parsley
var errors = form.parsley().errors().filter(function(err) { return err.field != field_to_ignore })
if (errors.length ) {
// error handling
} else {
// submit form
}
});
You could change the inputs or excluded options when you click on submit so that your inputs are all excluded.
My Solution is to work with two validations:
1.The first one is binding the error to the UI.
2.The second one is after adding the data-parsley-excluded=true attribute to your field_to_be_ignore.
$("#myForm").on('submit'), function(e) {
e.preventDefault();
var form = $(this);
//the first validation bind the error message to the screen
if (form.parsley().validate() == false) {
$('myFieldToIgnore').attr('data-parsley-excluded','true');
//Now let make a second validation:
form.parsley().validate();
}
else {
//submit
}
});

Resources