Hilla Documentation

Reacting to Form State Changes

How to recognize different states of fields and forms and react accordingly.

You can display some parts of the form differently, depending on the form state. For example, you can disable the Submit button when the form has validation errors, or show an 'operation in progress' spinner while an async form submission is in progress.

<vaadin-button ?disabled=${this.binder.invalid}>
  Submit
</vaadin-button>

The following properties are available both for the form as a whole, and for each field independently. They are a part of the BinderNode interface. You can access these properties either for a single field, for example binder.for(model.firstname).dirty, or for the entire form, for example binder.dirty.

  • dirty: true if the current value is different from the value it was initialized with

  • visited: true if the field has gained focus

  • invalid: true if the field or the form has validation errors

  • required: true if the field is required

  • errors: a list of all validation errors for a field and its sub-fields or for the form

  • ownErrors: a list of all the validation errors for a field (without sub-fields) or for the form (not specific to any field)

The following properties are available for the form as a whole, but not for individual fields. They are a part of the Binder interface. For example, you can access these properties via binder.validating.

  • validating: true if the form is performing some validation

  • submitting: true if the form is submitting the data to a callback

Example: Disable the Form While Submission Is in Progress

If form submission could take a long time, it’s usually a good idea to give users a quick visual indication that something is happening. You may also want to prevent more form submissions until the first one is completed (for example, in a payment form).

With the TypeScript Binder API, this can be done using the submitting property. In the following example, binder.submitting is bound to the disabled property of the Submit button to disable repeating form submissions. It’s also used as a condition to render an additional 'submitting' message.

<vaadin-form-layout>
  <vaadin-text-field label="First name" ${field(model.firstname)}></vaadin-text-field>
  <vaadin-text-field label="Last name" ${field(model.lastname)}></vaadin-text-field>
</vaadin-form-layout>

<vaadin-horizontal-layout>
  <vaadin-button
    theme="primary"
    @click="${this.save}"
    ?disabled="${this.binder.invalid || this.binder.submitting}"
  >
    Save
  </vaadin-button>

  ${this.binder.submitting
    ? html`
        <span class="label">submitting</span>
        <div class="spinner"></div>
      `
    : nothing}
</vaadin-horizontal-layout>

Disable the form while submission is in progress

Example: List All Validation Errors if Validation Fails

Sometimes you may want to list all validation errors in one place. This is convenient especially in large forms, where it can be difficult to find that one field that failed the validation.

With the TypeScript Binder API, this can be done using the errors property. In the following example, the form template iterates over the binder.errors list and renders the full list under the form.

<dl>
  ${this.binder.errors.map(error => html`
    <dt>${error.property}</dt>
    <dd>${error.message}</dd>
  `)}
</dl>

Disable the form while submission is in progress