@@ -5,11 +5,28 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
55
66 controller : [ '$scope' , '$timeout' , function ( $scope , $timeout ) {
77
8- var ctrl = this ;
9- var $select = $scope . $select ;
8+ var ctrl = this ,
9+ $select = $scope . $select ,
10+ ngModel ;
11+
12+ //Wait for link fn to inject it
13+ $scope . $evalAsync ( function ( ) { ngModel = $scope . ngModel ; } ) ;
1014
1115 ctrl . activeMatchIndex = - 1 ;
1216
17+ ctrl . updateModel = function ( ) {
18+ ngModel . $setViewValue ( Date . now ( ) ) ; //Set timestamp as a unique string to force changes
19+ ctrl . refreshComponent ( ) ;
20+ } ;
21+
22+ ctrl . refreshComponent = function ( ) {
23+ //Remove already selected items
24+ //e.g. When user clicks on a selection, the selected array changes and
25+ //the dropdown should remove that item
26+ $select . refreshItems ( ) ;
27+ $select . sizeSearchInput ( ) ;
28+ } ;
29+
1330 // Remove item from multiple select
1431 ctrl . removeChoice = function ( index ) {
1532
@@ -33,6 +50,8 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
3350 } ) ;
3451 } ) ;
3552
53+ ctrl . updateModel ( ) ;
54+
3655 } ;
3756
3857 ctrl . getPlaceholder = function ( ) {
@@ -48,9 +67,11 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
4867 link : function ( scope , element , attrs , ctrls ) {
4968
5069 var $select = ctrls [ 0 ] ;
51- var ngModel = ctrls [ 1 ] ;
70+ var ngModel = scope . ngModel = ctrls [ 1 ] ;
5271 var $selectMultiple = scope . $selectMultiple ;
5372
73+ //$select.selected = raw selected objects (ignoring any property binding)
74+
5475 $select . multiple = true ;
5576 $select . removeSelected = true ;
5677
@@ -76,63 +97,49 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
7697 var data = $select . parserResult . source ( scope , { $select : { search :'' } } ) , //Overwrite $search
7798 locals = { } ,
7899 result ;
79- if ( data ) {
80- var resultMultiple = [ ] ;
81- var checkFnMultiple = function ( list , value ) {
82- //if the list is empty add the value to the list
83- if ( ! list || ! list . length ) {
84- resultMultiple . unshift ( value ) ;
85- return true ;
100+ if ( ! data ) return inputValue ;
101+ var resultMultiple = [ ] ;
102+ var checkFnMultiple = function ( list , value ) {
103+ if ( ! list || ! list . length ) return ;
104+ for ( var p = list . length - 1 ; p >= 0 ; p -- ) {
105+ locals [ $select . parserResult . itemName ] = list [ p ] ;
106+ result = $select . parserResult . modelMapper ( scope , locals ) ;
107+ if ( $select . parserResult . trackByExp ) {
108+ var matches = / \. ( .+ ) / . exec ( $select . parserResult . trackByExp ) ;
109+ if ( matches . length > 0 && result [ matches [ 1 ] ] == value [ matches [ 1 ] ] ) {
110+ resultMultiple . unshift ( list [ p ] ) ;
111+ return true ;
112+ }
86113 }
87- for ( var p = list . length - 1 ; p >= 0 ; p -- ) {
88- locals [ $select . parserResult . itemName ] = list [ p ] ;
89- result = $select . parserResult . modelMapper ( scope , locals ) ;
90- if ( $select . parserResult . trackByExp ) {
91- var matches = / \. ( .+ ) / . exec ( $select . parserResult . trackByExp ) ;
92- if ( matches . length > 0 && result [ matches [ 1 ] ] == value [ matches [ 1 ] ] ) {
93- resultMultiple . unshift ( list [ p ] ) ;
94- return true ;
95- }
96- }
97- if ( result == value ) {
98- resultMultiple . unshift ( list [ p ] ) ;
99- return true ;
100- }
114+ if ( angular . equals ( result , value ) ) {
115+ resultMultiple . unshift ( list [ p ] ) ;
116+ return true ;
101117 }
102- return false ;
103- } ;
104- if ( ! inputValue ) return resultMultiple ; //If ngModel was undefined
105- for ( var k = inputValue . length - 1 ; k >= 0 ; k -- ) {
106- if ( ! checkFnMultiple ( $select . selected , inputValue [ k ] ) ) {
107- checkFnMultiple ( data , inputValue [ k ] ) ;
118+ }
119+ return false ;
120+ } ;
121+ if ( ! inputValue ) return resultMultiple ; //If ngModel was undefined
122+ for ( var k = inputValue . length - 1 ; k >= 0 ; k -- ) {
123+ //Check model array of currently selected items
124+ if ( ! checkFnMultiple ( $select . selected , inputValue [ k ] ) ) {
125+ //Check model array of all items available
126+ if ( ! checkFnMultiple ( data , inputValue [ k ] ) ) {
127+ //If not found on previous lists, just add it directly to resultMultiple
128+ resultMultiple . unshift ( inputValue [ k ] ) ;
108129 }
109130 }
110- return resultMultiple ;
111131 }
112- return inputValue ;
132+ return resultMultiple ;
113133 } ) ;
114134
115- //Watch selection
135+ //Watch for external model changes
116136 scope . $watchCollection ( function ( ) { return ngModel . $modelValue ; } , function ( newValue , oldValue ) {
117- if ( oldValue != newValue )
137+ if ( oldValue != newValue ) {
118138 ngModel . $modelValue = null ; //Force scope model value and ngModel value to be out of sync to re-run formatters
119- } ) ;
120- //TODO Should be a better way to detect first pass
121- $select . firstPass = true ; // so the form doesn't get dirty as soon as it loads
122- scope . $watchCollection ( '$select.selected' , function ( ) {
123- if ( ! $select . firstPass ) {
124- ngModel . $setViewValue ( Date . now ( ) ) ; //Set timestamp as a unique string to force changes
125- } else {
126- $select . firstPass = false ;
139+ $selectMultiple . refreshComponent ( ) ;
127140 }
128- //Remove already selected items
129- //e.g. When user clicks on a selection, the selected array changes and
130- //the dropdown should remove that item
131- $select . refreshItems ( ) ;
132- //TODO Should add a test
133- $select . sizeSearchInput ( ) ;
134141 } ) ;
135-
142+
136143 ngModel . $render = function ( ) {
137144 // Make sure that model value is array
138145 if ( ! angular . isArray ( ngModel . $viewValue ) ) {
@@ -144,11 +151,12 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
144151 }
145152 }
146153 $select . selected = ngModel . $viewValue ;
154+ scope . $evalAsync ( ) ; //To force $digest
147155 } ;
148156
149157 scope . $on ( 'uis:select' , function ( event , item ) {
150158 $select . selected . push ( item ) ;
151- $select . sizeSearchInput ( ) ;
159+ $selectMultiple . updateModel ( ) ;
152160 } ) ;
153161
154162 scope . $on ( 'uis:activate' , function ( ) {
0 commit comments