UNPKG

ember-cp-validations

Version:
213 lines (207 loc) 6 kB
import { isNone } from '@ember/utils'; import { deprecate } from '@ember/debug'; /** * @module Validators * @main Validators */ /** * ### description * * Default: __'This field'__ * * A descriptor for your attribute used in the error message strings. * You can overwrite this value in your `validators/messages.js` file by changing the `defaultDescription` property. * * ```javascript * // Examples * validator('date', { * description: 'Date of birth' * }) * // If validation is run and the attribute is empty, the error returned will be: * // 'Date of birth can't be blank' * ``` * * ### lazy * * Default: __true__ * * Only validate the given validator if the attribute is not already in an invalid * state. When you have multiple validators on an attribute, it will only validate subsequent * validators if the preceding validators have passed. When set to __false__, the validator * will always be executed, even if its preceding validators are invalid. * * ```javascript * // Examples * buildValidations({ * username: [ * validator('presence', true), * validator('length', { min: 5 }), * validator('custom-promise-based-validator') // Will only be executed if the above two have passed * ] * }); * * validator('custom-validator-that-must-executed', { * lazy: false * }) * ``` * * ### dependentKeys * * A list of other model specific dependents for you validator. * * ```javascript * // Examples * validator('has-friends', { * dependentKeys: ['model.friends.[]'] * }) * validator('has-valid-friends', { * dependentKeys: ['model.friends.@each.username'] * }) * validator('x-validator', { * dependentKeys: ['model.username', 'model.email', 'model.meta.foo.bar'] * }) * ``` * * ### disabled * * Default: __false__ * * If set to __true__, disables the given validator. * * ```js * // Examples * validator('presence', { * presence: true, * disabled: true * }) * validator('presence', { * presence: true, * disabled: computed.not('model.shouldValidate') * }) * ``` * * ### debounce * * Default: __0__ * * Debounces the validation with the given time in `milliseconds`. All debounced validations will * be handled asynchronously (wrapped in a promise). * * ```javascript * // Examples * validator('length', { * debounce: 500 * }) * validator('x-validator', { * debounce: 250 * }) * ``` * * ### isWarning * * Default: __false__ * * Any validator can be declared as a warning validator by setting `isWarning` to true. These validators will act as * assertions that when return a message, will be placed under `warnings` and `warningMessages` collections. What this means, * is that these validators will not have any affect on the valid state of the attribute allowing you to display warning messages * even when the attribute is valid. * * ```javascript * // Examples * validator('length', { * isWarning: true, * min: 6, * message: 'Password is weak' * }) * ``` * * ### value * * Used to retrieve the value to validate. This will overwrite the validator's default `value` method. * By default this returns `model[attribute]`. If you are dependent on other model attributes, you will * need to add them as `dependentKeys`. * * ```javascript * // Examples * validator('date', { * value(model, attribute) { * // Format the original value before passing it into the validator * return moment().utc(model.get(attribute)).format('DD/MM/YYY'); * } * }) * validator('number', { * dependentKeys: ['someOtherAttr'], * value(model, attribute) { * // Validate a value that is not the current attribute * return this.get('model').get('someOtherAttr'); * } * }) * ``` * * ### message * * This option can take two forms. It can either be a `string` (a CP that returns a string is also valid), or a `function`. * If a string is used, then it will overwrite all error message types for the specified validator. * * ```javascript * // Example: String * validator('confirmation', { * message: 'Email does not match {attribute}. What are you even thinking?!' * }) * ``` * * We can pass a `function` into our message option for even more customization capabilities. * * ```javascript * // Example: Function * validator('date', { * message(type, options, value, context) { * if (type === 'before') { * return '{description} should really be before {date}'; * } * if (type === 'after') { * return '{description} should really be after {date}'; * } * } * }) * ``` * The message function is given the following arguments: * * - `type` (**String**): The error message type * - `options` (**Object**): The validator options that were defined in the model * - `value`: The current value being evaluated * - `context` (**Object**): Context for string replacement * * The return value must be a `string`. If nothing is returned (`undefined`), * defaults to the default error message of the specified type. * * Within this function, the context is set to that of the current validator. * This gives you access to the model, defaultMessages, options and more. * * * @module Validators * @submodule Common Options */ export default function (arg1, options) { let props = { options: isNone(options) ? {} : options, }; if (typeof arg1 === 'function') { deprecate( '[ember-cp-validations] `validator` no longer directly accepts ' + 'a function. Please use the inline validator syntax:' + "\n\nvalidator('inline', { validate() {} )\n\n", false, { id: 'ember-cp-validations.inline-validator', until: '4.2.0' }, ); props.options.validate = arg1; props._type = 'inline'; } else if (typeof arg1 === 'string') { props._type = arg1; } else { throw new TypeError( '[ember-cp-validations] Unexpected type for first validator argument — It must be a string.', ); } return props; }