Using the [up-validate]
attribute you can implement forms where the state of some fields
depend on the value of other fields.
This is a form to purchase postage for international parcels:
The fields in this form have many dependencies between them:
We can implement this form with three [up-validate]
attributes and no additional JavaScript:
<form method="post" action="/purchases">
<fieldset>
<label for="continent">Continent</label>
<select name="continent" id="continent" up-validate="#country">...</select> <!-- mark-phrase "up-validate" -->
</fieldset>
<fieldset>
<label for="country">Country</label>
<select name="country" id="country" up-validate="#price">...</select> <!-- mark-phrase "up-validate" -->
</fieldset>
<fieldset>
<label for="weight">Weight</label>
<input name="weight" id="weight" up-validate="#price"> kg <!-- mark-phrase "up-validate" -->
</fieldset>
<fieldset>
<label for="price">Price</label>
<output id="price">23 €</output>
</fieldset>
<button>Buy stamps</button>
</form>
When a field is changed, Unpoly will automatically submit the form with an additional X-Up-Validate
HTTP header. Upon seeing this header, the server is expected to render a new form state from the
form values in the request parameters. See this example
for control flow on the server.
When the server responds with the re-rendered form state, Unpoly will update the
target selector from the changed field's [up-validate]
attribute.
For instance, when the continent is field is changed, the country field is updated.
A field with [up-validate]
may update multiple fragments
by separating their target selectors with a comma.
For instance, when the user changes the continent, the following would update the price preview in addition to the country select:
<select name="continent" up-validate="#country, #price">
...
</select>
Custom implementations of dependent fields will often exhibit race conditions, e.g. when the user is quickly changing fields while requests are still in flight.
Such issues are solved with [up-validate]
. The form will eventually show a consistent state,
regardless of how fast the user clicks or how slow the network is. In particular:
[up-validate]
or up.validate()
are batched into a single request with multiple targets.Let's walk through a challenging scenario using the postage form example above:
Once the last response is processed, all fields and the price preview show consistent values.
If you prefer to completely prevent user input during validation, give the form an
[up-watch-disable]
attribute. This will disable all form fields while validation requests are in flight:
<form method="post" action="/purchases" up-watch-disable> <!-- mark-phrase "up-watch-disable" -->
...
</form>
You may also assign [up-watch-disable]
to individual fields, or any element that contains fields.
Also see disabling fields while working.