Name: ko-validation
Owner: racker
Description: Knockout Validation Plugin for the Rackspace Control Panel.
Created: 2013-12-05 17:51:48.0
Updated: 2017-09-03 08:16:31.0
Pushed: 2015-10-07 17:30:35.0
Homepage: null
Size: 1542
Language: JavaScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Knockout Validation Plugin (used by the Rackspace Control Panel)
Just hook up validation to your knockout observables:
View Model:
ewModel = function () {
is['name'] = ko.observable('John Doe').extend({
'required': ['Name is required.'], // will show the message "Name is required."
'maxLength': [30, 'Name cannot be longer than 30 characters.'] // the last item is the message that will be shown
;
is['phone'] = ko.observable().extend({
'regex': [/[0-9]/, 'Must contain numbers.']
;
Template:
>
nput type="text" data-bind="value: name">
nput type="text" data-bind="value: phone">
v>
By default, the plugin will insert a span in the parent element of the input that is bound to that observable, and show the validation messages there.
Currently the following rules are supported:
required
maxLength
integer
range
regex
email
invalidChars
onlyIf
custom
equalToFieldValue
greaterThanOrEqualToFieldValue
lessThanOrEqualToFieldValue
Please refer to integration specs for examples
Sometimes we want to have multiple fields behave as a single field for validation purposes.
You can add an observable for each field and a computed observable with the final value, and have the computed observable be validated.
One example is if you have a text field alongside a select drop-down to select a time range, allowing the user to enter a number in the text field, and an option out of “Minutes, Hours, Days” in the select.
That would look like:
View Model:
['time'] = ko.observable();
['timeUnit'] = ko.observable('minutes');
['timeInMinutes'] = ko.computed(function () {
turn convertToMinutes(this['time'](), this['timeUnit']());
his).extend({
alidatesAfter': [this['time'], this['timeUnit']],
equired': ['Time is required.'],
ange': [0, (60 * 24), 'Cooldown must be between 0 minutes and 1 day.']
And, on the template:
>
nput type="text" data-bind="value: time">
elect data-bind="value: timeUnit">
v>
Notice the validationAfter
extension passed to timeInMinutes
. That means that observable will be validated after changes on both time
and timeUnit
, and the error message will be shown by the input fields associated to each of them.
In some cases, the validation for one field may depend on the value of another field. For example, one field might only be required if another field has a particular value. For fields like this, the validation should be re-run whenever either field changes.
The validates
extension allows you to indicate fields that should be validated whenever the given observable is changed. In the example below, the range validator on field1 will be run again whenever the value of field2 is changed:
['field1'] = ko.observable(1).extend({
ange': [1, 10, 'Must be between 1 and 10']
['field2'] = ko.observable(2).extend({
alidates': [this['field1']]
Validating that at least one checkbox is checked in a checkbox group is as easy as extending an observable array with the checkboxes values to be required.
One problem that this solution could cause is that a validation message would be inserted after each checkbox.
To ensure only one validation message is inserted somewhere, use the validationMessage
binding:
View Model:
['reasonsToCancelAccount'] = ko.observableArray([]).extend({
equired': ['Choose at least one please']
Template:
>
l>
<li><input type="checkbox" data-bind="checked: reasonsToCancelAccount" value="reason1"/>R1</li>
<li><input type="checkbox" data-bind="checked: reasonsToCancelAccount" value="reason2"/>R2</li>
<li><input type="checkbox" data-bind="checked: reasonsToCancelAccount" value="reason3"/>R3</li>
ul>
pan data-bind="validationMessage: reasonsToCancelAccount"></span>
v>
When an element with validationMessage
binding exists, new elements for displaying validation messages will not be automatically inserted in the DOM.
If you want to contribute to ko-validation, you will need npm and grunt-cli.
After installing the dependencies with npm, run grunt watch
to start the test watcher, which will run the tests in both Chrome and Firefox every time a file is modified. You can also use grunt karma:ci
to run all the tests with PhantomJS.
When submitting a pull request, do not forget to add unit tests, and if you are introducing a new validator, please also add integration tests for it.
To create a new distribution file with a patch version, run npm version patch -m "Upgrade to %s for reasons"
(with whatever is the most appropriate message), then run grunt dist
to generate the minified concatenated dist file. You can then npm publish
the new version to npm.
The rules are:
npm version [major | minor | patch]
. It creates a tagged commit with a proper change to package.json
.git push --tags
.npm publish
on the master branch.