/**
* Copyright 2016, Yahoo! Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
import Ember from 'ember';
import Base from 'ember-cp-validations/validators/base';
const moment = (self.requirejs.entries.moment || self.requirejs.entries['moment/index']) && self.require('moment').default;
if (typeof moment === 'undefined') {
throw new Error('MomentJS is required to use the Date validator. The easiest way to install moment.js is to install ember-moment.\n' +
'Installation instructions and documentation can be found at https://github.com/stefanpenner/ember-moment');
}
const {
isNone,
isEmpty
} = Ember;
/**
* Validate over a date range. Uses [MomentJS](http://momentjs.com/) for date mathematics and calculations.
*
* -*Note**: MomentJS must be installed to be able to use this validator. The easiest way to do this is to install [ember-moment](https://github.com/stefanpenner/ember-moment)
*
* #### Options
* - `allowBlank` (**Boolean**): If true, skips validation if the value is empty
* - `before` (**String**): The specified date must be before this date
* - `onOrBefore` (**String**): The specified date must be on or before this date
* - `after` (**String**): The specified date must be after this date
* - `onOrAfter` (**String**): The specified date must be on or after this date
* - `precision` (**String**): Limit the comparison check to a specific granularity. Options: year, month, week, day, hour, minute, second.
* - `format` (**String**): Input value date format
* - `errorFormat` (**String**): Error output date format. Defaults to `MMM Do, YYYY`
*
* ```javascript
* // Example
* validator('date', {
* after: 'now',
* before: '1/1/2020',
* precision: 'day',
* format: 'M/D/YYY',
* errorFormat: 'M/D/YYY'
* })
* // If before, onOrBefore, after, or onOrAfter is set to 'now', the value given to the validator will be tested against the current date and time.
* ```
*
* @class Date
* @module Validators
* @extends Base
*/
export default Base.extend({
_parseDate(date, format, useStrict = false) {
if (date === 'now' || isEmpty(date)) {
return moment();
}
return isNone(format) ? moment(new Date(date)) : moment(date, format, useStrict);
},
validate(value, options) {
const errorFormat = options.errorFormat || 'MMM Do, YYYY';
const format = options.format;
const precision = options.precision;
let { before, onOrBefore, after, onOrAfter } = options;
if (options.allowBlank && isEmpty(value)) {
return true;
}
let date = this._parseDate(value);
if (!date.isValid()) {
return this.createErrorMessage('date', value, options);
}
if (format) {
date = this._parseDate(value, format, true);
if (!date.isValid()) {
return this.createErrorMessage('wrongDateFormat', value, options);
}
}
if (before) {
before = this._parseDate(before, format);
if (!date.isBefore(before, precision)) {
options.before = before.format(errorFormat);
return this.createErrorMessage('before', value, options);
}
}
if (onOrBefore) {
onOrBefore = this._parseDate(onOrBefore, format);
if (!date.isSameOrBefore(onOrBefore, precision)) {
options.onOrBefore = onOrBefore.format(errorFormat);
return this.createErrorMessage('onOrBefore', value, options);
}
}
if (after) {
after = this._parseDate(after, format);
if (!date.isAfter(after, precision)) {
options.after = after.format(errorFormat);
return this.createErrorMessage('after', value, options);
}
}
if (onOrAfter) {
onOrAfter = this._parseDate(onOrAfter, format);
if (!date.isSameOrAfter(onOrAfter, precision)) {
options.onOrAfter = onOrAfter.format(errorFormat);
return this.createErrorMessage('onOrAfter', value, options);
}
}
return true;
}
});