For complex forms, you can use JustValidate to chain multiple validation rules, handle field dependencies, manage error containers, and validate groups of inputs (like checkboxes or radio buttons).
Key Capabilities:
- Field Dependencies: Use a custom
validator function to compare a field's value against another field in the form. - Custom Error Containers: Specify a specific DOM element to display errors for a field using the
errorsContainer option in addField. - Required Groups: Use
addRequiredGroup to ensure at least one element within a group (identified by a selector) is selected. This is useful for checkbox groups or radio button groups. - Built-in Rules: Apply rules like
required, number, integer, minNumber, and maxNumber directly to fields.
Example Implementation
const validator = new JustValidate('#form-id');
validator
// Basic required field
.addField('#password', [
{ rule: 'required' },
])
// Field with dependency (matching password)
.addField('#repeat-password', [
{ rule: 'required' },
{
validator: (value, fields) => {
if (fields['#password'] && fields['#password'].elem) {
const repeatPasswordValue = fields['#password'].elem.value;
return value === repeatPasswordValue;
}
return true;
},
errorMessage: 'Passwords should be the same',
},
])
// Field with custom logic and specific error container
.addField('#consent-checkbox', [
{ rule: 'required' },
], {
errorsContainer: '#consent-errors-container',
})
// Validating a checkbox group (at least one must be checked)
.addRequiredGroup(
'#communication-checkbox-group',
'You should select at least one communication channel'
)
// Validating a radio group
.addRequiredGroup('#communication-radio-group')
// Numeric constraints
.addField('#age', [
{ rule: 'required' },
{ rule: 'number' },
{ rule: 'minNumber', value: 10 },
{ rule: 'maxNumber', value: 20 },
]);
const validator = new JustValidate('#advanced-usage_form');
validator
.addField('#advanced-usage_password', [
{
rule: 'required',
},
])
.addField('#advanced-usage_repeat-password', [
{
rule: 'required',
},
{
validator: (value, fields) => {
if (
fields['#advanced-usage_password'] &&
fields['#advanced-usage_password'].elem
) {
const repeatPasswordValue =
fields['#advanced-usage_password'].elem.value;
return value === repeatPasswordValue;
}
return true;
},
errorMessage: 'Passwords should be the same',
},
])
.addField('#advanced-usage_message', [
{
validator: (value) => {
return value !== undefined && (value as string).length > 3;
},
errorMessage: 'Message should be more than 3 letters.',
},
])
.addField(
'#advanced-usage_consent_checkbox',
[
{
rule: 'required',
},
],
{
errorsContainer: '#advanced-usage_consent_checkbox-errors-container',
}
)
.addField('#advanced-usage_favorite_animal_select', [
{
rule: 'required',
},
])
.addRequiredGroup(
'#advanced-usage_communication_checkbox_group',
'You should select at least one communication channel'
)
.addRequiredGroup('#advanced-usage_communication_radio_group')
.addField('#advanced-usage_input_number', [
{
rule: 'required',
},
{
rule: 'number',
},
])
.addField('#advanced-usage_input_integer_number', [
{
rule: 'required',
},
{
rule: 'integer',
},
])
.addField('#advanced-usage_input_number_between', [
{
rule: 'required',
},
{
rule: 'minNumber',
value: 10,
},
{
rule: 'maxNumber',
value: 20,
},
]);