@@ -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 ;
@@ -2159,6 +2228,45 @@ describe('ui-select tests', function() {
2159
2228
2160
2229
} ) ;
2161
2230
2231
+ it ( 'should retain an invalid view value after refreshing items' , function ( ) {
2232
+ scope . taggingFunc = function ( name ) {
2233
+ return {
2234
+ name : name ,
2235
+ email : name + '@email.com' ,
2236
+ valid : name === "iamvalid"
2237
+ } ;
2238
+ } ;
2239
+
2240
+ var el = compileTemplate (
2241
+ '<ui-select multiple ng-model="selection.selectedMultiple" tagging="taggingFunc" tagging-label="false" test-validator> \
2242
+ <ui-select-match placeholder="Pick one...">{{$select.selected.email}}</ui-select-match> \
2243
+ <ui-select-choices repeat="person in people | filter: $select.search"> \
2244
+ <div ng-bind-html="person.name" | highlight: $select.search"></div> \
2245
+ <div ng-bind-html="person.email | highlight: $select.search"></div> \
2246
+ </ui-select-choices> \
2247
+ </ui-select>'
2248
+ ) ;
2249
+
2250
+ clickMatch ( el ) ;
2251
+ var searchInput = el . find ( '.ui-select-search' ) ;
2252
+
2253
+ setSearchText ( el , 'iamvalid' ) ;
2254
+ triggerKeydown ( searchInput , Key . Tab ) ;
2255
+
2256
+ //model value defined because it's valid, view value defined as expected
2257
+ var validTag = scope . taggingFunc ( "iamvalid" ) ;
2258
+ expect ( scope . selection . selectedMultiple ) . toEqual ( [ jasmine . objectContaining ( validTag ) ] ) ;
2259
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( [ jasmine . objectContaining ( validTag ) ] ) ;
2260
+
2261
+ clickMatch ( el ) ;
2262
+ setSearchText ( el , 'notvalid' ) ;
2263
+ triggerKeydown ( searchInput , Key . Tab ) ;
2264
+
2265
+ //model value undefined because it's invalid, view value STILL defined as expected
2266
+ var invalidTag = scope . taggingFunc ( "notvalid" ) ;
2267
+ expect ( scope . selection . selected ) . toEqual ( undefined ) ;
2268
+ expect ( $ ( el ) . scope ( ) . $select . selected ) . toEqual ( [ jasmine . objectContaining ( validTag ) , jasmine . objectContaining ( invalidTag ) ] ) ;
2269
+ } ) ;
2162
2270
2163
2271
it ( 'should run $formatters when changing model directly' , function ( ) {
2164
2272
0 commit comments