jQuery Mobile provides a complete set of finger-friendly form elements that are based on native HTML form elements.
All forms should be wrapped in a form
tag that has an action
and method
that will handle the form data processing on the server.
<form action="form.php" method="post">
...
</form>
When constructing forms to be used in jQuery Mobile, most of the standard guidelines used to create forms that submit via ordinary HTTP POST or GET still apply. Additionally, the id
attributes of form controls need to be not only unique on a given page, but also unique across the pages in a site. This is because jQuery Mobile's single-page navigation model allows many different "pages" to be present in the DOM at the same time. You must be careful to use unique id
attributes so there will be only one of each in the DOM. Be sure to pair them properly with label
elements via the for
attribute.
For a more compact version of all form elements and buttons, add the data-mini="true"
attribute to the element to create a mini version. This is useful in toolbars and tight spaces but is still finger-friendly. It's possible to add this attribute to a fieldcontainer to set this on a number of elements at once.
<label for="basic">Text Input:</label>
<input type="text" name="name" id="basic" data-mini="true" />
This will produce an input that is not as tall as the standard version and has a smaller text size.
For the sake of accessibility, jQuery Mobile requires that all form elements be paired with a meaningful label
. To hide labels in a way that leaves them visible to assistive technologies — for example, when letting an element's placeholder
attribute serve as a label — apply the helper class ui-hidden-accessible
to the label itself:
<label for="username" class="ui-hidden-accessible">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username"/>
To hide labels within a field container and adjust the layout accordingly, add the class ui-hide-label
to the field container as in the following:
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username"/>
</div>
Both of the above examples will render as:
While the label will no longer be visible, it will be available to assisitive technologies such as screen readers.
Because radio and checkbox buttons use the label
to display the button text you can't use ui-hidden-accessible
in this case. However, the class ui-hide-label
can be used to hide the legend element:
<div data-role="fieldcontain" class="ui-hide-label">
<fieldset data-role="controlgroup">
<legend>Agree to the terms:</legend>
<input type="checkbox" name="checkbox-2a" id="checkbox-2a" class="custom" />
<label for="checkbox-2a">I agree</label>
</fieldset>
</div>
All jQuery Mobile widgets can be disabled in the markup by adding the standard disabled
attribute to the element, just like you would with native controls. Each form widget also has standard disable
and enable
methods that are documented with each form widget. Here are a few examples of disabled widgets:
Note that you can disable buttons created from button
or input
-based markup, but not links with a role of button. Links don't have a parallel disabled feature in HTML, but if you need to disable a link-based button (or any element), it's possible to apply the disabled class ui-disabled
yourself with JavaScript to achieve the same effect.
To improve the styling of labels and form elements on wider screens, wrap a div
or fieldset
with the data-role="fieldcontain"
attribute around each label/form element. This framework aligns the input and associated label side-by-side, and breaks to stacked block-level elements below ~480px. The framework will also add a thin bottom border to act as a field separator.
While all form elements are now tested to work correctly within static toolbars as of jQuery Mobile 1.1, we recommend extensive testing when using form elements within fixed toolbars or within any position: fixed
elements. This can potentially trigger a number of unpredictable issues in various mobile browsers, Android 2.2/2.3 in particular (detailed in Known issues in Android 2.2/2.3).
For example:
<div data-role="fieldcontain">
<label for="name">Text Input:</label>
<input type="text" name="name" id="name" value="" />
</div>
Will render as:
For additional examples, see the form elements gallery
By default, jQuery Mobile will automatically enhance certain native form controls into rich touch-friendly components. This is handled internally by finding form elements by tag name and running a plugin method on them. For instance, a select
element will be found and initialized with the "selectmenu" plugin, while an input
element with a type="checkbox"
will be enhanced with the "checkboxradio" plugin. Once initialized, you can address these enhanced components programmatically through their jQuery UI widget API methods. See options, methods, and events listed on each form plugin's documentation page for details.
If you should generate new markup client-side or load in content via AJAX and inject it into a page, you can trigger the create
event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (see below).
For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the create event to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
In jQuery Mobile, some enhanced form controls are simply styled (inputs), but others are custom controls (selects, sliders) built from, and kept in sync with, the native control. To programmatically update a form control with JavaScript, first manipulate the native control, then use the refresh
method to tell the enhanced control to update itself to match the new state. Here are some examples of how to update common form controls, then call the refresh
method:
$("input[type='checkbox']").prop("checked",true).checkboxradio("refresh");
$("input[type='radio']").prop("checked",true).checkboxradio("refresh");
var myselect = $("#selectfoo");
myselect[0].selectedIndex = 3;
myselect.selectmenu("refresh");
$("input[type='range']").val(60).slider("refresh");
var myswitch = $("#selectbar");
myswitch[0].selectedIndex = 1;
myswitch.slider("refresh");
If you'd prefer that a particular form control be left untouched by jQuery Mobile, simply give that element the attribute data-role="none"
. For example:
<label for="foo">
<select name="foo" id="foo" data-role="none">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
If you'd like to prevent auto-initialization without adding attributes to your markup, you can customize the selector that is used for preventing auto-initialization by setting the page plugin's keepNative
option (which defaults to [data-role="none"]
). Be sure to configure this option inside an event handler bound to the mobileinit
event, so that it applies to the first page as well as subsequent pages that are loaded.
$(document).bind('mobileinit',function(){
$.mobile.page.prototype.options.keepNative = "select, input.foo, textarea.bar";
});
Alternately you can use the data-enhance="false"
data attribute on a parent element with $.mobile.ignoreContentEnabled
set to true. Beware though, this will incur a performance penalty for each and every element in the page that would otherwise be enhanced as jQuery Mobile must traverse the set of parents to look for those elements.
One special case is that of selects. The above sample will prevent any and all augmentation from taking place on select elements in the page if select
is included. If you wish to retain the native performance and appearance of the menu itself and benefit from the visual augmentation of the select button by jQuery Mobile, you can set $.mobile.selectmenu.prototype.options.nativeMenu
to true in a mobileinit
callback as a global setting or use data-native-menu="true"
on a case by case basis.
Using a multipart form with a file input is not supported by ajax. In this case you should decorate the parent form with data-ajax="false"
to ensure the form is submitted properly to the server.