A Knockout.js extension that adds Bootstrap form validation classes to a form group.
/** | |
* Knockout Extension: Bootstrap Form State | |
* | |
* Adds Bootstrap form validation classes to a form group; will also display | |
* a message if provided. | |
* | |
* @requires jQuery | |
* @requires Bootstrap 3 | |
* @requires Knockout.js | |
* | |
* @author Jon Stout (www.jonstout.net) | |
* | |
* @example <caption>Basic usage</caption> | |
* | |
* Set up your markup along these lines: | |
* | |
* ``` | |
* <form> | |
* <div class="form-group" data-bind="formState: observable"> | |
* <label for="example">Example field</label> | |
* <input type="text" class="form-control" id="example"> | |
* <span id="example-help" class="help-block" style="display:none;"></span> | |
* </div> | |
* </form> | |
* ``` | |
* | |
* Then define an observable in your view model: | |
* | |
* ``` | |
* this.observable = ko.observable(); | |
* // set to false to clear the validation state | |
* this.observable(false); | |
* // set to a string to show an error message... | |
* this.observable('error message'); | |
* // ... or set to an object with property `state` set to `"error"` | |
* this.observable({ | |
* state: 'error' | |
* }); | |
* // set to this to show a warning message: | |
* this.observable({ | |
* state: 'warning', | |
* message: 'warning message' | |
* }); | |
* // set to this to show success: | |
* this.observable({ | |
* state: 'success', | |
* message: 'success!' | |
* }); | |
* ``` | |
* | |
* @example <caption>Markup for a horizontal form</caption> | |
* | |
* ``` | |
* <form class="form-horizontal"> | |
* <div class="form-group"> | |
* <label for="example" class="control-label col-sm-2">Example field</label> | |
* <div class="col-sm-10"> | |
* <input type="text" class="form-control" id="example"> | |
* <span id="example-help" class="help-block" style="display:none"> | |
* </span> | |
* </div> | |
* </div> | |
* </form> | |
* ``` | |
*/ | |
(function($, ko) { | |
if (typeof ko.bindingHandlers.formState === 'undefined') { | |
ko.bindingHandlers.formState = { | |
update: function(element, valueAccessor) { | |
/** | |
* Shows a message within a span.help-block inside of a form group, if | |
* one exists. | |
* @private | |
* @param {Element} formGroup Form group div | |
* @param {String} message Message to display | |
*/ | |
var showMessage = function(formGroup, message) { | |
var help = $(formGroup).find('.help-block'); | |
if (help.length > 0) { | |
help.html(message).show(); | |
$(formGroup).find('input, select, textarea') | |
.attr('aria-describedby', help.attr('id')); | |
} | |
}; | |
var val = ko.unwrap(valueAccessor()); | |
if (typeof val === 'undefined' || val === null || !val) { | |
// if false or empty | |
$(element).removeClass('has-error') | |
.removeClass('has-warning') | |
.removeClass('has-success'); | |
$(element).find('input, select, textarea') | |
.removeAttr('aria-describedby'); | |
$(element).find('.help-block') | |
.empty() | |
.hide(); | |
} else if (typeof val.state !== 'undefined' && val.state === 'success'){ | |
// if success | |
$(element).addClass('has-success') | |
.removeClass('has-warning') | |
.removeClass('has-error'); | |
if (typeof val.message !== 'undefined') { | |
showMessage(element, val.message); | |
} | |
} else if (typeof val.state !== 'undefined' && val.state === 'warning'){ | |
// if warning | |
$(element).addClass('has-warning') | |
.removeClass('has-success') | |
.removeClass('has-error'); | |
if (typeof val.message !== 'undefined') { | |
showMessage(element, val.message); | |
} | |
} else { | |
// if error | |
if (typeof val === 'String') { | |
showMessage(element, val); | |
} else if (typeof val.message !== 'undefined') { | |
showMessage(element, val.message); | |
} | |
$(element).addClass('has-error') | |
.removeClass('has-warning') | |
.removeClass('has-success'); | |
$(element).find('input, select, textarea').focus(); | |
} | |
} | |
}; | |
} | |
})(jQuery, ko); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment