Forms form.js

Form.js takes an existing <form> element and adds useful event hooks for submitting, serialization / deserialization and validation.

Submitting

The native submit behavior of the form is not affected by default, and you can use Form.js to populate and serialize form data, but continue to submit the data normally.

If you want to handle the submit yourself, you can disable the native submit behavior, and add a hook for your own code.

Disable submit

You can disable submit by listening to the submit event on the form:

{% highlight js %} $(document).on('submit', '#myform', function (e) { e.preventDefault(); }) {% endhighlight %}

A shortcut to this is using the action option over the data or JavaScript APIs:

{% highlight js %} $('#myForm').form({action: false}) {% endhighlight %} {% highlight html %}
{% endhighlight %}

Handle submit

You should continue to use the submit event on the form element to bind any client-side submission logic. The submit.ac.form event will run only if the form has passed validation.

Access serialized form data

The submit.ac.form event exposes the form's data in two ways. The event's object attribute contains the form's data as an object, while array returns a list of the input elements and their corresponding values.

You can always the form inputs themselves if you need to customize this.

{% highlight js %} $(document).on('submit.ac.form', '#myform', function (e) { $.ajax({ data: e.object, ... }) }) {% endhighlight %}

Serialization / Deserialization

Populate a form

Most form data is fairly simple, and can be expressed with a serialized JSON object. Form.js lets you populate forms based on that JSON. This comes in handy when you have multiple items on a page that you may want to edit. Instead of rendering the form dynamically for each one, or populating the fields manually in JavaScript, you can populate the form automatically based on a source object.

{% highlight html %}
{% endhighlight %}

Use a form with multiple objects

Any page element with a data-toggle="form" attribute can populate a form. For example, if you have a form that can edit any item in a list, you can add each item's data into it's container element's data-serialized attribute. This attribute is checked by default for data to populate the form.

You can also use a different data attribute other than serialized, by specifying data-source="string". Because List.js stores each item's data as ac.list.item on it's rendered element, you're able to link forms to lists without JavaScript.

Use a form with a List

Specify data-source="ac.list.item" on a trigger element within a List.js item to populate a form with that item's data.

{% highlight html %}{% endhighlight %}
ID Name
{% highlight html %}
ID Name
{% endhighlight %}

Update source objects from the form

Submit actions

By default, submitting a form will cause the form's native submit action to fire, changing the page. Use the action=false option on the form to disable the default action.

You can then hook into the submit.ac.form event to update your associated record on a server and / or your local copy of that object.

{% highlight js %} $('#myForm').on('submit.ac.form', function(e) { $.post(myUrl, e.object); }); {% endhighlight %}

Update objects from List.js

When you update an object from an List.js list, you'll want to make sure the changes you've made are A) persisted to the list, and B) rendered. Call the update method on the index to update the data for that item.

{% highlight js %}$('#myIndex').index('update', itemElement, newData);{% endhighlight %}
ID Name
{% highlight html %} ...
...
{% endhighlight %}

Validation

Form.js encourages you to stay as close to the HTML5 Constraint validation spec as possible. That means using input validation attributes wherever possible (such as adding required to note a required field) and using the browser's built-in validation feedback.

We've tried to make the functionality that Form.js adds follow the same rules that the browser's default behavior does. Additional functionality follows the same patterns. This includes:

Form.js adds progressive enhancement by letting you use either the default validation feedback (the browser's native UI and default error messages), or a custom UI or content without changing when the validation occurs.

Customization

You should customize the validation of individual fields by adding change event handlers to the field in question, and calling .setCustomValidity() on the field, with a blank string for a valid field, and an error message for an invalid field.

If you wish to use custom display logic for individual fields, you should intercept the invalid event on the field and render your markup, optionally calling e.preventDefault() to prevent the default UI from displaying.

Form-wide error messages should be displayed using the invalid.ac.form event.

Usage

Via data attributes

Trigger changes to a form without writing any JavaScript. Set data-control="form" on your form element, and on a second trigger element, specify the data-toggle, data-target and data-serialized (or data-source) attributes.

{% highlight html %}
...
{% endhighlight %}

Via JavaScript

Or call the .form() method on the form element. Events triggered on the form will be triggered against this element.

{% highlight js %} $('#myForm').form(options); $('#myForm').on('submit.ac.form', function(e) { ... }); {% endhighlight %}

Options

Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-items="".

The form element

Name type default description
serialized native or serialized object Populate the form with these attributes on instantiation.
show boolean true Renders the Form when initialized. Requires the serialized option to be passed as well.

Form triggers

Name type default description
serialized native or serialized object Populate the form with these attributes when trigger fires.
source strong serialized When the event fires, Form.js must find the data to populate the form with. It will look in trigger element's data using this key. So by default the trigger element will use any data at data-serialized="". If no data with that key is found on the trigger element, it will look up through the elements parents until it finds one.

Stored data

When you display data in a form using the data-api, several helper references are added to the form element. They are there to help you find where the data you're editing came from.

$('#myForm').data('ac.form.sourceElement') returns the element the source data was stored on.

$('#myForm').data('ac.form.sourceData') returns the source data that was deserialized into the form.

Methods

.form('show', object)

Deserializes the passed object into the form's input fields.

{% highlight js %}$('#myForm').form('show', {"id": 1}){% endhighlight %}

.form('validate')

Trigger validation of the form. If any errors are detected, either the browser's default validation UI or your custom events will alert the user. Triggers validated.ac.form event with the result, and invalid.ac.form if the form is invalid.

{% highlight js %}$('#myForm').form('validate'){% endhighlight %}

Events

Event Type Description
show.ac.form This event is fired immediately when the show instance method has been called. The serialized data to be displayed is available as the serialized.array and serialized.object properties of the event. If the form was triggered via a button, that button will be available as relatedTarget. Call .preventDefault() on the event to stop showing the data.
shown.ac.form This event is fired when the serialized data has been inserted into the form. The data is available as the serialized.array and serialized.object properties of the event. If the form was triggered via a button, that button will be available as relatedTarget, the element containing that data is sourceElement, and a reference to the data itself is sourceData.
validate.ac.form This event is fired immediately when the validate instance method has been called. The current serialized values in the form are available through the object and array properties of the event. Call .preventDefault() on the event to stop validation.
invalid.ac.form This event is fired during attempted submission if the form is not valid. Use this event to display custom validation notices that apply to the form overall. Messages for individual fields should be applied using the invalid event on individual input elements.
validated.ac.form This event is fired when the form validation has completed. If any errors were detected, they will have been displayed to the user by this point. The validity of the form is available as the isValid property of the event.
submit.ac.form This data is fired when the form has passed validation. It takes place before a native form submit may occur. The form data is available in two ways: serialized into an object as the object property of the event, and as a raw array of input fields as array.
{% highlight js %} $('#myForm').on('submit.ac.form', function (e) { // do something... }) {% endhighlight %}