Skip to content

CdsForm

A form joins fields into one group: it collects their validation into a common status, intercepts the submission and can reset the values. CDS fields with the rules prop connect to the form automatically — with no registration and no extra code.

Storybook GitLab
Test coverage: 100% — good coverage
API in specs
20 / 20 props, events, slots and exposed members with a test
Test cases
36 unit · 0 browser
Known bugs
2 pinned by an it.fails test
Code coverage
100% lines · 100% branches measured in v4.0.0-alpha.13
A11y (axe)
10 recommendations in 13 stories measured in v4.0.0-alpha.11

The form does not render the fields itself — build them out of CdsTextInput, CdsSelect, CdsCheckbox and other controls. The validation rules are declared on the fields themselves through the rules prop.

Anatomy ​

The form is a native form with an optional header: the heading and the description are rendered above the content, and the fields from the default slot stay as they are. The heading is bound to the form through aria-labelledby, the description — through aria-describedby.

Variations ​

Heading and description ​

The label prop names the form, description adds an explanation under the heading. The slots of the same name accept arbitrary markup.

Validity status ​

The v-model of the form is the common status of its fields: null while the form has not been checked, false on errors and true when all the fields are valid. The status is updated on the fly — it is handy for blocking the submit button, for example.

The moment of validation ​

The validate-on prop sets the moment the check runs for all the fields of the form; the field's own validate-on takes precedence. Switch the mode and try it out: with input (the default) the error appears as you type, with blur — after leaving the field, with submit — only when the form is submitted.

Fast validation ​

The first-fail prop stops the check at the first invalid field. Submit the form: the error is shown only for "Имя", although "Фамилия" is invalid too.

States ​

disabled blocks all the fields of the form at once, readonly keeps the values visible and copyable but forbids changing them. There is no need to configure the individual fields — the state is inherited.

Hiding the details ​

The bottom block with the messages is controlled by the hide-details prop on the fields themselves: true always hides the block — errors included, false always reserves space for it, auto shows the block only when there is something to show. In dense forms use auto: the fields sit right next to each other, but the validation errors are not lost. Switch the value and submit an empty form.

Slots ​

The default slot receives the state of the form and the control methods — the "Check" and "Reset" buttons are built without a ref to the component.

Slot nameDescription
labelHeading content (replaces label)
descriptionDescription content (replaces description)
defaultForm content; slot props: isValid, errors, isValidating, validate, reset, resetValidation

Guidelines ​

Scenarios ​

Submitting a form ​

The submit event is a Promise: await event returns the validation result, and the handler decides on its own whether to send the data. The .prevent modifier turns off the native page submission. The request here is simulated with setTimeout, and the button shows loading for the duration of the "request".

Control from outside ​

The validate, reset and resetValidation methods are also available through a ref to the form. That is how the form is driven from outside — from the footer of a modal or a wizard panel, where the buttons live outside the form markup.

Vee-validate ​

The form gets along with external validation libraries. With vee-validate the schema is set in useForm, and the error messages of the fields are passed into error-messages.

Vuelidate ​

With vuelidate the rules are declared declaratively, and the field errors are passed into error-messages in the same way.

API ​

Props

NameTypeDefaultDescription
descriptionstring | undefined—Description of the form. Rendered under the heading through CdsDescription.
disabledboolean | null | undefinednullDisabled state
firstFailboolean | undefined—Stops the validation at the very first invalid field — the remaining fields are not checked
labelstring | undefined—Heading of the form. Rendered above the content through CdsDescription.
modelValueboolean | null | undefinednullResulting validity of the form: true — every field passed the check, false — there are errors, null — the form has not been validated yet
readonlyboolean | null | undefinednullRead-only state
validateOnValidateOn | undefined'input'When to run the validation of the form fields: on input, on blur or manually only

Events

NameTypeDescription
submit[payload: SubmitEventPromise]Submission of the form. The event is a Promise with the validation result.
update:modelValue[value: boolean | null]The overall validity status of the form changed (v-model).

Slots

NameTypeDescription
default{ errors: FieldValidationResult[]; isDisabled: boolean | null | undefined; isReadonly: boolean | null | undefined; isValidating: boolean; isValid: boolean | null | undefined; items: FormField[]; validate: () => Promise<FormValidationResult>; reset: () => void; resetValidation: () => void; }Main content of the form. Receives the current state and the validation methods.
descriptionanyDescription of the form (overrides the description prop).
labelanyHeading of the form (overrides the label prop).

Exposed

NameTypeDescription
errors{ id: string | number; errorMessages: string[]; }[]Validation errors of the form fields: the identifier of a field and its error messages.
isDisabledboolean | null | undefinedWhether all the fields of the form are blocked.
isReadonlyboolean | null | undefinedWhether the fields of the form are read-only.
isValidboolean | null | undefinedValidity of the form: true — every field passed the check, false — there are errors, null — the form has not been validated yet.
isValidatingbooleanWhether the form is being validated right now.
items{ id: string | number; validate: () => Promise<string[]>; reset: () => Promise<void>; resetValidation: () => Promise<void>; vm: Raw<ComponentInternalInstance>; isValid: boolean | null; errorMessages: string[]; }[]The fields registered in the form together with their validation state.
resetValidation() => voidResets the validation state only, keeping the entered values.
validate() => Promise<{ valid: boolean; errors: FieldValidationResult[] | { id: string | number; errorMessages: string[]; }[]; }>Runs the validation of all the form fields and returns the result together with the list of errors.