Yup conditional validation depending on if another field is valid? - javascript

I'm working on a project with a long registration form made with MUI, react-hook-forms and yup. There would be one field rendered at a time with a "Next" button to change the displayed input field to a next one (i.e. go from email field to name field). Right now it doesn't let me submit the email field and display the name field because it wants to validate both since there is no conditional validation.
I have a following schema:
const schema = yup.object().shape({
email: yup.string().email().required(),
firstName: yup.string().required("Please enter your first name"),
});
From what I've read online I understand that I need to use the .when method for the firstName field, except I don't know how to make it check based on if the email field is valid. I have tried the following:
const schema = yup.object().shape({
email: yup.string().email().required(),
firstName: yup.string().when("email", {
is: (value) => value !== undefined,
then: yup.string().required("Please enter your first name"),
otherwise: yup.string().notRequired(),
}),
});
But the value is defined onChange so it doesn't work.

I figured it out. I have divided the main schema into an emailSchema and a nameSchema, and then I used the concat method based on the step of the registration (1 being the step with the frist name field).
const schema = step === 1 ? emailSchema.concat(nameSchema) : emailSchema

Related

Angular 14: Nested FormGroup not resetting validators

I am trying to implement a nested FormGroup. So far, I am getting error while trying to reset the form. The form structure looks like this:
form: UntypedFormGroup;
this.form = this.fb.nonNullable.group({
f1: [''], f2: this.fb.nonNullable.array([], Validators.required),
f3: this.fb.nonNullable.array([]), f4: this.fb.nonNullable.array([]),
f5: this.fb.nonNullable.group({ id: ['', Validators.required] })
});
I noticed that required validator for the id field is not getting reset while resetting the overall form.
I have a similar project built on Angular 14 but there isn't any nested formgroup. But from my experience and research, I wrote this.form.reset() which is resetting the form with initial value but keeping the valid state of id field as false.
How this can be solved? Also the array fields are getting initialized with NULL even though I have set the formgroup & formarray to not allow NULL.
Current Logic:
this.form.reset();
console.log("Form after reset:", this.form.value);
console.log("Id field valid? ", this.form.get('f5').valid);
Current Output:
Output 1: Form after reset: {"f1":"","f2":[null],"f3":[],"f4":[],"f5":{"id":""}}
Output 2: Id field valid? false
NOTE: Here I only set value of f2 field so it is only having NULL now.
Expected Output:
Output 1: Form after reset: {"f1":"","f2":[],"f3":[],"f4":[],"f5":{"id":""}}
For the second output, the form should just reset to it's initial state as it is marking the mat-form-field associated with the id field as red.
Per documentation, control's value will be reset to initial value, if there is any, and if nonNullable is set to true. nonNullable does not mean that value will never be null, falsy or invalid after reset() call.
In Validator.required() documentation you read that empty field value will trigger invalid state. There is example for zero length string:
const control = new FormControl('', Validators.required);
console.log(control.errors); // {required: true}

How can I show a message if a condition isn't met in React

There is a form that uses Yup for data validation, for a field there are several conditions, it must be numerical value between 1 and 10, a default value 5, it must show an error message if the input is a number outside of the range and another error message if there is no input.
const schema = yup.object({
myInput: yup.number().default(5).min(1).max(10).required('no input'),
...
});
It shows the default value, 5, but when it is deleted and clicked on submit there is no message saying 'no input'.
Also, where should be added the error message if the input is outside of [1, 10] interval?

Any simple way to apply one validation rule to all fields by Angular 6

Consider a data model contains 20 string fields with different name ("name", "address", "company".. etc ), mapped to Angular front end as 20 input fields. Now the requirement asks to validate each fields that prevent user submit the form if any fields contain special characters.
I can work out the regex pattern but just wondering any simple way to do one validator to all fields.
There is a simple solution for this by using for example only one async validator.
For example you can group all the fields that we should verify whenever one field change in a subform
and then apply a validator to them.
Example:
this.mySubForm = this.fb.group({
field1: ['', [Validators.required]],
field2: ['', [Validators.required]],
...
field20: ['', [Validators.required]]
}, this.validatorAllFields.bind(this)
});
And define the async validator this way:
validatorAllFields(control: FormGroup): any {
if (control) {
if(control.value.field1 don't contain special char … &&
control.value.field2 don't contain special char … &&
…
control.value.field20 don't contain special char &&)
//validation is ok in this case
return null;
else
//validation fails here...
return {'formInvalid': 'true'}
} else {
return null;
}
}
You can do this without any additional package and it will work.
just implement the: do not have any special char for each control, it should be the same function for example.
You can use formGroupName for the sub form, or even avoid the use of a sub form if you want.

Lowercase and merge words together in JavaScript value

I can't seem to figure out what's going on on a form field input that gets stored inside a SharePoint column data collection.
I have a form field set when someone inputs a name that it automatically gets populated in a SharePoint list:
Here is what I currently have:
Output:
Profile Username: fhWestern Union
This is what I want to be able to achieve on all the inputs:
Output:
Profile Username: fhwesternunion
Here is the currently JavaScript code bit that I have grabbing the data:
ACI_Username: "fh" + $("#ACI_client-name-input").val(), // Username
I have tried adding this below and it did not work with my code.
.toLowerCase().val()
Replace
$("#ACI_client-name-input").val()
With
$("#ACI_client-name-input").val().replace(/\s+/g,'').toLowerCase()
this is it
ACI_Username = "fh" + $("#ACI_client-name-input").val().replace(" ", "").toLowerCase();

How create a field in mongodb schema with pre-defined values, and make the user choose the value with a radio button

I am creating an Schema to create events in the admin dashboard, and i have the following schema:
{
name: String,
date: Date,
price: String
}
Everything ok, i already create the CRUD, but now i need add a Description field in my schema. And this field is not exactly dynamic, I need it to have 4 pre-defined values:
Value 1: Blue
Value 2: Red
Value 3: Yellow
Value 4: Black
And on my form I need to bind the user choose [radio button], to an description value.
I have 4 pre-defined values, and i have 4 radio buttons in the form. Example:
Radio1 [If the user choose this, the value of description field will be blue]
Radio2 [If the user choose this, the value of description field will be red]
Radio3 [If the user choose this, the value of description field will be yellow]
Radio4 [If the user choose this, the value of description field will be the description black]
A bigger example:
If the user create an event with these values:
In the name input field, value = 'Super big event'
in the date input field, value = '20/03/2015' (in date format)
in the price input field, value = '50 dollars',
in the description radio buttons, he choose radio button with value 1, the output will be:
{
name: 'Super big event'
date: '20/03/2015' (in date format)
price: '50 dollars'
description: 'Blue'
}
I really appreciate if someone give me a hand here, i didn't find anything with google that could help me.
There are plenty of schema packages for every framework so I'd first suggest checking before opting for bespoke.
The general pattern you're after involves a separate object for each field.
So, your schema would look like this:
Schema = {
name: {type: String},
date: {type: Date},
description: {type: String, possibleValues: ['blue','red','yellow','black']}
}
Then, when you validate, you have a function that looks for a possibleValues field. If it exists, then you make sure the submitted value is a member of possibleValues.
Again, no need to build this yourself, but that's the general pattern you'd follow if you wanted to...
Hope it helps!

Categories