Author: | cferdinandi |
---|---|
Views Total: | 5,264 views |
Official Page: | Go to website |
Last Update: | January 15, 2019 |
License: | MIT |
Preview:

Description:
The Bouncer.js JavaScript library is created to extend the native HTML5 form validation that enables the customizable form validation on the form fields.
Features:
- Validate form fields on submit, blur and data change.
- Custom validation rules.
- Easy to add your own validators.
- Custom error messages.
- Useful API methods and events.
See also:
How to use it:
Download and insert the JavaScript file bouncer.polyfills.js
into the web page.
<script src="dist/bouncer.polyfills.js"></script>
Initialize the Bouncer library and we’re ready to go.
var bouncer = new Bouncer('[data-validate]')
Apply validation rules to the form fields as follows:
<form class="validate-me" id="validate-me" data-validate> <div> <label for="file">Upload any file</label> <input name="file" id="file" type="file" data-bouncer-target="#file-error-msg" required> </div> <div id="file-error-msg"></div> <div> <label for="color">Color Picker <span class="pattern color">7-Character Hexadecimal (ex. #f7f7f7)</span></label> <input type="color" name="color" id="color" pattern="#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})" required> </div> <div> <label for="date">Date <span class="pattern date">YYYY-MM-DD</span></label> <input type="date" name="date" id="date" required> </div> <div> <label for="time">Time <span class="pattern time">HH:MM (24-hour time)</span></label> <input type="time" name="time" id="time" required> </div> <div> <label for="month">Month <span class="pattern month">YYYY-MM</span></label> <input type="month" name="month" id="month" required> </div> <div> <!-- Regex: https://gist.github.com/badsyntax/719800 --> <label for="email">Email</label> <input type="email" name="email" id="email" data-bouncer-message="The domain portion of the email address is invalid (the portion after the @)." required> </div> <div> <!-- Regex: https://gist.github.com/dperini/729294 --> <label for="url">URL</label> <input type="url" name="url" id="url" data-bouncer-message="The URL is a missing a TLD (for example, .com)." required> </div> <div> <!-- Regex: https://gist.github.com/dperini/729294 --> <label for="urlnotld">URL without TLD allowed</label> <input type="url" name="urlnotld" id="urlnotld" pattern="(?:(?:https?|HTTPS?|ftp|FTP):\/\/)(?:\S+(?::\S*)[email protected])?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)*)(?::\d{2,5})?(?:[\/?#]\S*)?" required> </div> <div> <label for="number">Number</label> <input type="number" name="number" id="number" required> </div> <div> <label for="float">Number (no decimals)</label> <input type="number" step="any" name="integer" id="integer" pattern="^(?:[-+]?[0-9]*)$" required> </div> <div> <label for="numberminmax">Number with Min and Max <span class="pattern">Must be between 2 and 7</span></label> <input type="number" min="2" max="7" name="numberminmax" id="numberminmax" required> </div> <div> <label for="tel">Tel <span class="pattern">123-456-7890</span></label> <input type="text" name="tel" id="tel" pattern="^(?:\d{3}[\-]\d{3}[\-]\d{4})$" required> </div> <div> <label for="password">Password <span class="pattern">At least 1 uppercase character, 1 lowercase character, and 1 number</span></label> <input type="password" name="password" id="password" data-bouncer-message="Please choose a password that includes at least 1 uppercase character, 1 lowercase character, and 1 number." pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s).*" required> </div> <div> <label for="confirm-password">Confirm Password <span class="pattern">must match the field above</span></label> <input type="password" name="confirm-password" id="confirm-password" data-bouncer-match="#password" data-bouncer-mismatch-message="Your passwords do not match." required> </div> <div> <label for="textminmax">Text with MinLength and MaxLength <span class="pattern">must be between 3 and 9 characters long</span></label> <input type="text" minlength="3" maxlength="9" name="textminmax" id="textminmax" required> </div> <div> <label for="select">Select</label> <select name="select" id="select" required> <option></option> <option>Harry Potter</option> <option>Lord of the Rings</option> <option>Star Wars</option> <option>Start Trek</option> </select> </div> <div> <strong>Radio Buttons</strong> <label class="label-normal"> <input type="radio" name="radio" id="radio-1" required> Yes </label> <label class="label-normal"> <input type="radio" name="radio" id="radio-2" required> No </label> </div> <div> <strong>Checkboxes</strong> <label class="label-normal"> <input type="checkbox" name="checkbox-1" id="checkbox-1" required> Wolverine (must be checked) </label> <label class="label-normal"> <input type="checkbox" name="checkbox-2" id="checkbox-2"> Storm </label> <label class="label-normal"> <input type="checkbox" name="checkbox-3" id="checkbox-3"> Cyclops </label> <label class="label-normal"> <input type="checkbox" name="checkbox-4" id="checkbox-4"> Gambit </label> </div> <input type="submit" class="button" value="Submit"> </form>
Create a custom validator.
var bouncer = new Bouncer('[data-validate]',{ customValidations: { valueMismatch: function (field) { // Look for a selector for a field to compare // If there isn't one, return false (no error) var selector = field.getAttribute('data-bouncer-match'); if (!selector) return false; // Get the field to compare var otherField = field.form.querySelector(selector); if (!otherField) return false; // Compare the two field values // We use a negative comparison here because if they do match, the field validates // We want to return true for failures, which can be confusing return otherField.value !== field.value; } }, messages: { valueMismatch: function (field) { var customMessage = field.getAttribute('data-bouncer-mismatch-message'); return customMessage ? customMessage : 'Please make sure the fields match.' } } })
Customize the error messages.
var bouncer = new Bouncer('[data-validate]',{ messageAfterField: true, messageCustom: 'data-bouncer-message', messageTarget: 'data-bouncer-target', messages: { missingValue: { checkbox: 'This field is required.', radio: 'Please select a value.', select: 'Please select a value.', 'select-multiple': 'Please select at least one value.', default: 'Please fill out this field.' }, patternMismatch: { email: 'Please enter a valid email address.', url: 'Please enter a URL.', number: 'Please enter a number', color: 'Please match the following format: #rrggbb', date: 'Please use the YYYY-MM-DD format', time: 'Please use the 24-hour time format. Ex. 23:00', month: 'Please use the YYYY-MM format', default: 'Please match the requested format.' }, outOfRange: { over: 'Please select a value that is no more than {max}.', under: 'Please select a value that is no less than {min}.' }, wrongLength: { over: 'Please shorten this text to no more than {maxLength} characters. You are currently using {length} characters.', under: 'Please lengthen this text to {minLength} characters or more. You are currently using {length} characters.' }, fallback: 'There was an error with this field.' }, })
More configuration options.
var bouncer = new Bouncer('[data-validate]',{ // Classes & IDs fieldClass: 'error', errorClass: 'error-message', fieldPrefix: 'bouncer-field_', errorPrefix: 'bouncer-error_', // Patterns patterns: { email: /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$/, url: /^(?:(?:https?|HTTPS?|ftp|FTP):\/\/)(?:\S+(?::\S*)[email protected])?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)(?:\.(?:[a-zA-Z\u00a1-\uffff0-9]-*)*[a-zA-Z\u00a1-\uffff0-9]+)*(?:\.(?:[a-zA-Z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/, number: /^(?:[-+]?[0-9]*[.,]?[0-9]+)$/, color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/, 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))/, time: /^(?:(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]))$/, month: /^(?:(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])))$/ }, // Custom Validations customValidations: {}, // Form Submission disableSubmit: false, // Custom Events emitEvents: true })
API methods.
// validate a specific form field bouncer.validate(field); // validate all form fields bouncer.validateAll(); // destroy the library bouncer.destroy();
Event handlers.
document.addEventListener('bouncerShowError', function (event) { // when an error is displayed }); document.addEventListener('bouncerRemoveError', function (event) { // when an error is removed }); document.addEventListener('bouncerFormValid', function (event) { // when the form is valid }); document.addEventListener('bouncerFormInvalid', function (event) { // when the form is invalid }, false); document.addEventListener('bouncerInitialized', function (event) { // when the library is initialized }); document.addEventListener('bouncerDestroy', function (event) { // when the library is destroyed });