浏览代码

#807, #821: Add min, max options for the date validator, thanks to @Arkni

phuoc 11 年之前
父节点
当前提交
c5ea41ec64

+ 6 - 0
CHANGELOG.md

@@ -1,5 +1,11 @@
 # Change Log
 
+## v0.5.3 (not released yet)
+
+__New Features__
+
+* [#807](https://github.com/nghuuphuoc/bootstrapvalidator/issues/807), [#821](https://github.com/nghuuphuoc/bootstrapvalidator/pull/821): Add ```min```, ```max``` options for the [date](http://bootstrapvalidator.com/validators/date/) validator, thanks to [@Arkni](https://github.com/Arkni)
+
 ## v0.5.2 (2014-09-25)
 
 __New Features__

+ 1 - 1
dist/css/bootstrapValidator.min.css

@@ -2,7 +2,7 @@
  * BootstrapValidator (http://bootstrapvalidator.com)
  * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
  *
- * @version     v0.5.2, built on 2014-09-25 4:01:07 PM
+ * @version     v0.5.2, built on 2014-09-27 1:02:21 PM
  * @author      https://twitter.com/nghuuphuoc
  * @copyright   (c) 2013 - 2014 Nguyen Huu Phuoc
  * @license     MIT

+ 135 - 15
dist/js/bootstrapValidator.js

@@ -2,7 +2,7 @@
  * BootstrapValidator (http://bootstrapvalidator.com)
  * The best jQuery plugin to validate form fields. Designed to use with Bootstrap 3
  *
- * @version     v0.5.2, built on 2014-09-25 4:01:07 PM
+ * @version     v0.5.2, built on 2014-09-27 1:02:21 PM
  * @author      https://twitter.com/nghuuphuoc
  * @copyright   (c) 2013 - 2014 Nguyen Huu Phuoc
  * @license     MIT
@@ -2457,13 +2457,18 @@ if (typeof jQuery === 'undefined') {
 }(window.jQuery));
 ;(function($) {
     $.fn.bootstrapValidator.i18n.date = $.extend($.fn.bootstrapValidator.i18n.date || {}, {
-        'default': 'Please enter a valid date'
+        'default': 'Please enter a valid date',
+        min: 'Please enter a date after %s',
+        max: 'Please enter a date before %s',
+        range: 'Please enter a date in the range %s - %s'
     });
 
     $.fn.bootstrapValidator.validators.date = {
         html5Attributes: {
             message: 'message',
             format: 'format',
+            min: 'min',
+            max: 'max',
             separator: 'separator'
         },
 
@@ -2474,6 +2479,8 @@ if (typeof jQuery === 'undefined') {
          * @param {jQuery} $field Field element
          * @param {Object} options Can consist of the following keys:
          * - message: The invalid message
+         * - min: the minimum date
+         * - max: the maximum date
          * - separator: Use to separate the date, month, and year.
          * By default, it is /
          * - format: The date format. Default is MM/DD/YYYY
@@ -2483,7 +2490,7 @@ if (typeof jQuery === 'undefined') {
          * ii) date and time:
          * The time can consist of h, m, s parts which are separated by :
          * ii) date, time and A (indicating AM or PM)
-         * @returns {Boolean}
+         * @returns {Boolean|Object}
          */
         validate: function(validator, $field, options) {
             var value = $field.val();
@@ -2507,7 +2514,10 @@ if (typeof jQuery === 'undefined') {
                 time       = (sections.length > 1) ? sections[1] : null;
 
             if (formats.length !== sections.length) {
-                return false;
+                return {
+                    valid: false,
+                    message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                };
             }
 
             // Determine the separator
@@ -2516,14 +2526,20 @@ if (typeof jQuery === 'undefined') {
                 separator = (date.indexOf('/') !== -1) ? '/' : ((date.indexOf('-') !== -1) ? '-' : null);
             }
             if (separator === null || date.indexOf(separator) === -1) {
-                return false;
+                return {
+                    valid: false,
+                    message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                };
             }
 
             // Determine the date
             date       = date.split(separator);
             dateFormat = dateFormat.split(separator);
             if (date.length !== dateFormat.length) {
-                return false;
+                return {
+                    valid: false,
+                    message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                };
             }
 
             var year  = date[$.inArray('YYYY', dateFormat)],
@@ -2531,7 +2547,10 @@ if (typeof jQuery === 'undefined') {
                 day   = date[$.inArray('DD', dateFormat)];
 
             if (!year || !month || !day || year.length !== 4) {
-                return false;
+                return {
+                    valid: false,
+                    message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                };
             }
 
             // Determine the time
@@ -2541,7 +2560,10 @@ if (typeof jQuery === 'undefined') {
                 time       = time.split(':');
 
                 if (timeFormat.length !== time.length) {
-                    return false;
+                    return {
+                        valid: false,
+                        message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                    };
                 }
 
                 hours   = time.length > 0 ? time[0] : null;
@@ -2551,39 +2573,137 @@ if (typeof jQuery === 'undefined') {
                 // Validate seconds
                 if (seconds) {
                     if (isNaN(seconds) || seconds.length > 2) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                     seconds = parseInt(seconds, 10);
                     if (seconds < 0 || seconds > 60) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                 }
 
                 // Validate hours
                 if (hours) {
                     if (isNaN(hours) || hours.length > 2) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                     hours = parseInt(hours, 10);
                     if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                 }
 
                 // Validate minutes
                 if (minutes) {
                     if (isNaN(minutes) || minutes.length > 2) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                     minutes = parseInt(minutes, 10);
                     if (minutes < 0 || minutes > 59) {
-                        return false;
+                        return {
+                            valid: false,
+                            message: options.message || $.fn.bootstrapValidator.i18n.date['default']
+                        };
                     }
                 }
             }
 
             // Validate day, month, and year
-            return $.fn.bootstrapValidator.helpers.date(year, month, day);
+            var valid   = $.fn.bootstrapValidator.helpers.date(year, month, day),
+                message = options.message || $.fn.bootstrapValidator.i18n.date['default'];
+
+            // declare the date, min and max objects
+            var min       = null,
+                max       = null,
+                minOption = options.min,
+                maxOption = options.max;
+
+            if (minOption) {
+                if (isNaN(Date.parse(minOption))) {
+                    minOption = validator.getDynamicOption($field, minOption);
+                }
+                min = this._parseDate(minOption, dateFormat, separator);
+            }
+
+            if (maxOption) {
+                if (isNaN(Date.parse(maxOption))) {
+                    maxOption = validator.getDynamicOption($field, maxOption);
+                }
+                max = this._parseDate(maxOption, dateFormat, separator);
+            }
+
+            date = new Date(year, month, day, hours, minutes, seconds);
+
+            switch (true) {
+                case (minOption && !maxOption && valid):
+                    valid   = date.getTime() >= min.getTime();
+                    message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.min, minOption);
+                    break;
+
+                case (maxOption && !minOption && valid):
+                    valid   = date.getTime() <= max.getTime();
+                    message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.max, maxOption);
+                    break;
+
+                case (maxOption && minOption && valid):
+                    valid   = date.getTime() <= max.getTime() && date.getTime() >= min.getTime();
+                    message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.range, [minOption, maxOption]);
+                    break;
+
+                default:
+                    break;
+            }
+
+            return {
+                valid: valid,
+                message: message
+            };
+        },
+
+        /**
+         * Return a date object after parsing the date string
+         *
+         * @param {String} date   The date string to parse
+         * @param {String} format The date format
+         * The format can be:
+         *   - date: Consist of DD, MM, YYYY parts which are separated by the separator option
+         *   - date and time:
+         *     The time can consist of h, m, s parts which are separated by :
+         * @param {String} separator The separator used to separate the date, month, and year
+         * @returns {Date}
+         */
+        _parseDate: function(date, format, separator) {
+            var minutes     = 0, hours = 0, seconds = 0,
+                sections    = date.split(' '),
+                dateSection = sections[0],
+                timeSection = (sections.length > 1) ? sections[1] : null;
+
+            dateSection = dateSection.split(separator);
+            var year  = dateSection[$.inArray('YYYY', format)],
+                month = dateSection[$.inArray('MM', format)],
+                day   = dateSection[$.inArray('DD', format)];
+            if (timeSection) {
+                timeSection = timeSection.split(':');
+                hours       = timeSection.length > 0 ? timeSection[0] : null;
+                minutes     = timeSection.length > 1 ? timeSection[1] : null;
+                seconds     = timeSection.length > 2 ? timeSection[2] : null;
+            }
+
+            return new Date(year, month, day, hours, minutes, seconds);
         }
     };
 }(window.jQuery));

文件差异内容过多而无法显示
+ 4 - 4
dist/js/bootstrapValidator.min.js


+ 6 - 3
dist/js/language/ar_MA.js

@@ -8,8 +8,8 @@
             'default': 'الرجاء إدخال قيمة مشفرة طبقا للقاعدة 64.'
         },
         between: {
-            'default': 'من فضلك إدخال قيمة بين %s و %s .',
-            notInclusive: 'من فضلك إدخال قيمة بين %s و %s بدقة.'
+            'default': 'الرجاء إدخال قيمة بين %s و %s .',
+            notInclusive: 'الرجاء إدخال قيمة بين %s و %s بدقة.'
         },
         callback: {
             'default': 'الرجاء إدخال قيمة صالحة.'
@@ -30,7 +30,10 @@
             'default': 'الرجاء إدخال رقم CVV صالح.'
         },
         date: {
-            'default': 'الرجاء إدخال تاريخ صالح.'
+            'default': 'الرجاء إدخال تاريخ صالح.',
+            min: 'الرجاء إدخال تاريخ بعد %s.',
+            max: 'الرجاء إدخال تاريخ قبل %s.',
+            range: 'الرجاء إدخال تاريخ في المجال %s - %s.'
         },
         different: {
             'default': 'الرجاء إدخال قيمة مختلفة.'

+ 4 - 1
dist/js/language/en_US.js

@@ -30,7 +30,10 @@
             'default': 'Please enter a valid CVV number'
         },
         date: {
-            'default': 'Please enter a valid date'
+            'default': 'Please enter a valid date',
+            min: 'Please enter a date after %s',
+            max: 'Please enter a date before %s',
+            range: 'Please enter a date in the range %s - %s'
         },
         different: {
             'default': 'Please enter a different value'

+ 4 - 1
src/js/language/en_US.js

@@ -30,7 +30,10 @@
             'default': 'Please enter a valid CVV number'
         },
         date: {
-            'default': 'Please enter a valid date'
+            'default': 'Please enter a valid date',
+            min: 'Please enter a date after %s',
+            max: 'Please enter a date before %s',
+            range: 'Please enter a date in the range %s - %s'
         },
         different: {
             'default': 'Please enter a different value'

+ 30 - 28
src/js/validator/date.js

@@ -1,9 +1,9 @@
 (function($) {
     $.fn.bootstrapValidator.i18n.date = $.extend($.fn.bootstrapValidator.i18n.date || {}, {
         'default': 'Please enter a valid date',
-        min  : 'Please enter a date after %s',
-        max  : 'Please enter a date before %s',
-        range : 'Please enter a date in the range %s - %s'
+        min: 'Please enter a date after %s',
+        max: 'Please enter a date before %s',
+        range: 'Please enter a date in the range %s - %s'
     });
 
     $.fn.bootstrapValidator.validators.date = {
@@ -33,7 +33,7 @@
          * ii) date and time:
          * The time can consist of h, m, s parts which are separated by :
          * ii) date, time and A (indicating AM or PM)
-         * @returns {Boolean}
+         * @returns {Boolean|Object}
          */
         validate: function(validator, $field, options) {
             var value = $field.val();
@@ -165,47 +165,50 @@
                 }
             }
 
-            var valid = false, message;
-
             // Validate day, month, and year
-            valid   = $.fn.bootstrapValidator.helpers.date(year, month, day);
-            message = options.message || $.fn.bootstrapValidator.i18n.date['default'];
+            var valid   = $.fn.bootstrapValidator.helpers.date(year, month, day),
+                message = options.message || $.fn.bootstrapValidator.i18n.date['default'];
 
             // declare the date, min and max objects
-            var date = null, min = null, max = null,
-                minOption = options.min, maxOption = options.max;
+            var min       = null,
+                max       = null,
+                minOption = options.min,
+                maxOption = options.max;
 
-            if(minOption) {
-                if(isNaN(Date.parse(minOption))) {
+            if (minOption) {
+                if (isNaN(Date.parse(minOption))) {
                     minOption = validator.getDynamicOption($field, minOption);
                 }
-                min = this.parseDate(minOption, dateFormat, separator);
+                min = this._parseDate(minOption, dateFormat, separator);
             }
 
-            if(maxOption) {
-                if(isNaN(Date.parse(maxOption))) {
+            if (maxOption) {
+                if (isNaN(Date.parse(maxOption))) {
                     maxOption = validator.getDynamicOption($field, maxOption);
                 }
-                max = this.parseDate(maxOption, dateFormat, separator);
+                max = this._parseDate(maxOption, dateFormat, separator);
             }
 
             date = new Date(year, month, day, hours, minutes, seconds);
 
-            switch(true) {
-                case(minOption && !maxOption && valid):
+            switch (true) {
+                case (minOption && !maxOption && valid):
                     valid   = date.getTime() >= min.getTime();
                     message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.min, minOption);
                     break;
 
-                case(maxOption && !minOption && valid):
+                case (maxOption && !minOption && valid):
                     valid   = date.getTime() <= max.getTime();
                     message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.max, maxOption);
                     break;
 
-                case(maxOption && minOption && valid):
+                case (maxOption && minOption && valid):
                     valid   = date.getTime() <= max.getTime() && date.getTime() >= min.getTime();
                     message = options.message || $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.date.range, [minOption, maxOption]);
                     break;
+
+                default:
+                    break;
             }
 
             return {
@@ -226,17 +229,17 @@
          * @param {String} separator The separator used to separate the date, month, and year
          * @returns {Date}
          */
-        parseDate: function(date, format, separator) {
-            var year = 0, month = 0, day = 0, minutes = 0, hours = 0, seconds = 0,
+        _parseDate: function(date, format, separator) {
+            var minutes     = 0, hours = 0, seconds = 0,
                 sections    = date.split(' '),
                 dateSection = sections[0],
                 timeSection = (sections.length > 1) ? sections[1] : null;
 
-            dateSection  = dateSection.split(separator);
-            year  = dateSection[$.inArray('YYYY', format)];
-            month = dateSection[$.inArray('MM', format)];
-            day   = dateSection[$.inArray('DD', format)];
-            if(timeSection) {
+            dateSection = dateSection.split(separator);
+            var year  = dateSection[$.inArray('YYYY', format)],
+                month = dateSection[$.inArray('MM', format)],
+                day   = dateSection[$.inArray('DD', format)];
+            if (timeSection) {
                 timeSection = timeSection.split(':');
                 hours       = timeSection.length > 0 ? timeSection[0] : null;
                 minutes     = timeSection.length > 1 ? timeSection[1] : null;
@@ -245,6 +248,5 @@
 
             return new Date(year, month, day, hours, minutes, seconds);
         }
-
     };
 }(window.jQuery));

+ 647 - 2
test/spec.js

@@ -2351,6 +2351,18 @@ describe('creditCard', function() {
     });
 });
 
+function getDate(value, validator, $field) {
+    return validator.getFieldElements('date').val();
+};
+
+TestSuite = $.extend({}, TestSuite, {
+    Date: {
+        getDate: function(value, validator, $field) {
+            return validator.getFieldElements('date').val();
+        }
+    }
+});
+
 describe('date', function() {
     beforeEach(function() {
         $([
@@ -2359,13 +2371,25 @@ describe('date', function() {
                 '<div class="form-group">',
                     '<input type="text" name="date" data-bv-date />',
                 '</div>',
+                '<div class="form-group">',
+                    '<input type="text" name="minDate" data-bv-date data-bv-date-min="" />',
+                '</div>',
+                '<div class="form-group">',
+                    '<input type="text" name="maxDate" data-bv-date data-bv-date-max="" />',
+                '</div>',
+                '<div class="form-group">',
+                    '<input type="text" name="range" data-bv-date data-bv-date-min="" data-bv-date-max="" />',
+                '</div>',
             '</form>'
         ].join('\n')).appendTo('body');
 
         $('#dateForm').bootstrapValidator();
 
-        this.bv    = $('#dateForm').data('bootstrapValidator');
-        this.$date = this.bv.getFieldElements('date');
+        this.bv       = $('#dateForm').data('bootstrapValidator');
+        this.$date    = this.bv.getFieldElements('date');
+        this.$minDate = this.bv.getFieldElements('minDate');
+        this.$maxDate = this.bv.getFieldElements('maxDate');
+        this.$range   = this.bv.getFieldElements('range');
     });
 
     afterEach(function() {
@@ -2539,6 +2563,627 @@ describe('date', function() {
         this.bv.validate();
         expect(this.bv.isValid()).toBeTruthy();
     });
+
+    // min test suite
+    it('min date format YYYY/MM/DD', function() {
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+        this.bv.updateOption('minDate', 'date', 'min', '2010/01/01');
+
+        this.$minDate.val('2010/01/02');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2010/01/002'); // day prefexid by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2009/12/31');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2000/01/01');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+    });
+
+    it('min date format YYYY-MM-DD', function() {
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY-MM-DD');
+        this.bv.updateOption('minDate', 'date', 'min', '2010-01-01');
+
+        this.$minDate.val('2010-01-02');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2010-001-02'); // month prefexid by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2014-08-17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2000-01-01');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+    });
+
+    it('min date format DD/MM/YYYY', function() {
+        this.bv.updateOption('minDate', 'date', 'format', 'DD/MM/YYYY');
+        this.bv.updateOption('minDate', 'date', 'min', '01/01/2010');
+
+        this.$minDate.val('02/01/2010');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('17/08/2014');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('02/01/02010'); // year prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('31/12/2009');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('01/01/2000');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+    });
+
+    it('min date format YYYY-MM-DD h:m:s', function() {
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY-MM-DD h:m:s');
+        this.bv.updateOption('minDate', 'date', 'min', '2010-01-01 01:00:00');
+
+        this.bv.resetForm();
+        this.$minDate.val('2010-01-01 01:00:01');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.$minDate.val('2010-01-02 01:00:01');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2014-08-17 12:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31 00:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31 010:00:00'); // hours prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31 10:001:00'); // minutes prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31 10:01:012'); // seconds prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2009-12-31 00:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$minDate.val('2000-01-01 23:00:12');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toEqual(false);
+    });
+
+    // max test suite
+    it('max date format YYYY/MM/DD', function() {
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+        this.bv.updateOption('maxDate', 'date', 'max', '2014/09/10');
+
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('02014/012/031'); // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014/12/31');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2015/01/01');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+    });
+
+    it('max date format YYYY-MM-DD', function() {
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY-MM-DD');
+        this.bv.updateOption('maxDate', 'date', 'max', '2014-09-10');
+
+        this.$maxDate.val('2014-09-09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014-08-17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('02014-012-031');  // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014-12-31');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2015-01-01');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+    });
+
+    it('max date format DD/MM/YYYY', function() {
+        this.bv.updateOption('maxDate', 'date', 'format', 'DD/MM/YYYY');
+        this.bv.updateOption('maxDate', 'date', 'max', '10/09/2014');
+
+        this.$maxDate.val('09/09/2014');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('17/08/2014');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('031/012/02014'); // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('31/12/2014');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('01/01/2015');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+    });
+
+    it('max date format YYYY-MM-DD h:m:s', function() {
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY-MM-DD h:m:s');
+        this.bv.updateOption('maxDate', 'date', 'max', '2014-09-10 01:00:00');
+
+        this.$maxDate.val('2014-09-09 01:00:01');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014-08-17 12:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014-09-09 001:001:001'); // hours, minutes or seconds prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2014-12-31 00:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$maxDate.val('2015-01-01 23:00:12');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toEqual(false);
+    });
+
+    // range test suite
+    it('range format YYYY/MM/DD', function() {
+        this.bv.updateOption('range', 'date', 'format', 'YYYY/MM/DD');
+        this.bv.updateOption('range', 'date', 'min', '2010/09/10');
+        this.bv.updateOption('range', 'date', 'max', '2014/09/10');
+
+        this.$range.val('2011/01/01');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('02014/001/031'); // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2010/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2014/09/11');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+    });
+
+    it('range format YYYY-MM-DD', function() {
+        this.bv.updateOption('range', 'date', 'format', 'YYYY-MM-DD');
+        this.bv.updateOption('range', 'date', 'min', '2010-09-10');
+        this.bv.updateOption('range', 'date', 'max', '2014-09-10');
+
+        this.$range.val('2012-01-12');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('2014-09-09');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('02014-003-031');  // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2009-12-31');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2015-01-01');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+    });
+
+    it('range format DD/MM/YYYY', function() {
+        this.bv.updateOption('range', 'date', 'format', 'DD/MM/YYYY');
+        this.bv.updateOption('range', 'date', 'min', '10/09/2010');
+        this.bv.updateOption('range', 'date', 'max', '10/09/2014');
+
+        this.$range.val('11/11/2011');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('17/08/2014');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('031/012/02013'); // year, month or day prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('31/01/2010');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('25/03/2015');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+    });
+
+    it('range format YYYY-MM-DD h:m:s', function() {
+        this.bv.updateOption('range', 'date', 'format', 'YYYY-MM-DD h:m:s');
+        this.bv.updateOption('range', 'date', 'min', '2010-05-15 22:00:00');
+        this.bv.updateOption('range', 'date', 'max', '2015-05-15 22:00:00');
+
+        this.$range.val('2012-07-17 01:00:01');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('2013-08-17 12:00:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$range.val('2011-06-19 001:001:001'); // hours, minutes or seconds prefixed by 0 not allowed
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2008-11-27 23:15:00');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+
+        this.bv.resetForm();
+        this.$range.val('2015-05-15 22:00:01');
+        this.bv.validate();
+        expect(this.bv.isValidField('range')).toEqual(false);
+    });
+
+    // dynamic min option
+    it('dynamic min: name of field', function() {
+        this.$minDate.attr('data-bv-date-min', 'date');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    it('dynamic min: callback declarative function', function() {
+        this.$minDate.attr('data-bv-date-min', 'getDate');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/10/01');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    it('dynamic min: callback declarative function()', function() {
+        this.$minDate.attr('data-bv-date-min', 'getDate()');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/10/01');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    it('dynamic min: callback declarative A.B.C', function() {
+        this.$minDate.attr('data-bv-date-min', 'TestSuite.Date.getDate');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/10/01');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    it('dynamic min: callback declarative A.B.C()', function() {
+        this.$minDate.attr('data-bv-date-min', 'TestSuite.Date.getDate()');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/10/01');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    it('dynamic min: callback programmatically', function() {
+        this.$minDate.removeAttr('data-bv-date-min');
+        this.bv.destroy();
+        this.bv = $('#dateForm')
+                        .bootstrapValidator({
+                            fields: {
+                                minDate: {
+                                    validators: {
+                                        date: {
+                                            min: function(value, validator, $field) {
+                                                return getDate(value, validator, $field);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        })
+                        .data('bootstrapValidator');
+        this.bv.updateOption('minDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2014/09/08');
+        this.$minDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/10/01');
+        this.$minDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('minDate')).toBeFalsy();
+    });
+
+    // dynamic max option
+    it('dynamic max: name of field', function() {
+        this.$maxDate.attr('data-bv-date-max', 'date');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
+
+    it('dynamic max: callback declarative function', function() {
+        this.$maxDate.attr('data-bv-date-max', 'getDate');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
+
+    it('dynamic max: callback declarative function()', function() {
+        this.$maxDate.attr('data-bv-date-max', 'getDate()');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
+
+    it('dynamic max: callback declarative A.B.C', function() {
+        this.$maxDate.attr('data-bv-date-max', 'TestSuite.Date.getDate');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
+
+    it('dynamic max: callback declarative A.B.C()', function() {
+        this.$maxDate.attr('data-bv-date-max', 'TestSuite.Date.getDate()');
+        this.bv.destroy();
+        this.bv = $('#dateForm').bootstrapValidator().data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
+
+    it('dynamic max: callback programmatically', function() {
+        this.$maxDate.removeAttr('data-bv-date-max');
+        this.bv.destroy();
+        this.bv = $('#dateForm')
+                        .bootstrapValidator({
+                            fields: {
+                                maxDate: {
+                                    validators: {
+                                        date: {
+                                            max: function(value, validator, $field) {
+                                                return getDate(value, validator, $field);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        })
+                        .data('bootstrapValidator');
+        this.bv.updateOption('maxDate', 'date', 'format', 'YYYY/MM/DD');
+
+        this.$date.val('2015/01/01');
+        this.$maxDate.val('2014/09/09');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$date.val('2014/01/01');
+        this.$maxDate.val('2014/08/17');
+        this.bv.validate();
+        expect(this.bv.isValidField('maxDate')).toBeFalsy();
+    });
 });
 
 describe('ean', function() {