@@ -36,7 +36,37 @@ describe('ui-select tests', function() {
36
36
37
37
} ) ;
38
38
39
- beforeEach ( module ( 'ngSanitize' , 'ui.select' , 'wrapperDirective' ) ) ;
39
+ /* Create a directive that can be applied to the ui-select instance to test
40
+ * the effects of Angular's validation process on the control.
41
+ *
42
+ * Does not currently work with single property binding. Looks at the
43
+ * selected object or objects for a "valid" property. If all selected objects
44
+ * have a "valid" property that is truthy, the validator passes.
45
+ */
46
+ angular . module ( 'testValidator' , [ ] ) ;
47
+ angular . module ( 'testValidator' ) . directive ( 'testValidator' , function ( ) {
48
+ return {
49
+ restrict : 'A' ,
50
+ require : 'ngModel' ,
51
+ link : function ( scope , element , attrs , ngModel ) {
52
+ ngModel . $validators . testValidator = function ( modelValue , viewValue ) {
53
+ if ( angular . isUndefined ( modelValue ) || modelValue === null ) {
54
+ return true ;
55
+ } else if ( angular . isArray ( modelValue ) ) {
56
+ var allValid = true , idx = modelValue . length ;
57
+ while ( idx -- > 0 && allValid ) {
58
+ allValid = allValid && modelValue [ idx ] . valid ;
59
+ }
60
+ return allValid ;
61
+ } else {
62
+ return ! ! modelValue . valid ;
63
+ }
64
+ } ;
65
+ }
66
+ }
67
+ } ) ;
68
+
69
+ beforeEach ( module ( 'ngSanitize' , 'ui.select' , 'wrapperDirective' , 'testValidator' ) ) ;
40
70
41
71
beforeEach ( function ( ) {
42
72
module ( function ( $provide ) {
@@ -1510,6 +1540,45 @@ describe('ui-select tests', function() {
1510
1540
1511
1541
} ) ;
1512
1542
1543
+ it ( 'should retain an invalid view value after refreshing items' , function ( ) {
1544
+ scope . taggingFunc = function ( name ) {
1545
+ return {
1546
+ name : name ,
1547
+ email : name + '@email.com' ,
1548
+ valid : name === "iamvalid"
1549
+ } ;
1550
+ } ;
1551
+
1552
+ var el = compileTemplate (
1553
+ '<ui-select ng-model="selection.selected" tagging="taggingFunc" tagging-label="false" test-validator> \
1554
+ <ui-select-match placeholder="Pick one...">{{$select.selected.email}}</ui-select-match> \
1555
+ <ui-select-choices repeat="person in people | filter: $select.search"> \
1556
+ <div ng-bind-html="person.name" | highlight: $select.search"></div> \
1557
+ <div ng-bind-html="person.email | highlight: $select.search"></div> \
1558
+ </ui-select-choices> \
1559
+ </ui-select>'
1560
+ ) ;
1561
+
1562
+ clickMatch ( el ) ;
1563
+ var searchInput = el . find ( '.ui-select-search' ) ;
1564
+
1565
+ setSearchText ( el , 'iamvalid' ) ;
1566
+ triggerKeydown ( searchInput , Key . Tab ) ;
1567
+
1568
+ //model value defined because it's valid, view value defined as expected
1569
+ var validTag = scope . taggingFunc ( "iamvalid" ) ;
1570
+ expect ( scope . selection . selected ) . toEqual ( validTag ) ;
1571
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( validTag ) ;
1572
+
1573
+ clickMatch ( el ) ;
1574
+ setSearchText ( el , 'notvalid' ) ;
1575
+ triggerKeydown ( searchInput , Key . Tab ) ;
1576
+
1577
+ //model value undefined because it's invalid, view value STILL defined as expected
1578
+ expect ( scope . selection . selected ) . toEqual ( undefined ) ;
1579
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( scope . taggingFunc ( "notvalid" ) ) ;
1580
+ } ) ;
1581
+
1513
1582
describe ( 'search-enabled option' , function ( ) {
1514
1583
1515
1584
var el ;
@@ -2171,6 +2240,45 @@ describe('ui-select tests', function() {
2171
2240
2172
2241
} ) ;
2173
2242
2243
+ it ( 'should retain an invalid view value after refreshing items' , function ( ) {
2244
+ scope . taggingFunc = function ( name ) {
2245
+ return {
2246
+ name : name ,
2247
+ email : name + '@email.com' ,
2248
+ valid : name === "iamvalid"
2249
+ } ;
2250
+ } ;
2251
+
2252
+ var el = compileTemplate (
2253
+ '<ui-select multiple ng-model="selection.selectedMultiple" tagging="taggingFunc" tagging-label="false" test-validator> \
2254
+ <ui-select-match placeholder="Pick one...">{{$select.selected.email}}</ui-select-match> \
2255
+ <ui-select-choices repeat="person in people | filter: $select.search"> \
2256
+ <div ng-bind-html="person.name" | highlight: $select.search"></div> \
2257
+ <div ng-bind-html="person.email | highlight: $select.search"></div> \
2258
+ </ui-select-choices> \
2259
+ </ui-select>'
2260
+ ) ;
2261
+
2262
+ clickMatch ( el ) ;
2263
+ var searchInput = el . find ( '.ui-select-search' ) ;
2264
+
2265
+ setSearchText ( el , 'iamvalid' ) ;
2266
+ triggerKeydown ( searchInput , Key . Tab ) ;
2267
+
2268
+ //model value defined because it's valid, view value defined as expected
2269
+ var validTag = scope . taggingFunc ( "iamvalid" ) ;
2270
+ expect ( scope . selection . selectedMultiple ) . toEqual ( [ jasmine . objectContaining ( validTag ) ] ) ;
2271
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( [ jasmine . objectContaining ( validTag ) ] ) ;
2272
+
2273
+ clickMatch ( el ) ;
2274
+ setSearchText ( el , 'notvalid' ) ;
2275
+ triggerKeydown ( searchInput , Key . Tab ) ;
2276
+
2277
+ //model value undefined because it's invalid, view value STILL defined as expected
2278
+ var invalidTag = scope . taggingFunc ( "notvalid" ) ;
2279
+ expect ( scope . selection . selected ) . toEqual ( undefined ) ;
2280
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( [ jasmine . objectContaining ( validTag ) , jasmine . objectContaining ( invalidTag ) ] ) ;
2281
+ } ) ;
2174
2282
2175
2283
it ( 'should run $formatters when changing model directly' , function ( ) {
2176
2284
0 commit comments