Edit this page

up.form up.watch(element, [options], callback)
JavaScript function

Watches form fields and runs a callback when a value changes.

While you can also listen to a standard input event, using up.watch() comes with a number of quality of live improvements:

The unobtrusive variant of this is the [up-watch] attribute.


The following would print to the console whenever an input field changes:

up.watch('input.query', function(value) {
  console.log('Query is now', value)

Callback arguments

The callback may accept up to three arguments:

up.watch('input.query', function(value, name, options) {
  console.log('Query is now', value)

The three arguments are:

Name Type Description
value string The changed field value
name string The [name] of the changed field
options Object Render options for the change ({ origin, feedback })

Watching multiple fields

Instead of a single form field, you can also pass multiple fields, a <form> or any container that contains form fields. The callback will be run if any of the given fields change:

up.watch('form', function(value, name) {
  console.log('The value of %o is now %o', name, value)

Async callbacks

When your callback does async work (like fetching data over the network) it should return a promise that settles once the work concludes:

up.watch('input.query', function(value, name, options) {
  let url = '/search?query=' + escapeURIFragment(value)
  return up.render('.results', { url, ...options }) // mark-phrase "return"

Unpoly will guarantee that only one async callback is running concurrently. If the form is changed while an async callback is still processing, Unpoly will wait until the callback concludes and then run it again with the latest field values.

Batching changes

You may also pass the { batch: true } option to receive all changes since the last callback in a single object:

up.watch('form', { batch: true }, function(diff, options) {
  for (let name in diff) {
    let value = diff[name]
    console.log('The value of %o is now %o', name, value)


element ElementorjQuery

The form field that will be watched.

You can pass a field, a <form> or any container that contains form fields. The callback will be run if any of the contained fields change.

[options.batch=false] boolean optional experimental

If set to true, the onChange callback will receive multiple detected changes in a single diff object as its argument.

The object's keys are the names of the changed fields. The object's values are the values of the changed fields.

[options.event='input'] stringorArray<string> optional

The types of event to observe.

See which events to watch.

[options.delay] number optional

The number of miliseconds to wait between an observed event and running the callback.

See debouncing callbacks.

[options.disable] booleanorstring optional

Whether to disable fields while an async callback is running.

See disabling fields while working.

callback Function(value, name, options): Promiseorundefined

The callback to run when the field's value changes.

An async callback function should return a promise that settles when the callback completes.

Return value


A destructor function that unsubscribes the watcher when called.

Watching will stop automatically when the form is destroyed.