npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ko-validation

v1.1.3

Published

Knockout Validation Plugin (used by the Rackspace Control Panel)

Downloads

20

Readme

ko-validation Build Status

Knockout Validation Plugin (used by the Rackspace Control Panel)

Getting Started

Just hook up validation to your knockout observables:

View Model:

myViewModel = function () {
  this['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
  });

  this['phone'] = ko.observable().extend({
    'regex': [/[0-9]/, 'Must contain numbers.']
  });
};

Template:

<div>
  <input type="text" data-bind="value: name">
  <input type="text" data-bind="value: phone">
</div>

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.

Validation Rules

Currently the following rules are supported:

  • Required required
  • Maximum Length maxLength
  • Integer integer
  • Range range
  • Regex regex
  • Email email
  • Invalid Charachters invalidChars
  • Required Only If onlyIf
  • Custom custom

Deprecated validators

  • Equal To Field Value equalToFieldValue
  • Greater Than Or Equal To Field Value greaterThanOrEqualToFieldValue
  • Less Than Or Equal To Field Value lessThanOrEqualToFieldValue

Please refer to integration specs for examples

Validating Computed Observables

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:

this['time'] = ko.observable();

this['timeUnit'] = ko.observable('minutes');

this['timeInMinutes'] = ko.computed(function () {
  return convertToMinutes(this['time'](), this['timeUnit']());
}, this).extend({
  'validatesAfter': [this['time'], this['timeUnit']],
  'required': ['Time is required.'],
  'range': [0, (60 * 24), 'Cooldown must be between 0 minutes and 1 day.']
});

And, on the template:

<div>
  <input type="text" data-bind="value: time">
  <select data-bind="value: timeUnit">
</div>

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.

Validating Related Fields

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:

this['field1'] = ko.observable(1).extend({
  'range': [1, 10, 'Must be between 1 and 10']
});
this['field2'] = ko.observable(2).extend({
  'validates': [this['field1']]
});

Validating Checkboxes

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:

this['reasonsToCancelAccount'] = ko.observableArray([]).extend({
  'required': ['Choose at least one please']
});

Template:

<div>
  <ul>
    <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>
  <span data-bind="validationMessage: reasonsToCancelAccount"></span>
</div>

When an element with validationMessage binding exists, new elements for displaying validation messages will not be automatically inserted in the DOM.

Contributing

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.

When creating a new version

The rules are:

  • Follow semantic versioning.
  • Create separate pull requests to create new versions. Don't put extra code change in those PRs.
  • Use npm version [major | minor | patch]. It creates a tagged commit with a proper change to package.json.
  • Don't foget to push a tag to github using git push --tags.
  • After the PR with the new version is merged, execute npm publish on the master branch.