{"id":28509137,"url":"https://github.com/atomicobject/ember-validations-flow-rite","last_synced_at":"2025-08-26T00:16:33.832Z","repository":{"id":66257781,"uuid":"173333556","full_name":"atomicobject/ember-validations-flow-rite","owner":"atomicobject","description":null,"archived":false,"fork":false,"pushed_at":"2019-03-01T16:25:20.000Z","size":974,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-29T02:21:00.065Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atomicobject.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-03-01T16:24:49.000Z","updated_at":"2019-03-01T16:34:26.000Z","dependencies_parsed_at":"2023-02-22T16:30:24.881Z","dependency_job_id":null,"html_url":"https://github.com/atomicobject/ember-validations-flow-rite","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/atomicobject/ember-validations-flow-rite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicobject%2Fember-validations-flow-rite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicobject%2Fember-validations-flow-rite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicobject%2Fember-validations-flow-rite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicobject%2Fember-validations-flow-rite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atomicobject","download_url":"https://codeload.github.com/atomicobject/ember-validations-flow-rite/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomicobject%2Fember-validations-flow-rite/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272150646,"owners_count":24882204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-08T22:07:32.905Z","updated_at":"2025-08-26T00:16:33.409Z","avatar_url":"https://github.com/atomicobject.png","language":"JavaScript","readme":"# Ember Validations #\n\n[![Build Status](https://travis-ci.org/DockYard/ember-validations.svg?branch=master)](https://travis-ci.org/DockYard/ember-validations) [![CircleCI](https://circleci.com/gh/DockYard/ember-validations.svg?style=shield)](https://circleci.com/gh/DockYard/ember-validations) [![npm version](https://badge.fury.io/js/ember-validations.svg)](https://badge.fury.io/js/ember-validations) [![Ember Observer Score](http://emberobserver.com/badges/ember-validations.svg)](http://emberobserver.com/addons/ember-validations)\n\n**[ember-validations is built and maintained by DockYard, contact us for expert Ember.js consulting](https://dockyard.com/ember-consulting)**.\n\n## WARNING ##\n\nThis addon is no longer actively developed. At DockYard we have switched over to\nusing [ember-changeset-validations](https://github.com/DockYard/ember-changeset-validations/)\ntogether with [ember-changeset](https://github.com/DockYard/ember-changeset).\n\nWe do still maintain this addon.\n\n## Installing ##\n\n```\nember install ember-validations\n```\n\n## Looking for help? ##\n\nIf it is a bug [please open an issue on GitHub](https://github.com/dockyard/ember-validations/issues).\n\n## Usage ##\n\nYou need to mixin `EmberValidations` into any `Ember.Object` you want to add\nvalidations to:\n\n```javascript\nimport Ember from 'ember';\nimport { Mixin } from 'ember-validations';\n\nexport default Ember.Controller.extend(Mixin);\n```\n\nYou define your validations as a JSON object. They should be added to\nthe controller that represents the model in question.\nThe keys in the object should map to properties. If you pass a\nJSON object as the value this will be seen as validation rules to apply\nto the property. If you pass `true` then the property itself will be\nseen as a validatable object.\n\n```javascript\nimport Ember from 'ember';\nimport { Mixin } from 'ember-validations';\n\nexport default Ember.Controller.extend(Mixin, {\n  validations: {\n    'model.firstName': {\n      presence: true,\n      length: { minimum: 5 }\n    },\n    'model.age': {\n      numericality: true\n    },\n    'model.profile': true\n  }\n});\n```\n\nThough not yet explicitly part of the API, you can also add validators\nto nested objects:\n\n```javascript\nimport Ember from 'ember';\nimport { Mixin } from 'ember-validations';\n\nexport default Ember.Component.extend(Mixin, {\n  validations: {\n    'user.firstName': {\n      presence: true,\n      length: { minimum: 5 }\n    }\n  }\n});\n```\n\nThis is useful for things like Components which don't act as proxies, but\nagain, until this is officially built into the project, [YMMV](http://www.urbandictionary.com/define.php?term=ymmv).\n\n**Note: If you override the init function, you must call _super()**\n\n```javascript\nimport Ember from 'ember';\nimport { Mixin } from 'ember-validations';\n\nexport default Ember.Controller.extend(Mixin, {\n  init: function() {\n    // this call is necessary, don't forget it!\n    this._super.apply(this, arguments);\n\n    // Your init code...\n  }\n});\n```\n\n## Validators ##\n\n### Absence ###\nValidates the property has a value that is `null`, `undefined`, or `''`\n\n#### Options ####\n  * `true` - Passing just `true` will activate validation and use default message\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n\n```javascript\n// Examples\nabsence: true\nabsence: { message: 'must be blank' }\n```\n\n### Acceptance ###\nBy default the values `'1'`, `1`, and `true` are the acceptable values\n\n#### Options ####\n  * `true` - Passing just `true` will activate validation and use default message\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n  * `accept` - the value for acceptance\n\n```javascript\n// Examples\nacceptance: true\nacceptance: { message: 'you must accept', accept: 'yes' }\n```\n\n### Confirmation ###\nExpects a `propertyConfirmation` to have the same value as\n`property`. The validation must be applied to the `property`, not the `propertyConfirmation` (otherwise it would expect a `propertyConfirmationConfirmation`).\n\n#### Options ####\n  * `true` - Passing just `true` will activate validation and use default message\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n\n```javascript\n// Examples\nconfirmation: true\nconfirmation: { message: 'you must confirm' }\n```\n\n### Exclusion ###\nA list of values that are not allowed\n\n#### Options ####\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n  * `allowBlank` - If `true` skips validation if value is empty\n  * `in` - An array of values that are excluded\n  * `range` - an array with the first element as the lower bound the and second element as the upper bound. Any value that falls within the range will be considered excluded\n\n```javascript\n// Examples\nexclusion: { in: ['Yellow', 'Black', 'Red'] }\nexclusion: { range: [5, 10], allowBlank: true, message: 'cannot be between 5 and 10' }\n```\n\n### Format ###\nA regular expression to test with the value\n\n#### Options ####\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n  * `allowBlank` - If `true` skips validation if value is empty\n  * `with` - The regular expression to test with\n\n```javascript\n// Examples\nformat: { with: /^([a-zA-Z]|\\d)+$/, allowBlank: true, message: 'must be letters and numbers only'  }\n```\n\n### Inclusion ###\nA list of the only values allowed\n\n#### Options ####\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n  * `allowBlank` - If `true` skips validation if value is empty\n  * `in` - An array of values that are allowed\n  * `range` - an array with the first element as the lower bound the and\nsecond element as the upper bound. Only values that fall within the range will be considered allowed\n\n```javascript\n// Examples\ninclusion: { in: ['Yellow', 'Black', 'Red'] }\ninclusion: { range: [5, 10], allowBlank: true, message: 'must be between 5 and 10' }\n```\n\n### Length ###\nDefine the lengths that are allowed\n\n#### Options ####\n  * `number` - Alias for `is`\n  * `array` - Will expand to `minimum` and `maximum`. First element is the lower bound, second element is the upper bound.\n  * `allowBlank` - If `true` skips validation if value is empty\n  * `minimum` - The minimum length of the value allowed\n  * `maximum` - The maximum length of the value allowed\n  * `is` - The exact length of the value allowed\n  * `tokenizer` - A function that should return a object that responds to `length`\n\n##### Messages #####\n  * `tooShort` - the message used when the `minimum` validation fails. Overrides `i18n`\n  * `tooLong` - the message used when the `maximum` validation fails. Overrides `i18n`\n  * `wrongLength` - the message used when the `is` validation fails. Overrides `i18n`\n\n```javascript\n// Examples\nlength: 5\nlength: [3, 5]\nlength: { is: 10, allowBlank: true }\nlength: { minimum: 3, maximum: 5, messages: { tooShort: 'should be more than 3 characters', tooLong: 'should be less than 5 characters' } }\nlength: { is: 5, tokenizer: function(value) { return value.split(''); } }\n```\n\n### Numericality ###\nWill ensure the value is a number\n\n#### Options ####\n  * `true` - Passing just `true` will activate validation and use default message\n  * `allowBlank` - If `true` skips validation if value is empty\n  * `onlyInteger` - Will only allow integers\n  * `greaterThan` - Ensures the value is greater than\n  * `greaterThanOrEqualTo` - Ensures the value is greater than or equal to\n  * `equalTo` - Ensures the value is equal to\n  * `lessThan` - Ensures the value is less than\n  * `lessThanOrEqualTo` - Ensures the value is less than or equal to\n  * `odd` - Ensures the value is odd\n  * `even` - Ensures the value is even\n\n##### Messages #####\n  * `numericality` - Message used when value failes to be a number. Overrides `i18n`\n  * `onlyInteger` -  Message used when value failes to be an integer. Overrides `i18n`\n  * `greaterThan` - Message used when value failes to be greater than. Overrides `i18n`\n  * `greaterThanOrEqualTo` - Message used when value failes to be greater than or equal to. Overrides `i18n`\n  * `equalTo` - Message used when value failes to be equal to. Overrides `i18n`\n  * `lessThan` - Message used when value failes to be less than. Overrides `i18n`\n  * `lessThanOrEqualTo` - Message used when value failes to be less than or equal to. Overrides `i18n`\n  * `odd` - Message used when value failes to be odd. Overrides `i18n`\n  * `even` - Message used when value failes to be even. Overrides `i18n`\n\n```javascript\n// Examples\nnumericality: true\nnumericality: { messages: { numericality: 'must be a number' } }\nnumericality: { odd: true, messages: { odd: 'must be an odd number' } }\nnumericality: { onlyInteger: true, greaterThan: 5, lessThanOrEqualTo : 10 }\n```\n\n### Presence ###\nValidates the property has a value that is not `null`, `undefined`, or `''`\n\n#### Options ####\n  * `true` - Passing just `true` will activate validation and use default message\n  * `message` - Any string you wish to be the error message. Overrides `i18n`.\n\n```javascript\n// Examples\npresence: true\npresence: { message: 'must not be blank' }\n```\n\n### Uniqueness ###\n\n*Not yet implemented.*\n\n### Conditional Validators ##\n\nEach validator can take an `if` or an `unless` in its `options` hash.\nThe value of the conditional can be an inline function, a string that\nrepresents a property on the object, or a string that represents a\nfunction on the object. The result should be a boolean.\n\n**note that `if` is considered a keyword in IE8 and so you should put it\nin quotes**\n\n```javascript\n// function form\n'model.firstName': {\n  presence: {\n    'if': function(object, validator) {\n      return true;\n    }\n  }\n}\n\n// string form\n// if 'canValidate' is a function on the object it will be called\n// if 'canValidate' is a property object.get('canValidate') will be called\n'model.firstName': {\n  presence: {\n    unless: 'canValidate'\n  }\n}\n```\n\n### Custom Validators ###\n\n### With Ember-CLI ###\n\nYou can place your custom validators into\n`my-app/app/validators/{local,remote}/\u003cname\u003e`:\n\n```javascript\nimport Base from 'ember-validations/validators/base';\n\nexport default Base.extend({\n  // ...\n});\n```\n\nIt is recommended that you separate between `local` and `remote`\nvalidators. However, if you wish you can place your validator into\n`my-app/app/validators/\u003cname\u003e`. However, any similarly named validator\nin `local/` or `remote/` has a higher lookup presedence over those in\n`validators/`.\n\nThe \"native\" validators that come with `ember-validations` have the\nlowest lookup priority.\n\n### Without Ember-CLI ###\n\nYou can add your validators to the global object:\n\n```javascript\nEmberValidations.validators.local.\u003cClassName\u003e =\nEmberValidations.validators.Base.extend({\n  // ...\n});\n```\n\n### Creating ###\n\nTo create a new validator you need to override the `call` function. When\nthe validator is run its `call` function is what handles determining if\nthe validator is valid or not. Call has access to `this.model`,\n`this.property`. If the validation fails you **must** push the failing\nmessage onto the validator's `this.errors` array. A simple example of a\nvalidator could be:\n\n```javascript\nimport Base from 'ember-validations/validators/base';\nimport Ember from 'ember';\n\nexport default Base.extend({\n  call: function() {\n    if (Ember.isBlank(this.model.get(this.property))) {\n      this.errors.pushObject(\"cannot be blank\");\n    }\n  }\n});\n```\n\nYou may want to create a more complex validator that can observer for\nchanges on multiple properties. You should override the `init` function\nto accomplish this:\n\n```javascript\nimport Base from 'ember-validations/validators/base';\nimport Ember from 'ember';\n\nexport default Base.extend({\n  init: function() {\n    // this call is necessary, don't forget it!\n    this._super.apply(this, arguments);\n\n    this.dependentValidationKeys.pushObject(this.options.alsoWatch);\n  },\n  call: function() {\n    if (Ember.isBlank(this.model.get(this.property))) {\n      this.errors.pushObject(\"cannot be blank\");\n    }\n  }\n});\n```\n\nThe `init` function is given access to the `this.options` which is simply\na POJO of the options passed to the validator.\n`dependentValidationKeys` is the collection of paths relative to\n`this.model` that will be observed for changes. If any changes occur on\nany given path the validator will automatically trigger.\n\n#### Inline Validators ####\n\nIf you want to create validators inline you can use the\n`validator` function that is part of the `ember-validations` export:\n\n```javascript\nimport EmberValidations, { validator } from 'ember-validations';\n\nUser.create({\n  validations: {\n    'model.name': {\n      inline: validator(function() {\n        if (this.model.get('canNotDoSomething')) {\n          return \"you can't do this!\"\n        }\n      })\n    }\n  }\n});\n```\n\nInside the `validator` function you have access to `this.model` which is\na reference to the model. You **must** return an error message that will\nbe attached to the errors array for the property it is created on.\nReturn nothing for the validator to pass.\n\nAlternatively if the property doesn't have any additional validations\nyou can use a more concise syntax:\n\n```javascript\nUser.create({\n  validations: {\n    'model.name': EmberValidations.validator(function() {\n      if (this.model.get('canNotDoSomething')) {\n        return \"you can't do this!\"\n      }\n    })\n  }\n});\n```\n\n## Running Validations\n\nValidations will automatically run when the object is created and when\neach property changes. `isValid` states bubble up and help define the\ndirect parent's validation state. `isInvalid` is also available for convenience.\n\nIf you want to force all validations to run simply call `.validate()` on the object. `isValid` will be set to `true`\nor `false`. All validations are run as deferred objects, so the validations will\nnot be completed when `validate` is done. So `validate` returns a promise, call `then`\nwith a function containing the code you want to run after the validations have successfully\ncompleted.\n\n```javascript\nuser.validate().then(function() {\n  // all validations pass\n  user.get('isValid'); // true\n}).catch(function() {\n  // any validations fail\n  user.get('isValid'); // false\n}).finally(function() {\n  // all validations complete\n  // regardless of isValid state\n user.get('isValid'); // true || false\n});\n```\n\n## Inspecting Errors ##\n\nAfter mixing in `EmberValidations` into your object it will now have a\n`.errors` object. All validation error messages will be placed in there\nfor the corresponding property. Errors messages will always be an array.\n\n```javascript\nimport Ember from 'ember';\nimport EmberValidations from 'ember-validations';\n\nexport default Ember.Object.extend(EmberValidations, {\n  validations: {\n    'model.firstName': { presence: true }\n  }\n});\n```\n\n```javascript\nimport User from 'my-app/models/user';\n\nuser = User.create();\nuser.validate().then(null, function() {\n  user.get('isValid'); // false\n  user.get('errors.firstName'); // [\"can't be blank\"]\n  user.set('firstName', 'Brian');\n  user.validate().then(function() {\n    user.get('isValid'); // true\n    user.get('errors.firstName'); // []\n  })\n})\n\n```\n\n## Testing ##\n\n#### With Ember QUnit ####\n\nFor Ember Validations to work with [Ember QUnit](https://github.com/rwjblue/ember-qunit),\nyou must define all your validations in the `needs` property of the `moduleFor`\ncall. This will ensure Ember QUnit's isolated container will be able to locate\nthe validations during testing.\n\n```javascript\nimport { test, moduleFor } from 'ember-qunit';\n\nmoduleFor('controller:user/edit', 'UserEditController', {\n  needs: ['service:validations',\n          'ember-validations@validator:local/presence',\n          'ember-validations@validator:local/length',\n          'validator:local/name',\n          'validator:local/email'\n          ]\n});\n\ntest('Controller Test', function() { ... });\n```\n\nWhere `UserEditController` uses the built-in `presence` and `length` validators,\nand the locally defined `name` and `email` validators.\n\n#### Test Helpers ####\n\nTo test whether your Ember validations are working correctly, you can\nuse the test helpers:\n\n**`testValidPropertyValues(propertyName, values [, context ])`**\n\n**`testInvalidPropertyValues(propertyName, values [, context ])`**\n\n* `propertyName` (String): the property that you are validating.\n* `values` (Array): an array of property values to check.\n* `context` (function) _optional_: if specified, this function will be\n  called with the object under test as an argument. See example below.\n\n```javascript\nimport { test, moduleFor } from 'ember-qunit';\nimport {\n  testValidPropertyValues,\n  testInvalidPropertyValues\n} from '../../helpers/validate-properties';\n\nmoduleFor('controller:user', 'UserController', {\n  needs: ['ember-validations@validator:local/presence',\n          'ember-validations@validator:local/length'\n         ]\n});\n\ntestValidPropertyValues('firstName', ['Winston', '12345']);\ntestInvalidPropertyValues('firstName', ['abc', '', null, undefined]);\n```\n\nIf a property's validation relies on another property, you can pass a\ncontext to the test helper:\n\n```javascript\ntestValidPropertyValues('lastName', ['Dog', '12345'], function(subject) {\n  subject.set('firstName', 'Boomer');\n});\n\ntestValidPropertyValues('lastName', ['', null, undefined], function(subject) {\n  subject.set('firstName', null);\n});\n```\n\n## i18n ##\n\nWhen you use [ember-i18n](https://github.com/jamesarosen/ember-i18n) your `Ember.I18n.translations` object should contain the following keys under the `errors` key:\n\n```javascript\nEmber.I18n.translations = {\n  errors: {\n    inclusion: \"is not included in the list\",\n    exclusion: \"is reserved\",\n    invalid: \"is invalid\",\n    confirmation: \"doesn't match {{attribute}}\",\n    accepted: \"must be accepted\",\n    empty: \"can't be empty\",\n    blank: \"can't be blank\",\n    present: \"must be blank\",\n    tooLong: \"is too long (maximum is {{count}} characters)\",\n    tooShort: \"is too short (minimum is {{count}} characters)\",\n    wrongLength: \"is the wrong length (should be {{count}} characters)\",\n    notANumber: \"is not a number\",\n    notAnInteger: \"must be an integer\",\n    greaterThan: \"must be greater than {{count}}\",\n    greaterThanOrEqualTo: \"must be greater than or equal to {{count}}\",\n    equalTo: \"must be equal to {{count}}\",\n    lessThan: \"must be less than {{count}}\",\n    lessThanOrEqualTo: \"must be less than or equal to {{count}}\",\n    otherThan: \"must be other than {{count}}\",\n    odd: \"must be odd\",\n    even: \"must be even\"\n  }\n}\n````\n\n## Other Resources ##\n\n* [Six-part screencast series on ember-validations](https://www.emberscreencasts.com/tags/form-validations)\n\n## Authors ##\n\n* [Brian Cardarella](http://twitter.com/bcardarella)\n\n[We are very thankful for the many contributors](https://github.com/dockyard/ember-validations/graphs/contributors)\n\n## Versioning ##\n\nThis library follows [Semantic Versioning](http://semver.org)\n\n## Want to help? ##\n\nPlease do! We are always looking to improve this library. Please see our\n[Contribution Guidelines](https://github.com/dockyard/ember-validations/blob/master/CONTRIBUTING.md)\non how to properly submit issues and pull requests.\n\n## Legal ##\n\n[DockYard](http://dockyard.com/ember-consulting), LLC \u0026copy; 2016\n\n[@dockyard](http://twitter.com/dockyard)\n\n[Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicobject%2Fember-validations-flow-rite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatomicobject%2Fember-validations-flow-rite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomicobject%2Fember-validations-flow-rite/lists"}