Edit this page

up.form input[up-validate]
HTML selector

When a form field with this attribute is changed, the form is validated on the server and is updated with validation messages.

To validate the form, Unpoly will submit the form with an additional X-Up-Validate HTTP header. When seeing this header, the server is expected to validate (but not save) the form submission and render a new copy of the form with validation errors.

The programmatic variant of this is the up.validate() function.

Example

Let's look at a standard registration form that asks for an e-mail and password:

<form action="/users">

  <label>
    E-mail: <input type="text" name="email" />
  </label>

  <label>
    Password: <input type="password" name="password" />
  </label>

  <button type="submit">Register</button>

</form>

When the user changes the email field, we want to validate that the e-mail address is valid and still available. Also we want to change the password field for the minimum required password length. We can do this by giving both fields an up-validate attribute:

<form action="/users">

  <label>
    E-mail: <input type="text" name="email" up-validate />
  </label>

  <label>
    Password: <input type="password" name="password" up-validate />
  </label>

  <button type="submit">Register</button>

</form>

Whenever a field with up-validate changes, the form is POSTed to /users with an additional X-Up-Validate HTTP header. When seeing this header, the server is expected to validate (but not save) the form submission and render a new copy of the form with validation errors.

In Ruby on Rails the processing action should behave like this:

class UsersController < ApplicationController

  * This action handles POST /users
  def create
    user_params = params[:user].permit(:email, :password)
    @user = User.new(user_params)
    if request.headers['X-Up-Validate']
      @user.valid?  # run validations, but don't save to the database
      render 'form' # render form with error messages
    elsif @user.save?
      sign_in @user
    else
      render 'form', status: :bad_request
    end
  end

end

Note that if you're using the unpoly-rails gem you can simply say up.validate? instead of manually checking for request.headers['X-Up-Validate'].

The server now renders an updated copy of the form with eventual validation errors:

<form action="/users">

  <label class="has-error">
    E-mail: <input type="text" name="email" value="foo@bar.com" />
    Has already been taken!
  </label>

  <button type="submit">Register</button>

</form>

The <label> around the e-mail field is now updated to have the has-error class and display the validation message.

How validation results are displayed

Although the server will usually respond to a validation with a complete, fresh copy of the form, Unpoly will by default not update the entire form. This is done in order to preserve volatile state such as the scroll position of <textarea> elements.

By default Unpoly looks for a <fieldset>, <label> or <form> around the validating input field, or any element with an up-fieldset attribute. With the Bootstrap bindings, Unpoly will also look for a container with the form-group class.

You can change this default behavior by setting up.form.config.validateTargets:

// Always update the entire form containing the current field ("&")
up.form.config.validateTargets = ['form &']

You can also individually override what to update by setting the up-validate attribute to a CSS selector:

<input type="text" name="email" up-validate=".email-errors">
<span class="email-errors"></span>

Updating dependent fields

The [up-validate] behavior is also a great way to partially update a form when one fields depends on the value of another field.

Let's say you have a form with one <select> to pick a department (sales, engineering, …) and another <select> to pick an employeee from the selected department:

<form action="/contracts">
  <select name="department">...</select> <!-- options for all departments -->
  <select name="employeed">...</select> <!-- options for employees of selected department -->
</form>

The list of employees needs to be updated as the appartment changes:

<form action="/contracts">
  <select name="department" up-validate="[name=employee]">...</select>
  <select name="employee">...</select>
</form>

In order to update the department field in addition to the employee field, you could say up-validate="&, [name=employee]", or simply up-validate="form" to update the entire form.

Modifying attributes

up-validate

The CSS selector to update with the server response. This defaults to a fieldset or form group around the validating field.

This website uses cookies to improve usability and analyze traffic.
I accept or learn more