@@ -16,27 +16,60 @@ angular.module('angular-advanced-searchbox', [])
16
16
restrict : 'E' ,
17
17
scope : {
18
18
model : '=ngModel' ,
19
- parameters : '='
19
+ parameters : '=' ,
20
+ placeholder : '@'
20
21
} ,
21
22
replace : true ,
22
23
templateUrl : 'angular-advanced-searchbox.html' ,
23
24
controller : [
24
25
'$scope' , '$attrs' , '$element' , '$timeout' , '$filter' ,
25
26
function ( $scope , $attrs , $element , $timeout , $filter ) {
26
27
27
- $scope . placeholder = $attrs . placeholder || 'Search ...' ;
28
+ $scope . placeholder = $scope . placeholder || 'Search ...' ;
28
29
$scope . searchParams = [ ] ;
29
30
$scope . searchQuery = '' ;
30
31
$scope . setSearchFocus = false ;
32
+ var searchThrottleTimer ;
33
+ var changeBuffer = [ ] ;
31
34
32
- $scope . $watch ( 'searchQuery' , function ( ) {
33
- updateModel ( ) ;
34
- } ) ;
35
+ $scope . $watch ( 'model' , function ( newValue , oldValue ) {
36
+
37
+ if ( angular . equals ( newValue , oldValue ) )
38
+ return ;
35
39
36
- $scope . $watch ( 'searchParams' , function ( ) {
37
- updateModel ( ) ;
40
+ angular . forEach ( $scope . model , function ( value , key ) {
41
+ if ( key === 'query' && $scope . searchQuery !== value ) {
42
+ $scope . searchQuery = value ;
43
+ } else {
44
+ var paramTemplate = $filter ( 'filter' ) ( $scope . parameters , function ( param ) { return param . key === key ; } ) [ 0 ] ;
45
+ var searchParam = $filter ( 'filter' ) ( $scope . searchParams , function ( param ) { return param . key === key ; } ) [ 0 ] ;
46
+
47
+ if ( paramTemplate !== undefined ) {
48
+ if ( searchParam === undefined )
49
+ $scope . addSearchParam ( paramTemplate , value , false ) ;
50
+ else if ( searchParam . value !== value )
51
+ searchParam . value = value ;
52
+ }
53
+ }
54
+ } ) ;
55
+
56
+ // delete not existing search parameters from internal state array
57
+ angular . forEach ( $scope . searchParams , function ( value , key ) {
58
+ if ( ! $scope . model . hasOwnProperty ( value . key ) ) {
59
+ var index = $scope . searchParams . map ( function ( e ) { return e . key ; } ) . indexOf ( value . key ) ;
60
+ $scope . removeSearchParam ( index ) ;
61
+ }
62
+ } ) ;
38
63
} , true ) ;
39
64
65
+ $scope . searchParamValueChanged = function ( param ) {
66
+ updateModel ( 'change' , param . key , param . value ) ;
67
+ } ;
68
+
69
+ $scope . searchQueryChanged = function ( query ) {
70
+ updateModel ( 'change' , 'query' , query ) ;
71
+ } ;
72
+
40
73
$scope . enterEditMode = function ( index ) {
41
74
if ( index === undefined )
42
75
return ;
@@ -60,12 +93,20 @@ angular.module('angular-advanced-searchbox', [])
60
93
$scope . typeaheadOnSelect = function ( item , model , label ) {
61
94
$scope . addSearchParam ( item ) ;
62
95
$scope . searchQuery = '' ;
96
+ updateModel ( 'delete' , 'query' ) ;
97
+ } ;
98
+
99
+ $scope . isUnsedParameter = function ( value , index ) {
100
+ return $filter ( 'filter' ) ( $scope . searchParams , function ( param ) { return param . key === value . key ; } ) . length === 0 ;
63
101
} ;
64
102
65
103
$scope . addSearchParam = function ( searchParam , value , enterEditModel ) {
66
104
if ( enterEditModel === undefined )
67
105
enterEditModel = true ;
68
106
107
+ if ( ! $scope . isUnsedParameter ( searchParam ) )
108
+ return ;
109
+
69
110
$scope . searchParams . push (
70
111
{
71
112
key : searchParam . key ,
@@ -76,23 +117,24 @@ angular.module('angular-advanced-searchbox', [])
76
117
}
77
118
) ;
78
119
79
- //TODO: hide used suggestion
120
+ updateModel ( 'add' , searchParam . key , value ) ;
80
121
} ;
81
122
82
123
$scope . removeSearchParam = function ( index ) {
83
124
if ( index === undefined )
84
125
return ;
85
126
127
+ var searchParam = $scope . searchParams [ index ] ;
86
128
$scope . searchParams . splice ( index , 1 ) ;
87
129
88
- //TODO: show hidden/removed suggestion
130
+ updateModel ( 'delete' , searchParam . key ) ;
89
131
} ;
90
132
91
133
$scope . removeAll = function ( ) {
92
134
$scope . searchParams . length = 0 ;
93
135
$scope . searchQuery = '' ;
94
136
95
- //TODO: show hidden/removed suggestion
137
+ $scope . model = { } ;
96
138
} ;
97
139
98
140
$scope . editPrevious = function ( currentIndex ) {
@@ -172,21 +214,28 @@ angular.module('angular-advanced-searchbox', [])
172
214
restoreModel ( ) ;
173
215
}
174
216
175
- var searchThrottleTimer ;
176
- function updateModel ( ) {
217
+ function updateModel ( command , key , value ) {
177
218
if ( searchThrottleTimer )
178
219
$timeout . cancel ( searchThrottleTimer ) ;
179
220
180
- searchThrottleTimer = $timeout ( function ( ) {
181
- $scope . model = { } ;
182
-
183
- if ( $scope . searchQuery . length > 0 )
184
- $scope . model . query = $scope . searchQuery ;
221
+ // remove all previous entries to the same search key that was not handled yet
222
+ changeBuffer = $filter ( 'filter' ) ( changeBuffer , function ( change ) { return change . key !== key ; } ) ;
223
+ // add new change to list
224
+ changeBuffer . push ( {
225
+ command : command ,
226
+ key : key ,
227
+ value : value
228
+ } ) ;
185
229
186
- angular . forEach ( $scope . searchParams , function ( param ) {
187
- if ( param . value !== undefined && param . value . length > 0 )
188
- $scope . model [ param . key ] = param . value ;
230
+ searchThrottleTimer = $timeout ( function ( ) {
231
+ angular . forEach ( changeBuffer , function ( change ) {
232
+ if ( change . command === 'delete' )
233
+ delete $scope . model [ change . key ] ;
234
+ else
235
+ $scope . model [ change . key ] = change . value ;
189
236
} ) ;
237
+
238
+ changeBuffer . length = 0 ;
190
239
} , 500 ) ;
191
240
}
192
241
@@ -275,11 +324,12 @@ angular.module('angular-advanced-searchbox', [])
275
324
}
276
325
] ) ;
277
326
} ) ( ) ;
327
+
278
328
angular . module ( 'angular-advanced-searchbox' ) . run ( [ '$templateCache' , function ( $templateCache ) {
279
329
'use strict' ;
280
330
281
331
$templateCache . put ( 'angular-advanced-searchbox.html' ,
282
- "<div class=advancedSearchBox ng-class={active:focus} ng-init=\"focus = false\"><span ng-show=\"searchParams.length < 1 && searchQuery.length === 0\" class=\"search-icon glyphicon glyphicon-search\"></span> <a ng-href=\"\" ng-show=\"searchParams.length > 0 || searchQuery.length > 0\" ng-click=removeAll() role=button><span class=\"remove-all-icon glyphicon glyphicon-trash\"></span></a><div><div class=search-parameter ng-repeat=\"searchParam in searchParams\"><a ng-href=\"\" ng-click=removeSearchParam($index) role=button><span class=\"remove glyphicon glyphicon-trash\"></span></a><div class=key>{{searchParam.name}}:</div><div class=value><span ng-show=!searchParam.editMode ng-click=enterEditMode($index)>{{searchParam.value}}</span> <input name=value nit-auto-size-input nit-set-focus=searchParam.editMode ng-keydown=\"keydown($event, $index)\" ng-blur=leaveEditMode($index) ng-show=searchParam.editMode ng-model=searchParam.value placeholder=\"{{searchParam.placeholder}}\"></div></div><input name=searchbox class=search-parameter-input nit-set-focus=setSearchFocus ng-keydown=keydown($event) placeholder={{placeholder}} ng-focus=\"focus = true\" ng-blur=\"focus = false\" typeahead-on-select=\"typeaheadOnSelect($item, $model, $label)\" typeahead=\"parameter as parameter.name for parameter in parameters | filter:{name:$viewValue} | limitTo:8\" ng-model=\"searchQuery\"></div><div class=search-parameter-suggestions ng-show=\"parameters && focus\"><span class=title>Parameter Suggestions:</span> <span class=search-parameter ng-repeat=\"param in parameters | limitTo:8\" ng-mousedown=addSearchParam(param)>{{param.name}}</span></div></div>"
332
+ "<div class=advancedSearchBox ng-class={active:focus} ng-init=\"focus = false\" ng-click=\"!focus ? setSearchFocus = true : null\"><span ng-show=\"searchParams.length < 1 && searchQuery.length === 0\" class=\"search-icon glyphicon glyphicon-search\"></span> <a ng-href=\"\" ng-show=\"searchParams.length > 0 || searchQuery.length > 0\" ng-click=removeAll() role=button><span class=\"remove-all-icon glyphicon glyphicon-trash\"></span></a><div><div class=search-parameter ng-repeat=\"searchParam in searchParams\"><a ng-href=\"\" ng-click=removeSearchParam($index) role=button><span class=\"remove glyphicon glyphicon-trash\"></span></a><div class=key>{{searchParam.name}}:</div><div class=value><span ng-if=!searchParam.editMode ng-click=enterEditMode($index)>{{searchParam.value}}</span> <input name=value nit-auto-size-input nit-set-focus=searchParam.editMode ng-keydown=\"keydown($event, $index)\" ng-blur=leaveEditMode($index) ng-if=searchParam.editMode ng-change=searchParamValueChanged(searchParam) ng-model=searchParam.value placeholder=\"{{searchParam.placeholder}}\"></div></div><input name=searchbox class=search-parameter-input nit-auto-size-input nit-set-focus=setSearchFocus ng-keydown=keydown($event) placeholder={{placeholder}} ng-focus=\"focus = true\" ng-blur=\"focus = false\" typeahead-on-select=\"typeaheadOnSelect($item, $model, $label)\" typeahead=\"parameter as parameter.name for parameter in parameters | filter:isUnsedParameter | filter:{name:$viewValue} | limitTo:8\" ng-change=searchQueryChanged(searchQuery) ng-model=\"searchQuery\"></div><div class=search-parameter-suggestions ng-show=\"parameters && focus\"><span class=title>Parameter Suggestions:</span> <span class=search-parameter ng-repeat=\"param in parameters | filter:isUnsedParameter | limitTo:8\" ng-mousedown=addSearchParam(param)>{{param.name}}</span></div></div>"
283
333
) ;
284
334
285
335
} ] ) ;
0 commit comments