Our application has a number of different forms, with a variety of validation needs. I’ve done a bunch of reading up on JSON schema validation and I think I have an approach that will work for us. But, I wanted to run a particularly complex example by you guys to make sure I’m on the right path.
Requirements:
- An Array called addresses which allows a user to enter up to three types of addresses, Home, Alternate, and Work, where work is optional. I have this working fine with some custom renderers.
- Any field that is required should show on the form with a red label and the input should be outlined in red. Once that field is valid, the field outline should change from red to black, but the label stays red. I have this working as well.
The problem arises when I add custom validation rules to my schema. For example, Email should only be required on the objects which have a “type” value of either “Home” or “Alternate.” I used to have email in the required array at the top of the schema, but moved it to the conditional required statement at the bottom of the schema (see below). Now the email field on the Home and Alternate forms doesn’t have the required styling, although ajv correctly validates the form if no email is included on either of those objects.
So, to make sure the Email field has the correct styling, I was thinking about adding an “options”: { “required”: true } to the uischema for any element that has conditional validation logic. Then I could just handle it in my custom components as needed. Would that be a valid approach or is there a better way to handle this?
"addresses": {
"type": "array",
"items": {
"type": "object",
"itemLabel": "Address",
"required": [
"type",
"address1",
"city",
"state",
"zip"
],
"properties": {
"preferred": {
"type": "boolean"
},
"type": {
"type": "string",
"enum": [
"Work",
"Home",
"Alternate"
]
},
"address1": {
"type": "string"
},
"address2": {
"type": "string"
},
"city": {
"type": "string"
},
"state": {
"type": "string"
},
"zip": {
"type": "string"
},
"country": {
"type": "string"
},
"email": {
"type": "string"
}
},
"if": {
"properties": {
"type": {
"const": "Home"
}
}
},
"then": {
"required": ["email"],
"errorMessage": {
"required": {
"email": "Email should be the correct format (eg email@emailprovider.com)."
}
}
},
"errorMessage": {
"required": {
"address1": "Address 1 is required.",
"city": "City is required.",
"state": "State is required.",
"zip": "Zip is required."
}
}
}
}