Abide is an HTML5 form validation library that supports the native API by using patterns and required attributes.

Passwords must be at least 8 characters with 1 capital letter, 1 number, and one special character.
Passwords must match.
Valid email required.
Valid URL required.

Setting Up Validation

To enable validation with Abide, add the data-abide attribute to your form element. Then add the required attribute to each input that you want to require. Additionaly, you can define a pattern to define restraints on what users can input.

<form data-abide> <div class="name-field"> <label>Your name <small>required</small> <input type="text" required pattern="[a-zA-Z]+"> </label> <small class="error">Name is required and must be a string.</small> </div> <div class="email-field"> <label>Email <small>required</small> <input type="email" required> </label> <small class="error">An email address is required.</small> </div> <button type="submit">Submit</button> </form>

Predefined Patterns

Abide has several patterns common validation patterns built into the library:

Name Valid Example or Format
alpha Foundation
alpha_numeric A1Sauce
integer -1
number 2937
card visa, amex, mastercard
cvv 384 or 3284
email [email protected]
url http://zurb.com
domain zurb.com
datetime YYYY-MM-DDThh:mm:ssTZD
time HH:MM:SS
dateISO not sure yet
month_day_year MM/DD/YYYY
color #FFF or #FFFFFF

You can also use these patterns by setting the input's type to the name of the pattern instead of using the pattern attribute:

<input type="email" required> <input type="url">

There is a good list of valid HTML5 input types on the Mozilla Developer Network. Try avoiding patterns defined by type that do not match the specification.

You can use the following shortcut for named patterns that aren't valid input types:

<input type="text" pattern="integer">

Custom Named Patterns

By overriding Abide during Foundation initilization, you can define your own custom patterns or override the default patterns to validate against.

$(document) .foundation({ abide : { patterns: { dashes_only: /^[0-9-]*$/, ip_address: /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/ } } });

You can then use these custom patterns like you would the predfined patterns in your markup:

<form class="custom" data-abide> <label>Serial Number <input type="text" pattern="dashes_only" required> </label> </form>

Equal To

To add a confirmation field, you can define the data-equalto attribute.

<form data-abide> <div class="password-field"> <label>Password <small>required</small> <input type="password" id="password" required pattern="[a-zA-Z]+"> </label> <small class="error">Your password must match the requirements</small> </div> <div class="password-confirmation-field"> <label>Confirm Password <small>required</small> <input type="password" required pattern="[a-zA-Z]+" data-equalto="password"> </label> <small class="error">The password did not match</small> </div> <button type="submit">Submit</button> </form>

Error Messages

To display an error message for your invalid form element, include a small tag with an error class as a sibling of your input.

<div class="input-wrapper"> <label>Email Address <small>required</small> <input type="email" required> </label> <small class="error">A valid email address is required.</small> </div>

We have wrapped our input in a div in the example above. This div will receive an error class when the input is invalid. This class will show our error message and style the label and input accordingly.

Invalid inputs inherit a data-invalid attribute.


If a submit event is fired, a valid.fndtn.abide event is triggered when the form is valid and an invalid.fndtn.abide event is triggered when the form is invalid.

Deprecation Notice

Previous versions of the abide plugin emitted un-namespaced valid and invalid events, however, these have been replaced by the namespaced valid.fndtn.abide and invalid.fndtn.abide events. The un-namespaced events will be fully deprecated when Foundation 5.4 is released.

You can bind to these events and fire your own callback:

$('#myForm') .on('invalid.fndtn.abide', function () { var invalid_fields = $(this).find('[data-invalid]'); console.log(invalid_fields); }) .on('valid.fndtn.abide', function () { console.log('valid!'); });

To handle the submit event yourself, use data-abide="ajax" instead of data-abide inside the form tag.

<form data-abide="ajax" id="myform"> <div class="name-field"> <label>Your name <small>required</small> <input type="text" name="users_name" required pattern="[a-zA-Z]+"> </label> <small class="error">Name is required and must be a string.</small> </div> <button type="submit">Submit</button> </form>
$('#myform').on('valid.fndtn.abide', function() { // Handle the submission of the form });

Custom Validators

equalTo is actually an example of a built-in validator. To get an idea of how validators work, check out the implementation of equalTo:

equalTo: function(el, required, parent) { var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value, to = el.value, valid = (from === to); return valid; }

Your function will be passed three arguments: el, required, and parent. These are the elements being validated, whether or not it was marked as required, and the parent of the element being validated, respectively. Your function should return true if the element is valid, or false if it is invalid. You can define your custom validators and pass them into abide options when initializing foundation. See the Configuration section for more details on defining custom validators.

Suppose you've defined a custom validator diceRoll which randomly marks your element as valid or invalid. You would use it like so:

<input type="text" data-abide-validator="diceRoll">

Using the Javascript

Before you can use Abide you'll want to verify that jQuery and foundation.js are available on your page. You can refer to the Javascript documentation on setting that up.

Just add foundation.abide.js AFTER the foundation.js file. Your markup should look something like this:

<body> ... <script src="js/foundation/foundation.js"></script> <script src="js/foundation/foundation.abide.js"></script> <!-- Other JS plugins can be included here --> <script> $(document).foundation(); </script> </body>

Required Foundation Library: foundation.abide.js

Optional Javascript Configuration

$(document).foundation({ abide : { live_validate : true, focus_on_invalid : true, error_labels: true, // labels with a for="inputId" will recieve an `error` class timeout : 1000, patterns : { alpha: /^[a-zA-Z]+$/, alpha_numeric : /^[a-zA-Z0-9]+$/, integer: /^[-+]?\d+$/, number: /^[-+]?[1-9]\d*$/, // amex, visa, diners card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/, cvv : /^([0-9]){3,4}$/, // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, url: /(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?/, // abc.de domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/, datetime: /([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))/, // YYYY-MM-DD date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))/, // HH:MM:SS time : /(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}/, dateISO: /\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/, // MM/DD/YYYY month_day_year : /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/, // #FFF or #FFFFFF color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ }, validators: { diceRoll: function(el, required, parent) { var possibilities = [true, false]; return possibilities[Math.round(Math.random())]; } } } });

Stay on top of what’s happening in responsive design.

Sign up to receive monthly Responsive Reading highlights. Read Last Month's Edition »