jqBootstrapValidation

A JQuery validation plugin for bootstrap forms.

It turns this

<input type="email" id="email" required>
<input 
  name="emailAgain"
  data-validation-matches-match="email" 
  data-validation-matches-message=
    "Must match email address entered above" 
>
<input 
  type="checkbox" 
  name="terms-and-conditions" 
  required 
  data-validation-required-message=
    "You must agree to the terms and conditions"
>
<input type="checkbox"
  name="qualityControl[]"
  value="fast"
  minchecked="2"
  data-validation-minchecked-message="Choose two"
  maxchecked="2"
  data-validation-maxchecked-message=
    "You can't have it all ways"
>
                    

Into this

Email address we can contact you on

And again, to check for speeling miskates


(go ahead, nothing is sent anywhere)

Installation

  1. Download jqBootstrapValidation and include the script tags on your page:
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <!-- or use local jquery -->
    <script src="/js/jqBootstrapValidation.js"></script>
  2. Apply the jqBootstrapValidation plugin to the elements you want validation applied to
    <script>
      $(function () { $("input,select,textarea").not("[type=submit]").jqBootstrapValidation(); } );
    </script>
  3. jqBootstrapValidation will scan for HTML5 validator attributes directly on the elements, plus any extra options specified via data attributes.
    See below.

Validators

Email address

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Email address</label>
    <div class="controls">
      <input type="email" />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
type email
data-validation-email-message (your failure message)

Required

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input type="text" name="some_field" required />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
required (doesn't need a value)
data-validation-required-message (your failure message)

Minimum

Must be higher than 41

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type a number</label>
    <div class="controls">
      <input type="number" min="42" name="some_field" />
      <p class="help-block">Must be higher than 41</p>
    </div>
  </div>
</form>
Attribute Value Req?
min (minimum number to accept)
data-validation-min-message (your failure message)

Maximum

Must be lower than 43

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type a number</label>
    <div class="controls">
      <input type="number" max="42" name="some_field" />
      <p class="help-block">Must be lower than 43</p>
    </div>
  </div>
</form>
Attribute Value Req?
max (maximum number to accept)
data-validation-max-message (your failure message)

Maximum Length

<form class="form-horizontal" novalidate>
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input type="text" maxlength="10" name="some_field" />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
maxlength (maximum number of characters to accept)
data-validation-maxlength-message (your failure message)

Minimum Length

<form class="form-horizontal" novalidate>
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input type="text" minlength="10" name="some_field" />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
minlength (minimum number of characters to accept)
data-validation-minlength-message (your failure message)

Pattern

Must start with 'a' and end with 'z'

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input type="text" 
        pattern="a.*z" 
        data-validation-pattern-message="Must start with 'a' and end with 'z'" 
        name="some_field"
      />
      <p class="help-block">Must start with 'a' and end with 'z'</p>
    </div>
  </div>
</form>
Attribute Value Req?
pattern Regex to determine if the input is acceptable
Note only expects abc, not /^abc$/ig
data-validation-pattern-message (your failure message)

Confirm match

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input type="text" name="some_field" />
      <p class="help-block"></p>
    </div>
  </div>
  <div class="control-group">
    <label class="control-label">Type it again</label>
    <div class="controls">
      <input 
        type="text" 
        data-validation-match-match="some_field" 
        name="some_other_field" 
      />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
data-validation-match-match name of form field to match
data-validation-match-message (your failure message)

Max checked options

Note: you only need to apply this to one checkbox; the form is searched for matching names for the rest.
<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Select your two favourite colours</label>
    <div class="controls">
      <label class="checkbox">
        <input 
          type="checkbox" 
          name="some_field" 
          data-validation-maxchecked-maxchecked="2" 
          data-validation-maxchecked-message="Don't be greedy!" 
        /> Red
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Orange
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Yellow
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Green
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Blue
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Indigo
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Violet
      </label>
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
data-validation-maxchecked-maxchecked maximum number of options that may be checked
data-validation-maxchecked-message your failure message

Min checked options

Note: you only need to apply this to one checkbox; the form is searched for matching names for the rest.
<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Select your two favourite colours</label>
    <div class="controls">
      <label class="checkbox">
        <input 
          type="checkbox" 
          name="some_field" 
          data-validation-minchecked-minchecked="2" 
          data-validation-minchecked-message="Choose at least two" 
        /> Red
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Orange
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Yellow
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Green
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Blue
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Indigo
      </label>
      <label class="checkbox">
        <input type="checkbox" name="some_field" /> Violet
      </label>
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
data-validation-minchecked-minchecked minimum number of options that may be checked
data-validation-minchecked-message your failure message

Regex matching

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Select your two favourite colours</label>
    <div class="controls">
      <input 
        type="text" 
        data-validation-regex-regex="a.*z" 
        data-validation-regex-message="Must start with 'a' and end with 'z'" 
      />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
data-validation-regex-regex pattern the input must match
data-validation-regex-message your failure message (strongly recommended you make this descriptive)

Javascript Callback

<script>
  function demo_callback_function($el, value, callback) {
    callback({
      value: value,
      valid: /a.*z/.test(value),
      message: "Must start with 'a' and end with 'z'"
    });
  }
</script>
<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input 
        type="text" 
        data-validation-callback-callback="demo_callback_function" 
      />
      <p class="help-block"></p>
    </div>
  </div>
</form>
Attribute Value Req?
data-validation-callback-callback name of the callback function
data-validation-callback-message your failure message
Note: You can include this in the callback response in stead, to customise against the user's error

The callback function will be passed the element (wrapped in jQuery), the field value, and a response function to call when ready.

The response function expects a single variable, a hash containing 'value', 'valid' and optionally 'message'.

The value must be returned, as this is checked against the current value and stale responses are ignored. The 'valid' item in the hash should evaluate to true only if the given value is valid. The message item in the hash, if given, will override the current message on the validator.

Sound a bit complex? Don't worry and take a look at the code tab, its pretty self explanatory.

Warning: While waiting for your function to use the callback, the validator assumes the field is valid. This is to guard against something failing server-side and stopping the user from submitting the form. If your callback takes a long time, the user could be able to submit the form with invalid data without realising.

AJAX

Note: As github doesn't offer dynamic pages yet, this form is only an example and accepts everything

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input 
        type="text" 
        name="ajax_input"
        data-validation-ajax-ajax="/path/to/validator/script" 
      />
      <p class="help-block"></p>
    </div>
  </div>
</form>
<?php
  echo json_encode(
    array(
      "value" => $_REQUEST["value"],
      "valid" => preg_match("/^[A-Z].*$/", $_REQUEST["value"]),
      "message" => "Must start with an uppercase letter"
    )
  );
{
  "value": "test",
  "valid": 0,
  "message": "Must start with an uppercase letter"
}
Attribute Value Req?
data-validation-ajax-ajax path to the validation page on the server
data-validation-ajax-message your failure message
Note: You can include this in the ajax response in stead, to customise against the user's error

The ajax call will be passed the field name and the field value.

The response is expected as a JSON hash containing 'value', 'valid' and optionally 'message'.

Value must be returned, as this is checked against the current value so stale responses are ignored. The 'valid' item in the hash should evaluate to true only if the given value is valid. The message item in the hash, if given, will override the current message on the validator.

Sound a bit complex? Don't worry and take a look at the server tab, its pretty self explanatory.

Warning: While waiting for AJAX call, the validator assumes the field is valid. This is to guard against a something failing and stopping the user from submitting the form. If your ajax takes a long time, the user could be able to submit the form with invalid data without realising.

Numbers

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type a number</label>
    <div class="controls">
      <input type="number" />
      <p class="help-block"></p>
    </div>
  </div>
  <div class="form-actions">
</form>
Attribute Value Req?
type "number"
data-validation-number-message your failure message

Mix and multiply validators

<form class="form-horizontal">
  <div class="control-group">
    <label class="control-label">Type something</label>
    <div class="controls">
      <input 
        type="text" 
        data-validation-uppercase-regex="([^a-z]*[A-Z]*)*" 
        data-validation-uppercase-message="Must be uppercase" 
        data-validation-containsnumber-regex="([^0-9]*[0-9]+)+" 
        data-validation-containsnumber-message="Needs at least one number" 
      />
      <p class="help-block"></p>
    </div>
  </div>
</form>

Have you noticed how all the validation messages data-attributes look the same?

data-validation-validatorname-message

Validators are attached with names, so you can have multiple of the same validator if you just name them differently.

In the form above, I've added two Regex validators, one requiring uppercase, the other requiring at least one number. Because they are named differently ('uppercase' and 'containsnumber' respectively) they are both applied rather than cancelling eachother out.

You can also use the HTML5 validators multiple times by specifying them in data-attribute format, such as data-validator-myvalidator-maxlength=10 to use the maxlength HTML5 validator, for example.

Configuration

sniffHtml

Internally, jqBootstrapValidation only uses data attributes. By default, it will also sniff for native HTML5 form validation attributes, as detailed above.

If you decide this isn't what you want, you can restrict jqBootstrapValidation to only data attributes by setting sniffHtml to false when calling it on your form elements. $(...).jqBootstrapValidation({sniffHtml: false});

preventSubmit

By default, jqBootstrapValidtion will prevent forms from submitting if any of their elements fail validation by jqBootstrapValidation.

If you decide this isn't what you want, you can allow submitting of potentially invalid data for validation server-side (or in case you think someone might have a genuine case for exceptional data). $(...).jqBootstrapValidation({preventSubmit: false});

submitError

A javascript callback, used when a user is attempting to submit a form with invalid input.

Parameter Description
$form The form element which has the user attempted to submit (wrapped in jQuery)
event The submit event (note this may have already been cancelled before you receive it depending on your preventSubmit option).
errors An object consisting of the names of fields as keys, and the array of errors as values.

If you decide you want to react to the invalid submit attempt, you can write a function directly into the jqBootstrapValidation call:

$(/*...*/).jqBootstrapValidation(
  {
    submitError: function ($form, event, errors) { 
      /* ... */ 
    }
  }
);
Note: The event parameter is a full jQuery event and may be manipulated as normal.

submitSuccess

A javascript callback, used when a user is attempting to submit a form with valid input.

Parameter Description
$form The form element which has the user attempted to submit (wrapped in jQuery)
event The submit event (note this may have already been cancelled before you receive it depending on your preventSubmit option).

If you decide you want to react to the submit attempt, you can write a function directly into the jqBootstrapValidation call:

$(/*...*/).jqBootstrapValidation(
  {
    submitSuccess: function ($form, event) { 
      /* ... */ 
    }
  }
);
Note: The event parameter is a full jQuery event and may be manipulated as normal.

autoAdd

If your form is missing help blocks, for example if you don't want an empty element hanging around near 'terms and conditions' check boxes where no explanation would normally be needed, jqBootstrapValidation will add them for you automatically.

If you decide this isn't what you want, for example if you only want the error styling without a warning message, you can stop jqBootstrapValidation from creating extra elements. $(...).jqBootstrapValidation({autoAdd: {helpBlocks: false}});

filter

jqBootstrapValidation doesn't assume anything about your form, so if you need to ignore some validators in multi-stage forms you can optionally filter them out of the submit event with the filter option.

The this variable is set to a single element. If you return false, it will be ignored on submit events. For example, the below ignores all elements that are not visible on the page:

$(...).jqBootstrapValidation({
  filter: function () {
    return $(this).is(":visible");
  }
});

Events

validation.validation

Returns an array of validation errors for a given object.

If no errors are found, returns an empty array.

Note Must be called on a single element via triggerHandler.
To collect all errors for a set of elements, you could use an each loop:

var errorMessages = [];
$("...").each(function (i, el) {
  errorMessages = errorMessages.concat(
      $(this).triggerHandler("validation.validation")
  );
});
If you just want a list of all error messages for a group of elements, see the "collectErrors" jqBoostrapValidation function.

getValidators.validation

Returns the internal array of valiators for inspection.

Note Must be called on a single element via triggerHandler.
var myValidators = $("...").first().triggerHandler("getValidators.validation");

Functions

destroy

Removes all jqBootstrapValidation events attached to the given elements, and resets their control-block classes and help-block text to their original values.

$("...").jqBootstrapValidation("destroy");

collectErrors

Collects an object containing arrays of all error messages associated with each invalid element.

var errors = $("...").jqBootstrapValidation("collectErrors");
{
  "username": ["...", "..."],
  "password": ["...", "..."]
}

override

Overrides the internal array, to change the behaviour of default functions, add extra validators, and so on.

WARNING This has the potential to break jqBootstrapValidation. Tread carefully.
You should only use the override function if you are certain you need to, or if you're adding new validators

Because this is a big topic, it has it's own section. See the "Overrides" configuration option.

hasErrors

Returns true if the given collection of elements would show an error when submitted.

if ($("...").jqBootstrapValidation("hasErrors")) {
  alert("Something is wrong!");
}

Override

WARNING This has the potential to break jqBootstrapValidation. Tread carefully.

Internally, all of jqBootstrapValidation's functions are stored in one big object, which you can override by calling the "override" function with a new object to merge on top of it. Anything you don't set, is left as it was.

Note that as the objects are merged together, you can define your own extra functions, options, etc.

This allows you to duck punch your own solutions, and set up the options in one place rather than on every call to .jqBootstrapValidation()

options

Question If you override the defaults, will you need to tell anyone else?

You can override the default options by calling the 'override' function and setting the 'options' key with the values you'd use when calling .jqBootstrapValidation() on a set of elements. As this updates the internal object, all subsequent calls to .jqBootstrapValidation() will use the new options.

For example, to stop jqBootstrapValidation from preventing an invalid form from being submitted by default:

$.jqBootstrapValidation("override", {options: {preventSubmit: false}});

methods

Allows you to override the methods you can call on jqBootstrapValidation:

Function Description
init Used when you call jqBootstrapValidation on a set of elements to set up the validators and events.
destroy Removes all hooks jqBootstrapValidation has set on the given set of elements, and any extra elements jqBootstrapValidaiton has added.
collectErrors returns an array containing the errors generated by the given collection of elements (or an empty object if none)
override this function, used to override other functions

For example, to prevent anyone from overriding anything else once you're done:

$.jqBootstrapValidation("override", {methods: {override: function () {} }});

validatorTypes

Allows you to override the validation methods used when validating a field. You must write the init and validate functions.

If your test is too complex for a regex, this is the primary method of adding a custom validator.

For example:

$.jqBootstrapValidation(
  "override", 
  {
    validatorTypes: 
    {
      check_username_ok: // the name of our validator
      {
        // the 'name' attribute must match the name used above
        name: 'check_something_important',
        init: function ($this, name)
        {
          return {
            like: "green eggs and ham",
            iAm: "sam i am"
          };
        },
        validate: function ($this, value, validator) 
        {
          console.log(validator.like);
          // "green eggs and ham"
          console.log(validator.iAm);
          // "sam i am"
          console.log(validator.message);
          // -- the message displayed for errors --

          validator.message = "You can override the message here";
          
          // Perform some checks on the value
          okValue = value.length > 5 && anExternalCheck(value);
          
          // true for valid values, false to display error message
          return okValue;
        }
      }
    }
  }
);
Attribute Type Description
init() function

Called on each element passed to jqBootstrapValidation that uses the current validator.

Returns an object with values that will be copied onto the validator object for future use.

Parameter Description
$this The element passed to jqBootstrapValidation (wrapped in jQuery)
name The name given to this validator in the html, eg `peter` from `data-validation-peter-myvalidator`
validate() function

Called on each element as it is validated.

Returns false if an error is found.

Parameter Description
$this The element to be validated (wrapped in jQuery)
value The current value of the element
validator The validator object. Note you can access attributes returned from the init function.
message string Message displayed when the validator fails.

This section is still being written. The current sections to-do are:

  • validatorTypes
  • builtInValidators

FAQ

Where is the date/time/tel/currency validator?

Simply put, I'm in the UK and you probably aren't. English might not even be your first language.

I can't possibly know how you write dates, when even the UK and USA can't agree.

I can't find a nice cross platform way of detecting someone's region preferences easily. If there is enough demand (@ReactiveRaven) I'll add region support, but for now you may be better finding a non-restrictive regex for your local format.

Where do I ask a question?

The best place to reach me is on twitter @ReactiveRaven. If you don't have a twitter account, you could email me in stead. It turns out I'm terrible at answering emails though, so please don't be surprised if I'm slow to respond. Sorry!

If you think you've found a bug, please do file an issue on github or better yet, fork and send a pull request.

Where do I report a bug?

If you've found a bug, please do file an issue on github or better yet, fork and send a pull request.

Created by David Godfrey
AKA @ReactiveRaven
No twitter? Email me.