@@ -16,6 +16,10 @@ var INTEGER_REGEXP = /^\s*(\-|\+)?\d+\s*$/;
16
16
* @param {string } ng:model Assignable angular expression to data-bind to.
17
17
* @param {string= } name Property name of the form under which the widgets is published.
18
18
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
19
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
20
+ * minlength.
21
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
22
+ * maxlength.
19
23
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
20
24
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
21
25
* patterns defined as scope expressions.
@@ -79,6 +83,10 @@ var INTEGER_REGEXP = /^\s*(\-|\+)?\d+\s*$/;
79
83
* @param {string } ng:model Assignable angular expression to data-bind to.
80
84
* @param {string= } name Property name of the form under which the widgets is published.
81
85
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
86
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
87
+ * minlength.
88
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
89
+ * maxlength.
82
90
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
83
91
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
84
92
* patterns defined as scope expressions.
@@ -146,6 +154,10 @@ angularInputType('email', function() {
146
154
* @param {string } ng:model Assignable angular expression to data-bind to.
147
155
* @param {string= } name Property name of the form under which the widgets is published.
148
156
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
157
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
158
+ * minlength.
159
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
160
+ * maxlength.
149
161
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
150
162
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
151
163
* patterns defined as scope expressions.
@@ -288,6 +300,10 @@ angularInputType('list', function() {
288
300
* @param {string= } min Sets the `MIN` validation error key if the value entered is less then `min`.
289
301
* @param {string= } max Sets the `MAX` validation error key if the value entered is greater then `min`.
290
302
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
303
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
304
+ * minlength.
305
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
306
+ * maxlength.
291
307
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
292
308
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
293
309
* patterns defined as scope expressions.
@@ -353,6 +369,10 @@ angularInputType('number', numericRegexpInputType(NUMBER_REGEXP, 'NUMBER'));
353
369
* @param {string= } min Sets the `MIN` validation error key if the value entered is less then `min`.
354
370
* @param {string= } max Sets the `MAX` validation error key if the value entered is greater then `min`.
355
371
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
372
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
373
+ * minlength.
374
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
375
+ * maxlength.
356
376
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
357
377
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
358
378
* patterns defined as scope expressions.
@@ -601,6 +621,10 @@ var HTML5_INPUTS_TYPES = makeMap(
601
621
* @param {string } ng:model Assignable angular expression to data-bind to.
602
622
* @param {string= } name Property name of the form under which the widgets is published.
603
623
* @param {string= } required Sets `REQUIRED` validation error key if the value is not entered.
624
+ * @param {number= } ng:minlength Sets `MINLENGTH` validation error key if the value is shorter than
625
+ * minlength.
626
+ * @param {number= } ng:maxlength Sets `MAXLENGTH` validation error key if the value is longer than
627
+ * maxlength.
604
628
* @param {string= } ng:pattern Sets `PATTERN` validation error key if the value does not match the
605
629
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
606
630
* patterns defined as scope expressions.
@@ -612,32 +636,69 @@ var HTML5_INPUTS_TYPES = makeMap(
612
636
<doc:source>
613
637
<script>
614
638
function Ctrl() {
615
- this.text = 'guest';
639
+ this.user = {name: 'guest', last: 'visitor'} ;
616
640
}
617
641
</script>
618
642
<div ng:controller="Ctrl">
619
643
<form name="myForm">
620
- text: <input type="text" name="input" ng:model="text" required>
621
- <span class="error" ng:show="myForm.input.$error.REQUIRED">
622
- Required!</span>
644
+ User name: <input type="text" name="userName" ng:model="user.name" required>
645
+ <span class="error" ng:show="myForm.userName.$error.REQUIRED">
646
+ Required!</span><br>
647
+ Last name: <input type="text" name="lastName" ng:model="user.last"
648
+ ng:minlength="3" ng:maxlength="10">
649
+ <span class="error" ng:show="myForm.lastName.$error.MINLENGTH">
650
+ Too short!</span>
651
+ <span class="error" ng:show="myForm.lastName.$error.MAXLENGTH">
652
+ Too long!</span><br>
623
653
</form>
624
- <tt>text = {{text}}</tt><br/>
625
- <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
626
- <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
627
- <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
628
- <tt>myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}</tt><br/>
654
+ <hr>
655
+ <tt>user = {{user}}</tt><br/>
656
+ <tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
657
+ <tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
658
+ <tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
659
+ <tt>myForm.userName.$error = {{myForm.lastName.$error}}</tt><br>
660
+ <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
661
+ <tt>myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}</tt><br>
662
+ <tt>myForm.$error.MINLENGTH = {{!!myForm.$error.MINLENGTH}}</tt><br>
663
+ <tt>myForm.$error.MAXLENGTH = {{!!myForm.$error.MAXLENGTH}}</tt><br>
629
664
</div>
630
665
</doc:source>
631
666
<doc:scenario>
632
667
it('should initialize to model', function() {
633
- expect(binding('text')).toEqual('guest');
634
- expect(binding('myForm.input.$valid')).toEqual('true');
668
+ expect(binding('user')).toEqual('{\n \"last\":\"visitor",\n \"name\":\"guest\"}');
669
+ expect(binding('myForm.userName.$valid')).toEqual('true');
670
+ expect(binding('myForm.$valid')).toEqual('true');
635
671
});
636
672
637
- it('should be invalid if empty', function() {
638
- input('text').enter('');
639
- expect(binding('text')).toEqual('');
640
- expect(binding('myForm.input.$valid')).toEqual('false');
673
+ it('should be invalid if empty when required', function() {
674
+ input('user.name').enter('');
675
+ expect(binding('user')).toEqual('{\n \"last\":\"visitor",\n \"name\":\"\"}');
676
+ expect(binding('myForm.userName.$valid')).toEqual('false');
677
+ expect(binding('myForm.$valid')).toEqual('false');
678
+ });
679
+
680
+ it('should be valid if empty when min length is set', function() {
681
+ input('user.last').enter('');
682
+ expect(binding('user')).toEqual('{\n \"last\":\"",\n \"name\":\"guest\"}');
683
+ expect(binding('myForm.lastName.$valid')).toEqual('true');
684
+ expect(binding('myForm.$valid')).toEqual('true');
685
+ });
686
+
687
+ it('should be invalid if less than required min length', function() {
688
+ input('user.last').enter('xx');
689
+ expect(binding('user')).toEqual('{\n \"last\":\"xx",\n \"name\":\"guest\"}');
690
+ expect(binding('myForm.lastName.$valid')).toEqual('false');
691
+ expect(binding('myForm.lastName.$error')).toMatch(/MINLENGTH/);
692
+ expect(binding('myForm.$valid')).toEqual('false');
693
+ });
694
+
695
+ it('should be valid if longer than max length', function() {
696
+ input('user.last').enter('some ridiculously long name');
697
+ expect(binding('user'))
698
+ .toEqual('{\n \"last\":\"some ridiculously long name",\n \"name\":\"guest\"}');
699
+ expect(binding('myForm.lastName.$valid')).toEqual('false');
700
+ expect(binding('myForm.lastName.$error')).toMatch(/MAXLENGTH/);
701
+ expect(binding('myForm.$valid')).toEqual('false');
641
702
});
642
703
</doc:scenario>
643
704
</doc:example>
@@ -656,6 +717,8 @@ angularWidget('input', function(inputElement){
656
717
modelScope = this ,
657
718
patternMatch , widget ,
658
719
pattern = trim ( inputElement . attr ( 'ng:pattern' ) ) ,
720
+ minlength = parseInt ( inputElement . attr ( 'ng:minlength' ) , 10 ) ,
721
+ maxlength = parseInt ( inputElement . attr ( 'ng:maxlength' ) , 10 ) ,
659
722
loadFromScope = type . match ( / ^ \s * \@ \s * ( .* ) / ) ;
660
723
661
724
@@ -711,15 +774,24 @@ angularWidget('input', function(inputElement){
711
774
widget . $pristine = ! ( widget . $dirty = false ) ;
712
775
713
776
widget . $on ( '$validate' , function ( event ) {
714
- var $viewValue = trim ( widget . $viewValue ) ;
715
- var inValid = widget . $required && ! $viewValue ;
716
- var missMatch = $viewValue && ! patternMatch ( $viewValue ) ;
777
+ var $viewValue = trim ( widget . $viewValue ) ,
778
+ inValid = widget . $required && ! $viewValue ,
779
+ tooLong = maxlength && $viewValue && $viewValue . length > maxlength ,
780
+ tooShort = minlength && $viewValue && $viewValue . length < minlength ,
781
+ missMatch = $viewValue && ! patternMatch ( $viewValue ) ;
782
+
717
783
if ( widget . $error . REQUIRED != inValid ) {
718
784
widget . $emit ( inValid ? '$invalid' : '$valid' , 'REQUIRED' ) ;
719
785
}
720
786
if ( widget . $error . PATTERN != missMatch ) {
721
787
widget . $emit ( missMatch ? '$invalid' : '$valid' , 'PATTERN' ) ;
722
788
}
789
+ if ( widget . $error . MINLENGTH != tooShort ) {
790
+ widget . $emit ( tooShort ? '$invalid' : '$valid' , 'MINLENGTH' ) ;
791
+ }
792
+ if ( widget . $error . MAXLENGTH != tooLong ) {
793
+ widget . $emit ( tooLong ? '$invalid' : '$valid' , 'MAXLENGTH' ) ;
794
+ }
723
795
} ) ;
724
796
725
797
forEach ( [ 'valid' , 'invalid' , 'pristine' , 'dirty' ] , function ( name ) {
0 commit comments