Every feature that watches form fields for changes shares the same options:
which events to observe, how long to wait before reacting, and what to show
while a change is being processed. You set them as [up-watch-...] attributes
in HTML, or pass them as options from JavaScript.
The options on this page apply to all of these features:
| HTML | JavaScript | Purpose |
|---|---|---|
[up-watch] |
up.watch() |
Run a callback after a change |
[up-validate] |
up.validate() |
Render a new form state after a change |
[up-autosubmit] |
up.autosubmit() |
Submit a form after a change |
[up-switch] |
Switch other elements after a change |
Options for events and delays apply to all of them. Options for disabling and loading state
apply to features that render, like [up-validate] and [up-autosubmit].
Most features watch the input event by default, so they react while the user is typing.
Only validation watches the change event by default, which fires when
the user is done editing and leaves the field.
You can control which events are observed by setting an [up-watch-event] attribute:
<form action="/search">
<input name="query" up-autosubmit up-watch-event="change"> <!-- mark: up-watch-event="change" -->
</form>
From JavaScript you can pass an { event } option instead:
up.autosubmit(field, { event: 'change' })
Multiple events can be passed as a space- or comma-separated string, or as an array.
For up.watch(), [up-autosubmit] and [up-switch], Unpoly guarantees the callback is run only once per unique changed value.
[up-validate] validates on every watched event, so watching input also validates once more on change.
Sometimes fields emit non-standard events instead of change and input.
You can configure Unpoly to normalize field events so they become
observable as change or input.
For example, if a custom select component emits a myselect:chosen event on selection:
up.form.config.watchChangeEvents = ['change', 'myselect:chosen']
A watcher with [up-watch-event="change"] will now also react to a myselect:chosen event.
In the same fashion you may configure an event in up.form.config.watchInputEvents
to make it observable with [up-watch-event="input"].
Instead of configuring an array of event types, you may also set a function that accepts a form field and returns an array of event types to watch for that field.
For example, on desktop browsers date pickers inconveniently emit a change event when any date component
changes, causing multiple events as the user picks a day, month and year. In this case
we can watch blur instead of change for such fields:
up.form.config.watchChangeEvents = function(field) {
if (field.matches('input[type=date]') && isDesktop()) { // isDesktop() is your own check
return ['blur']
} else {
return ['change']
}
}
When observing the input event, you may want to wait until the user has stopped
typing before running a callback. You can do so by setting an [up-watch-delay] attribute:
<form action="/search">
<!-- Wait until the user has stopped typing for 100 milliseconds -->
<input name="query" up-autosubmit up-watch-delay="100"> <!-- mark: up-watch-delay="100" -->
</form>
From JavaScript you can pass a { delay } option instead.
For watchers of input the default delay is up.form.config.watchInputDelay (which defaults to 0).
For watchers of other events there is no default delay.
[up-switch] is never debounced, because its effects are applied on the client.
If the field's form is aborted or destroyed while waiting for a delay, the callback is unscheduled.
Info
Regardless of the delay, Unpoly guarantees that only one async callback is running concurrently. If the form is changed while an async callback is still processing, Unpoly waits until the callback concludes and then re-runs it with the latest field values.
To prevent user input while processing changes, you can disable form fields while an async callback is running.
For this set an [up-watch-disable] attribute on the form or field being watched:
<form action="/search">
<input name="query" up-autosubmit up-watch-disable> <!-- mark: up-watch-disable -->
</form>
By default, setting [up-watch-disable] will cause all fields in the form to be disabled while processing.
To only disable some form controls,
set the value of [up-watch-disable] to any selector that matches fields or buttons.
From JavaScript you can pass a { disable } option instead.
When a callback for [up-watch] or up.watch() renders, it must pass these options on.
Its third argument holds the options parsed from the field's [up-watch-...] attributes.
Forward them to the function that renders (see callback arguments):
up.watch('input.query', function(value, name, options) { // mark: options
return up.reload('main', { ...options, params: { query: value }}) // mark: options
})
Tip
To disable fields while submitting (instead of while watching), use
[up-disable]instead.
To signal to users that you're processing changes, you can show arbitrary loading state while an async callback is running.
To apply a preview, set an [up-watch-preview] attribute on the form or field being watched:
<form action="/search">
<input name="query" up-autosubmit up-watch-preview="spinner"> <!-- mark: up-watch-preview="spinner" -->
</form>
To show a placeholder while working, use an [up-watch-placeholder] attribute:
<form action="/search">
<input name="query" up-autosubmit up-watch-placeholder="#results-placeholder"> <!-- mark: up-watch-placeholder="#results-placeholder" -->
</form>
From JavaScript you can pass a { preview } or { placeholder } option instead.
While a validation or autosubmit request is loading, feedback classes
like .up-active and .up-loading are set by default.
To not set them, use an [up-watch-feedback="false"] attribute or pass a { feedback: false } option.
Instead of setting [up-watch-...] attributes on individual fields, you may also set them on any element containing fields.
The closest attribute around a changed field is honored.
By setting attributes on the <form> you can configure defaults for all watchers:
<form action="/search" up-watch-disable> <!-- mark: up-watch-disable -->
<input name="department" up-autosubmit>
<input name="query" up-autosubmit>
</form>
Form-wide options can be overridden at the field level:
<form action="/search" up-watch-disable> <!-- mark: up-watch-disable -->
<input name="department" up-autosubmit>
<input name="query" up-autosubmit up-watch-disable="false"> <!-- mark: up-watch-disable="false" -->
</form>
The feature attribute itself can sit on a container, too. Unpoly then watches all fields inside it. This is how you watch a group of radio buttons:
<form action="/search">
<fieldset up-autosubmit up-watch-disable> <!-- mark: up-watch-disable -->
<input type="radio" name="format" value="html"> HTML format
<input type="radio" name="format" value="pdf"> PDF format
<input type="radio" name="format" value="txt"> Text format
</fieldset>
</form>
Options passed from JavaScript override all attributes:
up.validate(field, { disable: true })
Tip Your coding agent can search these docs locally with the Unpoly agent skill