Form
Advanced form controller and UI API. Grants you full control of the HTML form elements and enables you to build perfect form interfaces for your users.
It includes a full spectrum type validation (string, number, integer, tel, email, text, select, radiobuttons, checkbox, password, date, datetime, files, location and HTML editor), min and max values, patterns and a neat "compare to" property, allowing you to easily create validated "re-type you email/password/string" inputs.
The form module adds and removes interaction (hover, focus) and validation (correct, error, default) classes for your convenience and dispatches event callbacks for any user interaction (changed, updated, preSubmitted, submitted, resat, focused, blurred, validationPassed, validationFailed) – you decide the level for control by defining the callback methods you need.
The modular design and the helper methods allow you to customize form design and interaction responses to meet any design request.
Util.Form is based on the Templator HTML Form syntax, ensuring full HTML fallback when no JavaScript is available.
In Util.Form we are working with terms, such as form (the form or pseudo form), field (the div that wraps an input/label/hint collection), inputs (the actual HTML inputs) and actions (HTML buttons and links). In addition a field can (and should) contain a help element, with a hint and an error message. See Templator HTML Form for more information.
Functions
Util.Form.init
Definition
- Name
- Util.Form.init
- Shorthand
- u.f.init
- Syntax
- Void = Util.Form.init( Node form [, JSON _options ] );
Description
Initialize a form, extending it with realtime validation, state classes and event callbacks. An initialized form consists of a form, inputs and actions (buttons), and provides some element collections to help you access any form component with ease.
Initially a form input will have used state. Only inputs that have been interacted with will show error states, as the user should not be reprimanded for untouched required inputs. When user interacts with field, the correct state will be applied when validation passes. The error state will only be applied after an input has lost focus the first time OR when the form is submitted.
Upon initialization all fields are bulk validated and a callback to validationPassed or validationFailed will be dispatched, if the form either failed or passed validation. Note, a form with partially un-used inputs will not pass validation, nor necessarily fail validation. When initialization is complete a ready callback is dispatched for form.
Any field can be made required simply by adding a required class to the field. Upon validation the presence of the required class is checked, and you can switch between required and not required simply by adding or removing the class. In addition a mix of classes and input attributes are used to provide additional validation information. See the Input types section below for more information.
An indicator (*) element is automatically added to all fields. This should be hidden for non-required fields using CSS. This is done so, because the field may change required state during interaction, and thus it is convenient that they are always injected.
Util.Form.init can also be used on a partial form (a pseudo form), as any HTML node can be passed instead of the actual outer form. This makes it extra useful in frameworks which dictate a global form element (like .NET).
focus, hover, error, correct and default classes are added/removed from fields and inputs when their state changes, to allow you to easily add styling of the different input states.
Parameters
- form
-
Node Form to initialize
- _options
-
JSON Optional, JSON _options
Options
Return values
Void
Extended properties
The form elements are indexed and made available on form, fields, inputs and actions as follows:
Form
- form.inputs
- Collection of inputs in form.
- form.actions
- Collection of named actions in form. If action doesn't have a name attribute, then then wrapping li classname will be used for naming action.
Field
- field._form
- Reference to form or pseudo form. As the form property is reserved, we are using _form.
- field.input
- Reference to primary field input
- field.inputs
- Array of references to all field inputs for fields with multiple inputs, such as radiobuttons.
- field.label
- Reference to field's primary label.
- field.indicator
- Reference to field's required indicator. See custom extensions below for more information.
- field.help
- Reference to field help element.
- field.hint
- Reference to field hint element.
- field.error
- Reference to field error element.
- field.type
- String representation of field type.
Input
- input._form
- Reference to form or pseudo form. As the form property is reserved, we are using _form.
- input.label
- Reference to input label (not available for hidden inputs).
- input.field
- Reference to input field (not available for hidden inputs).
Action
- action._form
- Reference to form or pseudo form. As the form property is reserved, we are using _form.
Extended methods
The form elements are extended with convenient helper methods to make form handling more consistent and cross type/browser safe.
Form
- form.submit
- Validate all fields and submit form if validation passes.
- form.DOMsubmit
- Perform a native form submit.
- form.reset
- Reset all fields to their initial state.
- form.DOMreset
- Perform a native form reset.
- form.getData
- Shorthand method for getting form data set. See Util.Form.getFormData below for details and note that when invoking this method directly on form, you should omit passing the form argument.
Input
- input.val([value])
- Function to get/set input value. Works with all types of inputs. If value is passed, value will be set for input. If no value is passed, current value will be returned.
Input types
Util.Form comes with a range of default field/input types. The initialization of each field relies on the presence of a type class, as listed below. Any field can be made required simply by adding a required class to the field. Additional validation rules can be specified using classVars or attributes on the input element as specified below.
- string
- String input (input type="text"). Must be string. Optional min:[length] and max:[length] can be added as classVars on field. Default min length is 1, default max length is 255. Regex pattern can be added using the pattern attribute. Add a data-compare-to attribute to input containing the name of other input, to require both inputs to have same value. Useful for "re-type your xyz"-type fields.
- text
- Multiline text input (textarea). Must be string. Optional min:[length] and max:[length] can be added as classVars on field. Default min length is 1, default max length is 10000000. Regex pattern can be added using the pattern attribute.
- Email input (input type="email"). Must be valid email syntax. Alternate regex pattern can be added using the pattern attribute. Add a data-compare-to attribute to input containing the name of other input, to require both inputs to have same value. Useful for "re-type your email"-type fields.
- password
- Password input (input type="password"). Must be between 8 and 20 chars. Optional min:[length] and max:[length] can be added as classVars on field. Regex pattern can be added using the pattern attribute. Add a data-compare-to attribute to input containing the name of other input, to require both inputs to have same value. Useful for "re-type your password"-type fields.
- numeric
- Numeric input (input type="number"). Must be numeric (integer or decimal number). Optional min:[value] and max:[value] can be added as classVars on field. Note that for numeric inputs min and max refers to the numeric value, not the length of the input. Regex pattern can be added using the pattern attribute.
- integer
- Integer input (input type="number"). Must be integer. Optional min:[value] and max:[value] can be added as classVars on field. Note that for integer inputs min and max refers to the numeric value, not the length of the input.
- tel
- Phone input (input type="number"). Must be telephone (.-+ 0-9) and between 5 and 16 chars. Alternate regex pattern can be added using the pattern attribute. Add a data-compare-to attribute to input containing the name of other input, to require both inputs to have same value. Useful for "re-type your phonenumber"-type fields.
- select
- Dropdown/Select input with multiple options (select).
- checkbox
- Checkbox input (input type="checkbox").
- radio_buttons
- Radiobutton input (input type="radio").
- date
- Date input (input type="date"). Optional min:[date] and max:[date] can be added as classVars on field. Note that for date inputs min and max refers to dates, not the length of the input. Regex pattern can be added using the pattern attribute.
- datetime
- Date AND time input (input type="datetime"). Optional min:[date[time]] and max:[date[time]] can be added as classVars on field. Note that for date inputs min and max refers to dates, not the length of the input. Time can be omitted when stating min and max properties. Regex pattern can be added using the pattern attribute.
- files
- File upload (input type="file"). Optional min:[count] and max:[count] can be added as classVars on field. Note that for file inputs min and max refers to file count, not the length of the input. Allowed files can be specified using the accept attribute on the input. Regex pattern can be added using the pattern attribute.
- location
- Location with geo coordinates and map-picker. This field consists of three inputs. One for the location name, one for latitude and one for longitude. All three must be valid if any of them are filled out. Note: This input type requires that you include u-form-field-location. Also remember to add your Google API key (u.gapi_key = #API_KEY#) to enable map-picker.
- html
- HTML editor with strict semantic formatting controls. This editor has been designed to prioritize SEO and design over "free form editing". Note: This input type requires that you include u-form-field-html. In addition the build-in file and media upload functionality, requires additional backend services (happily provided by Janitor).
Callbacks
An extensive set of callback are dispatched to give you full control of form behaviour – just declare the appropriate callback methods on either form, input or action.
Form
- form.focused(input)
- When form input gets focus.
- form.blurred(input)
- When form input loses focus.
- form.updated(input)
- When form input is updated.
- form.changed(input)
- When form input is changed.
- form.submitted(input)
- When form is submitted - if callback function is not declared, form will be submitted as regular HTML form.
- form.preSubmitted(input)
- Just before form submission is executed - last chance before sending data.
- form.resat(input)
- When form is reset.
- form.validationFailed(JSON)
- When form validation fails - sends errors object, containing names of all failed inputs.
- form.validationPassed()
- When form validation is passed - form contains no errors.
Input
- input.updated(input)
- When input is updated.
- input.changed(input)
- When input is changed.
- input.focused(input)
- When input gets focus.
- input.blurred(input)
- When input loses focus.
- input.validationFailed()
- When input failed validation.
- input.validationPassed()
- When input passed validation.
Action
- action.focused(action)
- When button gets focus.
- action.blurred(action)
- When button loses focus.
Extension modules
The default form behaviour can be modified by defining your own custom modifiers or initializers. This allows you to build new input types, custom validations, label styles/behaviours, hint positioning, HTML pre-processors as well as custom ways of compiling data on submit.
Please refer to u-form-custom.js for examples.
Examples
<form name="test_form" action="action" method="get">
<fieldset>
<div class="field string required">
<label for="input_string_id">String, required</label>
<input type="text" name="string_required" id="input_string_id" pattern="[a-f]+" />
</div>
<div class="field integer required min:2 max:10">
<label for="input_integer_id">Integer, required</label>
<input type="text" name="integer_required" id="input_integer_id" />
</div>
</fieldset>
<ul class="actions">
<li><input type="submit" value="submit, name" name="submit_name" class="button" /></li>
</ul>
</form>
<script>
var form = u.querySelector("form");
u.f.init(form);
form.changed = function(input) {
// callback for form changed (input has changed)
}
// returns input value
form.inputs["string_required"].input.val();
// set input value to "test"
form.inputs["string_required"].input.val("test");
form.inputs["string_required"].input.updated = function(input) {
// callback for input value updated (input was updated)
}
form.actions["submit_name"].focused = function(action) {
// callback for button focus
}
form.submitted = function(action) {
// callback for form submit
}
form.validationFailed = function(errors) {
// callback for failed form validation
}
form.validationPassed = function() {
// callback for passed form validation
}
</script>
Dependencies
JavaScript
- typeof
- String.replace
- String.match
- String.toLowerCase
- Array.push
- Object.keys
- switch...case
- for...in
- parseInt
- Event.keyCode
- Event.metaKey
- Event.ctrlKey
- Element.setAttribute
- Element.getAttribute
- Element.insertBefore
- Document.parentNode
- Document.setAttribute
- JSON.parse
- JSON.stringify
Manipulator
- fun
- obj
- Util.normalize
- Util.browser
- Util.querySelector
- Util.querySelectorAll
- Util.appendElement
- Util.parentNode
- Util.classVar
- Util.hasClass
- Util.addClass
- Util.removeClass
- Util.applyStyle
- Util.applyStyles
- Util.getComputedStyle
- Util.clickableElement
- Util.Event.kill
- Util.Event.addEvent
- Util.Event.event_support
- Util.Timer.setTimer
- Util.Timer.resetTimer
Util.Form.getFormData
Definition
- Name
- Util.Form.getFormData
- Syntax
- Mixed = Util.Form.getFormData( Node form [, JSON _options ] );
Description
Get name/value pairs from all inputs in form – structured as you please.
Note, this methods is also mapped to any initialized form as form.getData(_options). When invoked directly on form, the form argument is omitted.
Parameters
- form
-
Node node to use as form scope. Can be form or just plain HTML node.
- _options
-
JSON Optional, JSON _options
Options
Return values
Mixed Default GET string, otherwise object as specified in format setting.
Examples
<form name="test_form" action="action" method="get">
<fieldset>
<div class="field string required">
<label for="input1_id">String, required</label>
<input type="text" name="string_required" id="input1_id" value="test1" />
</div>
<div class="field string required">
<label for="input2_id">String, required</label>
<input type="text" name="string_not_required" id="input2_id" value="test2" />
</div>
</fieldset>
</form>
<script>
var form = u.querySelector("form");
u.f.getParams(form, {format:"params"});
</script>
Returns string_required=test1&string_not_required=test2
<form name="test_form" action="action" method="get">
<fieldset>
<div class="field string required">
<label for="input1_id">String, required</label>
<input type="text" name="string_required" id="input1_id" value="test1" />
</div>
<div class="field string required">
<label for="input2_id">String, required</label>
<input type="text" name="string_not_required" id="input2_id" value="test2" />
</div>
</fieldset>
</form>
<script>
var form = u.querySelector("form");
u.f.getParams(form, {format:"object"});
</script>
Returns JSON object like:
{
"string_required":"test1",
"string_not_required":"test2"
}
Dependencies
JavaScript
- Switch...case
- for...in
- encodeURIComponent
- String.match
Manipulator
- obj
- fun
- Util.querySelectorAll
- Util.hasClass
Files
Main file
- u-form.js
Segment support files
- u-form-desktop_light.js
Segment dependencies
- desktop
- u-form.js + u-events.js + u-dom.js + u-timer.js + u-string.js + u-system.js
- desktop_ie11
- u-form.js + u-events.js + u-dom.js + u-dom-desktop_ie.js + u-timer.js + u-string.js + u-system.js
- desktop_ie10
- u-form.js + u-events.js + u-dom.js + u-dom-desktop_ie.js + u-timer.js + u-string.js + u-system.js
- desktop_ie9
- u-form-desktop_light.js + u-events.js + u-dom.js + u-dom-desktop_ie.js + u-timer.js + u-string.js + u-system.js
- desktop_light
- u-form-desktop_light.js + u-events.js + u-events-desktop_light.js + u-dom.js + u-dom-desktop_light.js + u-timer.js + u-string.js + u-string-desktop_light.js + u-system.js
- tablet
- u-form.js + u-events.js + u-dom.js + u-timer.js + u-string.js + u-system.js
- tablet_light
- u-form.js + u-events.js + u-dom.js + u-timer.js + u-string.js + u-system.js
- smartphone
- u-form.js + u-events.js + u-dom.js + u-timer.js + u-string.js + u-system.js
- mobile
- not tested
- mobile_light
- not tested
- tv
- u-form-desktop_light.js + u-events.js + u-events-desktop_light.js + u-dom.js + u-dom-desktop_light.js + u-timer.js + u-string.js + u-string-desktop_light.js + u-system.js
- seo
- not supported