ソースを参照

#430: lessThan adds support for comparing to other field, return value of a callback function

phuoc 11 年 前
コミット
3443704ba5

+ 1 - 1
CHANGELOG.md

@@ -49,7 +49,7 @@ __Improvements__
 * [#420](https://github.com/nghuuphuoc/bootstrapvalidator/issues/420): Enable/disable particular validator
 * [#422](https://github.com/nghuuphuoc/bootstrapvalidator/issues/422): Exclude particular field by ```excluded``` option or ```data-bv-excluded``` attribute
 * [#426](https://github.com/nghuuphuoc/bootstrapvalidator/issues/426): Add test suite
-* [#430](https://github.com/nghuuphuoc/bootstrapvalidator/issues/430): [greaterThan](http://bootstrapvalidator.com/validators/greaterThan/) adds support for comparing to other field, return value of a callback function
+* [#430](https://github.com/nghuuphuoc/bootstrapvalidator/issues/430): [greaterThan](http://bootstrapvalidator.com/validators/greaterThan/), [lessThan](http://bootstrapvalidator.com/validators/lessThan/) add support for comparing to other field, return value of a callback function
 * [#431](https://github.com/nghuuphuoc/bootstrapvalidator/issues/431): Add built time to the build file
 * [#432](https://github.com/nghuuphuoc/bootstrapvalidator/issues/432): Define the callback via ```data-bv-callback-callback``` attribute
 * [#447](https://github.com/nghuuphuoc/bootstrapvalidator/pull/447): [zipCode validator](http://bootstrapvalidator.com/validators/zipCode/) allow to set the country code via another field or callback, thanks to [@AlaskanShade](https://github.com/AlaskanShade)

+ 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.0-dev, built on 2014-07-05 5:51:14 PM
+ * @version     v0.5.0-dev, built on 2014-07-05 6:00:00 PM
  * @author      https://twitter.com/nghuuphuoc
  * @copyright   (c) 2013 - 2014 Nguyen Huu Phuoc
  * @license     MIT

+ 25 - 11
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.0-dev, built on 2014-07-05 5:51:14 PM
+ * @version     v0.5.0-dev, built on 2014-07-05 6:00:00 PM
  * @author      https://twitter.com/nghuuphuoc
  * @copyright   (c) 2013 - 2014 Nguyen Huu Phuoc
  * @license     MIT
@@ -4077,13 +4077,7 @@
 ;(function($) {
     $.fn.bootstrapValidator.i18n.lessThan = $.extend($.fn.bootstrapValidator.i18n.lessThan || {}, {
         'default': 'Please enter a value less than or equal to %s',
-        notInclusive: 'Please enter a value less than %s',
-
-        getMessage: function(options) {
-            return (options.inclusive === true || options.inclusive === undefined)
-                    ? $.fn.bootstrapValidator.helpers.format(this['default'], options.value)
-                    : $.fn.bootstrapValidator.helpers.format(this.notInclusive, options.value);
-        }
+        notInclusive: 'Please enter a value less than %s'
     });
 
     $.fn.bootstrapValidator.validators.lessThan = {
@@ -4110,18 +4104,38 @@
          * @param {BootstrapValidator} validator The validator plugin instance
          * @param {jQuery} $field Field element
          * @param {Object} options Can consist of the following keys:
-         * - value: The number used to compare to
+         * - value: The number used to compare to. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
          * - inclusive [optional]: Can be true or false. Default is true
          * - message: The invalid message
-         * @returns {Boolean}
+         * @returns {Object}
          */
         validate: function(validator, $field, options) {
             var value = $field.val();
             if (value === '') {
                 return true;
             }
+
+            var compareTo = options.value;
+            if ('function' === typeof compareTo) {
+                compareTo = $.fn.bootstrapValidator.helpers.call(compareTo, [value, validator, $field]);
+            } else if ('string' === typeof compareTo && !$.isNumeric(compareTo)) {
+                var $compareField = validator.getFieldElements(compareTo);
+                if ($compareField.length) {
+                    compareTo = $compareField.val();
+                } else {
+                    compareTo = $.fn.bootstrapValidator.helpers.call(compareTo, [value, validator, $field]);
+                }
+            }
+
             value = parseFloat(value);
-            return (options.inclusive === true || options.inclusive === undefined) ? (value <= options.value) : (value < options.value);
+            return (options.inclusive === true || options.inclusive === undefined)
+                    ? { valid: value <= compareTo, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'],   compareTo) }
+                    : { valid: value < compareTo,  message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan.notInclusive, compareTo) };
         }
     };
 }(window.jQuery));

ファイルの差分が大きいため隠しています
+ 3 - 3
dist/js/bootstrapValidator.min.js


+ 24 - 10
src/js/validator/lessThan.js

@@ -1,13 +1,7 @@
 (function($) {
     $.fn.bootstrapValidator.i18n.lessThan = $.extend($.fn.bootstrapValidator.i18n.lessThan || {}, {
         'default': 'Please enter a value less than or equal to %s',
-        notInclusive: 'Please enter a value less than %s',
-
-        getMessage: function(options) {
-            return (options.inclusive === true || options.inclusive === undefined)
-                    ? $.fn.bootstrapValidator.helpers.format(this['default'], options.value)
-                    : $.fn.bootstrapValidator.helpers.format(this.notInclusive, options.value);
-        }
+        notInclusive: 'Please enter a value less than %s'
     });
 
     $.fn.bootstrapValidator.validators.lessThan = {
@@ -34,18 +28,38 @@
          * @param {BootstrapValidator} validator The validator plugin instance
          * @param {jQuery} $field Field element
          * @param {Object} options Can consist of the following keys:
-         * - value: The number used to compare to
+         * - value: The number used to compare to. It can be
+         *      - A number
+         *      - Name of field which its value defines the number
+         *      - Name of callback function that returns the number
+         *      - A callback function that returns the number
+         *
          * - inclusive [optional]: Can be true or false. Default is true
          * - message: The invalid message
-         * @returns {Boolean}
+         * @returns {Object}
          */
         validate: function(validator, $field, options) {
             var value = $field.val();
             if (value === '') {
                 return true;
             }
+
+            var compareTo = options.value;
+            if ('function' === typeof compareTo) {
+                compareTo = $.fn.bootstrapValidator.helpers.call(compareTo, [value, validator, $field]);
+            } else if ('string' === typeof compareTo && !$.isNumeric(compareTo)) {
+                var $compareField = validator.getFieldElements(compareTo);
+                if ($compareField.length) {
+                    compareTo = $compareField.val();
+                } else {
+                    compareTo = $.fn.bootstrapValidator.helpers.call(compareTo, [value, validator, $field]);
+                }
+            }
+
             value = parseFloat(value);
-            return (options.inclusive === true || options.inclusive === undefined) ? (value <= options.value) : (value < options.value);
+            return (options.inclusive === true || options.inclusive === undefined)
+                    ? { valid: value <= compareTo, message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'],   compareTo) }
+                    : { valid: value < compareTo,  message: $.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan.notInclusive, compareTo) };
         }
     };
 }(window.jQuery));

+ 129 - 14
test/spec.js

@@ -1221,74 +1221,77 @@ describe('i18n', function() {
     });
 
     it('default message', function() {
+        var format = $.fn.bootstrapValidator.helpers.format,
+            i18n   = $.fn.bootstrapValidator.i18n;
+
         this.bv.validate();
-        expect(this.bv.getMessages(this.$fullName, 'notEmpty')[0]).toEqual($.fn.bootstrapValidator.i18n.notEmpty['default']);
+        expect(this.bv.getMessages(this.$fullName, 'notEmpty')[0]).toEqual(i18n.notEmpty['default']);
 
         this.$fullName.val('lowerName');
         this.bv.revalidateField('fullName');
-        expect(this.bv.getMessages('fullName', 'stringCase')[0]).toEqual($.fn.bootstrapValidator.i18n.stringCase.upper);
+        expect(this.bv.getMessages('fullName', 'stringCase')[0]).toEqual(i18n.stringCase.upper);
 
         this.bv.resetForm();
         this.$userName.val('123');
         this.bv.validate();
-        expect(this.bv.getMessages('username', 'stringLength')[0]).toEqual($.fn.bootstrapValidator.i18n.stringLength.getMessage({ min: 6, max: 20 }));
+        expect(this.bv.getMessages('username', 'stringLength')[0]).toEqual(i18n.stringLength.getMessage({ min: 6, max: 20 }));
 
         this.bv.resetForm();
         this.$userName.val('contain@#$');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$userName, 'regexp')[0]).toEqual($.fn.bootstrapValidator.i18n.regexp['default']);
+        expect(this.bv.getMessages(this.$userName, 'regexp')[0]).toEqual(i18n.regexp['default']);
 
         this.bv.resetForm();
         this.$userName.val('validUserName');
         this.$password.val('validUserName');
         this.bv.validate();
-        expect(this.bv.getMessages('username', 'different')[0]).toEqual($.fn.bootstrapValidator.i18n.different['default']);
+        expect(this.bv.getMessages('username', 'different')[0]).toEqual(i18n.different['default']);
 
         this.bv.resetForm();
         this.$email.val('invalid#email@address');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$email, 'emailAddress')[0]).toEqual($.fn.bootstrapValidator.i18n.emailAddress['default']);
+        expect(this.bv.getMessages(this.$email, 'emailAddress')[0]).toEqual(i18n.emailAddress['default']);
 
         this.bv.resetForm();
         this.$password.val('@S3cur3P@@w0rd');
         this.$confirm.val('notMatch');
         this.bv.validate();
-        expect(this.bv.getMessages('password', 'identical')[0]).toEqual($.fn.bootstrapValidator.i18n.identical['default']);
+        expect(this.bv.getMessages('password', 'identical')[0]).toEqual(i18n.identical['default']);
 
         this.bv.resetForm();
         this.$age.val('notDigit');
         this.bv.validate();
-        expect(this.bv.getMessages('age', 'digits')[0]).toEqual($.fn.bootstrapValidator.i18n.digits['default']);
+        expect(this.bv.getMessages('age', 'digits')[0]).toEqual(i18n.digits['default']);
 
         this.bv.resetForm();
         this.$age.val(10);
         this.bv.validate();
-        expect(this.bv.getMessages(this.$age, 'greaterThan')[0]).toEqual($.fn.bootstrapValidator.i18n.greaterThan.getMessage({ value: 18 }));
+        expect(this.bv.getMessages(this.$age, 'greaterThan')[0]).toEqual(format(i18n.greaterThan['default'], 18));
 
         this.bv.resetForm();
         this.$age.val(120);
         this.bv.validate();
-        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.i18n.lessThan.getMessage({ value: 100 }));
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual(format(i18n.lessThan['default'], 100));
 
         this.bv.resetForm();
         this.$website.val('http://invalidWebsite');
         this.bv.validate();
-        expect(this.bv.getMessages('website', 'uri')[0]).toEqual($.fn.bootstrapValidator.i18n.uri['default']);
+        expect(this.bv.getMessages('website', 'uri')[0]).toEqual(i18n.uri['default']);
 
         this.bv.resetForm();
         this.$phone.val('123456');
         this.bv.validate();
-        expect(this.bv.getMessages('phoneNumber', 'phone')[0]).toEqual($.fn.bootstrapValidator.i18n.phone.getMessage({ country: 'US' }));
+        expect(this.bv.getMessages('phoneNumber', 'phone')[0]).toEqual(i18n.phone.getMessage({ country: 'US' }));
 
         this.bv.resetForm();
         this.$program.eq(0).prop('checked', 'checked');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$program, 'choice')[0]).toEqual($.fn.bootstrapValidator.i18n.choice.getMessage({ min: 2, max: 4 }));
+        expect(this.bv.getMessages(this.$program, 'choice')[0]).toEqual(i18n.choice.getMessage({ min: 2, max: 4 }));
 
         this.bv.resetForm();
         this.$program.prop('checked', 'checked');
         this.bv.validate();
-        expect(this.bv.getMessages('programs[]', 'choice')[0]).toEqual($.fn.bootstrapValidator.i18n.choice.getMessage({ min: 2, max: 4 }));
+        expect(this.bv.getMessages('programs[]', 'choice')[0]).toEqual(i18n.choice.getMessage({ min: 2, max: 4 }));
     });
 });
 
@@ -2900,6 +2903,118 @@ describe('issn', function() {
     });
 });
 
+function lessThanCompare() {
+    var compareTo = $('#lessThanForm').find('[name="maxAge"]').val();
+    $('#msg').html('lessThanCompare() called; compare to ' + compareTo);
+    return compareTo;
+};
+
+TestSuite = $.extend({}, TestSuite, {
+    lessThan: {
+        compareTo: function(value, validator, $field) {
+            var compareTo = $('#lessThanForm').find('[name="maxAge"]').val();
+            $('#msg').html('TestSuite.lessThan.compareTo() called; compare to ' + compareTo);
+            return compareTo;
+        }
+    }
+});
+
+describe('lessThan', function() {
+    beforeEach(function() {
+        $([
+            '<form class="form-horizontal" id="lessThanForm">',
+                '<div id="msg"></div>',
+                '<div class="form-group">',
+                    '<input type="text" name="maxAge" />',
+                '</div>',
+                '<div class="form-group">',
+                    '<input type="text" name="age" data-bv-lessthan data-bv-lessthan-value="100" />',
+                '</div>',
+            '</form>'
+        ].join('\n')).appendTo('body');
+
+        $('#lessThanForm').bootstrapValidator();
+
+        this.bv      = $('#lessThanForm').data('bootstrapValidator');
+        this.$maxAge = this.bv.getFieldElements('maxAge');
+        this.$age    = this.bv.getFieldElements('age');
+    });
+
+    afterEach(function() {
+        $('#lessThanForm').bootstrapValidator('destroy').remove();
+    });
+
+    it('compare to value', function() {
+        this.$age.val(120);
+        this.bv.validate();
+        expect(this.bv.isValid()).toEqual(false);
+
+        this.bv.resetForm();
+        this.$age.val(30);
+        this.bv.validate();
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+
+    // Compare to maxAge field
+    it('compare to other field', function() {
+        this.$age.attr('data-bv-lessthan-value', 'maxAge');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(40);
+        this.$age.val(20);
+        this.bv.validate();
+        expect(this.bv.isValid()).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxAge.val(20);
+        this.$age.val(30);
+        this.bv.validate();
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+    });
+
+    it('compare to return value of a function', function() {
+        this.$age.attr('data-bv-lessthan-value', 'lessThanCompare');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(50);
+        this.$age.val(60);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('lessThanCompare() called; compare to 50');
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+
+        this.bv.resetForm();
+        this.$maxAge.val(60);
+        this.$age.val(30);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('lessThanCompare() called; compare to 60');
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+
+    it('compare to return value of a namespace function', function() {
+        this.$age.attr('data-bv-lessthan-value', 'TestSuite.lessThan.compareTo');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(50);
+        this.$age.val(60);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('TestSuite.lessThan.compareTo() called; compare to 50');
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+
+        this.bv.resetForm();
+        this.$maxAge.val(60);
+        this.$age.val(30);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('TestSuite.lessThan.compareTo() called; compare to 60');
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+});
+
 describe('vat', function() {
     beforeEach(function() {
         $([

+ 17 - 14
test/spec/i18n.js

@@ -248,73 +248,76 @@ describe('i18n', function() {
     });
 
     it('default message', function() {
+        var format = $.fn.bootstrapValidator.helpers.format,
+            i18n   = $.fn.bootstrapValidator.i18n;
+
         this.bv.validate();
-        expect(this.bv.getMessages(this.$fullName, 'notEmpty')[0]).toEqual($.fn.bootstrapValidator.i18n.notEmpty['default']);
+        expect(this.bv.getMessages(this.$fullName, 'notEmpty')[0]).toEqual(i18n.notEmpty['default']);
 
         this.$fullName.val('lowerName');
         this.bv.revalidateField('fullName');
-        expect(this.bv.getMessages('fullName', 'stringCase')[0]).toEqual($.fn.bootstrapValidator.i18n.stringCase.upper);
+        expect(this.bv.getMessages('fullName', 'stringCase')[0]).toEqual(i18n.stringCase.upper);
 
         this.bv.resetForm();
         this.$userName.val('123');
         this.bv.validate();
-        expect(this.bv.getMessages('username', 'stringLength')[0]).toEqual($.fn.bootstrapValidator.i18n.stringLength.getMessage({ min: 6, max: 20 }));
+        expect(this.bv.getMessages('username', 'stringLength')[0]).toEqual(i18n.stringLength.getMessage({ min: 6, max: 20 }));
 
         this.bv.resetForm();
         this.$userName.val('contain@#$');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$userName, 'regexp')[0]).toEqual($.fn.bootstrapValidator.i18n.regexp['default']);
+        expect(this.bv.getMessages(this.$userName, 'regexp')[0]).toEqual(i18n.regexp['default']);
 
         this.bv.resetForm();
         this.$userName.val('validUserName');
         this.$password.val('validUserName');
         this.bv.validate();
-        expect(this.bv.getMessages('username', 'different')[0]).toEqual($.fn.bootstrapValidator.i18n.different['default']);
+        expect(this.bv.getMessages('username', 'different')[0]).toEqual(i18n.different['default']);
 
         this.bv.resetForm();
         this.$email.val('invalid#email@address');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$email, 'emailAddress')[0]).toEqual($.fn.bootstrapValidator.i18n.emailAddress['default']);
+        expect(this.bv.getMessages(this.$email, 'emailAddress')[0]).toEqual(i18n.emailAddress['default']);
 
         this.bv.resetForm();
         this.$password.val('@S3cur3P@@w0rd');
         this.$confirm.val('notMatch');
         this.bv.validate();
-        expect(this.bv.getMessages('password', 'identical')[0]).toEqual($.fn.bootstrapValidator.i18n.identical['default']);
+        expect(this.bv.getMessages('password', 'identical')[0]).toEqual(i18n.identical['default']);
 
         this.bv.resetForm();
         this.$age.val('notDigit');
         this.bv.validate();
-        expect(this.bv.getMessages('age', 'digits')[0]).toEqual($.fn.bootstrapValidator.i18n.digits['default']);
+        expect(this.bv.getMessages('age', 'digits')[0]).toEqual(i18n.digits['default']);
 
         this.bv.resetForm();
         this.$age.val(10);
         this.bv.validate();
-        expect(this.bv.getMessages(this.$age, 'greaterThan')[0]).toEqual($.fn.bootstrapValidator.i18n.greaterThan.getMessage({ value: 18 }));
+        expect(this.bv.getMessages(this.$age, 'greaterThan')[0]).toEqual(format(i18n.greaterThan['default'], 18));
 
         this.bv.resetForm();
         this.$age.val(120);
         this.bv.validate();
-        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.i18n.lessThan.getMessage({ value: 100 }));
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual(format(i18n.lessThan['default'], 100));
 
         this.bv.resetForm();
         this.$website.val('http://invalidWebsite');
         this.bv.validate();
-        expect(this.bv.getMessages('website', 'uri')[0]).toEqual($.fn.bootstrapValidator.i18n.uri['default']);
+        expect(this.bv.getMessages('website', 'uri')[0]).toEqual(i18n.uri['default']);
 
         this.bv.resetForm();
         this.$phone.val('123456');
         this.bv.validate();
-        expect(this.bv.getMessages('phoneNumber', 'phone')[0]).toEqual($.fn.bootstrapValidator.i18n.phone.getMessage({ country: 'US' }));
+        expect(this.bv.getMessages('phoneNumber', 'phone')[0]).toEqual(i18n.phone.getMessage({ country: 'US' }));
 
         this.bv.resetForm();
         this.$program.eq(0).prop('checked', 'checked');
         this.bv.validate();
-        expect(this.bv.getMessages(this.$program, 'choice')[0]).toEqual($.fn.bootstrapValidator.i18n.choice.getMessage({ min: 2, max: 4 }));
+        expect(this.bv.getMessages(this.$program, 'choice')[0]).toEqual(i18n.choice.getMessage({ min: 2, max: 4 }));
 
         this.bv.resetForm();
         this.$program.prop('checked', 'checked');
         this.bv.validate();
-        expect(this.bv.getMessages('programs[]', 'choice')[0]).toEqual($.fn.bootstrapValidator.i18n.choice.getMessage({ min: 2, max: 4 }));
+        expect(this.bv.getMessages('programs[]', 'choice')[0]).toEqual(i18n.choice.getMessage({ min: 2, max: 4 }));
     });
 });

+ 111 - 0
test/spec/validator/lessThan.js

@@ -0,0 +1,111 @@
+function lessThanCompare() {
+    var compareTo = $('#lessThanForm').find('[name="maxAge"]').val();
+    $('#msg').html('lessThanCompare() called; compare to ' + compareTo);
+    return compareTo;
+};
+
+TestSuite = $.extend({}, TestSuite, {
+    lessThan: {
+        compareTo: function(value, validator, $field) {
+            var compareTo = $('#lessThanForm').find('[name="maxAge"]').val();
+            $('#msg').html('TestSuite.lessThan.compareTo() called; compare to ' + compareTo);
+            return compareTo;
+        }
+    }
+});
+
+describe('lessThan', function() {
+    beforeEach(function() {
+        $([
+            '<form class="form-horizontal" id="lessThanForm">',
+                '<div id="msg"></div>',
+                '<div class="form-group">',
+                    '<input type="text" name="maxAge" />',
+                '</div>',
+                '<div class="form-group">',
+                    '<input type="text" name="age" data-bv-lessthan data-bv-lessthan-value="100" />',
+                '</div>',
+            '</form>'
+        ].join('\n')).appendTo('body');
+
+        $('#lessThanForm').bootstrapValidator();
+
+        this.bv      = $('#lessThanForm').data('bootstrapValidator');
+        this.$maxAge = this.bv.getFieldElements('maxAge');
+        this.$age    = this.bv.getFieldElements('age');
+    });
+
+    afterEach(function() {
+        $('#lessThanForm').bootstrapValidator('destroy').remove();
+    });
+
+    it('compare to value', function() {
+        this.$age.val(120);
+        this.bv.validate();
+        expect(this.bv.isValid()).toEqual(false);
+
+        this.bv.resetForm();
+        this.$age.val(30);
+        this.bv.validate();
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+
+    // Compare to maxAge field
+    it('compare to other field', function() {
+        this.$age.attr('data-bv-lessthan-value', 'maxAge');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(40);
+        this.$age.val(20);
+        this.bv.validate();
+        expect(this.bv.isValid()).toBeTruthy();
+
+        this.bv.resetForm();
+        this.$maxAge.val(20);
+        this.$age.val(30);
+        this.bv.validate();
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+    });
+
+    it('compare to return value of a function', function() {
+        this.$age.attr('data-bv-lessthan-value', 'lessThanCompare');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(50);
+        this.$age.val(60);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('lessThanCompare() called; compare to 50');
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+
+        this.bv.resetForm();
+        this.$maxAge.val(60);
+        this.$age.val(30);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('lessThanCompare() called; compare to 60');
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+
+    it('compare to return value of a namespace function', function() {
+        this.$age.attr('data-bv-lessthan-value', 'TestSuite.lessThan.compareTo');
+        this.bv.destroy();
+        this.bv = $('#lessThanForm').bootstrapValidator().data('bootstrapValidator');
+
+        this.$maxAge.val(50);
+        this.$age.val(60);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('TestSuite.lessThan.compareTo() called; compare to 50');
+        expect(this.bv.isValid()).toEqual(false);
+        expect(this.bv.getMessages('age', 'lessThan')[0]).toEqual($.fn.bootstrapValidator.helpers.format($.fn.bootstrapValidator.i18n.lessThan['default'], this.$maxAge.val()));
+
+        this.bv.resetForm();
+        this.$maxAge.val(60);
+        this.$age.val(30);
+        this.bv.validate();
+        expect($('#msg').html()).toEqual('TestSuite.lessThan.compareTo() called; compare to 60');
+        expect(this.bv.isValid()).toBeTruthy();
+    });
+});