@@ -11,9 +11,10 @@ angular
11
11
* @param $mdConstant
12
12
* @param $log
13
13
* @param $element
14
+ * @param $mdUtil
14
15
* @constructor
15
16
*/
16
- function MdChipsCtrl ( $scope , $mdConstant , $log , $element , $timeout ) {
17
+ function MdChipsCtrl ( $scope , $mdConstant , $log , $element , $timeout , $mdUtil ) {
17
18
/** @type {$timeout } **/
18
19
this . $timeout = $timeout ;
19
20
@@ -50,6 +51,8 @@ function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) {
50
51
/** @type {boolean } */
51
52
this . hasAutocomplete = false ;
52
53
54
+ /** @type {string } */
55
+ this . enableChipEdit = $mdUtil . parseAttributeBoolean ( this . mdEnableChipEdit ) ;
53
56
54
57
/**
55
58
* Hidden hint text for how to delete a chip. Used to give context to screen readers.
@@ -137,18 +140,47 @@ MdChipsCtrl.prototype.inputKeydown = function(event) {
137
140
if ( this . separatorKeys . indexOf ( event . keyCode ) !== - 1 ) {
138
141
if ( ( this . hasAutocomplete && this . requireMatch ) || ! chipBuffer ) return ;
139
142
event . preventDefault ( ) ;
140
- this . appendChip ( chipBuffer ) ;
143
+
144
+ // Only append the chip and reset the chip buffer if the max chips limit isn't reached.
145
+ if ( this . hasMaxChipsReached ( ) ) return ;
146
+
147
+ this . appendChip ( chipBuffer . trim ( ) ) ;
141
148
this . resetChipBuffer ( ) ;
142
149
}
143
150
} ;
144
151
152
+
153
+ /**
154
+ * Updates the content of the chip at given index
155
+ * @param chipIndex
156
+ * @param chipContents
157
+ */
158
+ MdChipsCtrl . prototype . updateChipContents = function ( chipIndex , chipContents ) {
159
+ if ( chipIndex >= 0 && chipIndex < this . items . length ) {
160
+ this . items [ chipIndex ] = chipContents ;
161
+ this . ngModelCtrl . $setDirty ( ) ;
162
+ }
163
+ } ;
164
+
165
+
166
+ /**
167
+ * Returns true if a chip is currently being edited. False otherwise.
168
+ * @return {boolean }
169
+ */
170
+ MdChipsCtrl . prototype . isEditingChip = function ( ) {
171
+ return ! ! this . $element [ 0 ] . getElementsByClassName ( '_md-chip-editing' ) . length ;
172
+ } ;
173
+
174
+
145
175
/**
146
176
* Handles the keydown event on the chip elements: backspace removes the selected chip, arrow
147
177
* keys switch which chips is active
148
178
* @param event
149
179
*/
150
180
MdChipsCtrl . prototype . chipKeydown = function ( event ) {
151
181
if ( this . getChipBuffer ( ) ) return ;
182
+ if ( this . isEditingChip ( ) ) return ;
183
+
152
184
switch ( event . keyCode ) {
153
185
case this . $mdConstant . KEY_CODE . BACKSPACE :
154
186
case this . $mdConstant . KEY_CODE . DELETE :
@@ -242,7 +274,7 @@ MdChipsCtrl.prototype.appendChip = function(newChip) {
242
274
var identical = this . items . some ( function ( item ) {
243
275
return angular . equals ( newChip , item ) ;
244
276
} ) ;
245
- if ( identical ) return ;
277
+ if ( identical ) return ;
246
278
}
247
279
248
280
// Check for a null (but not undefined), or existing chip and cancel appending
@@ -251,6 +283,10 @@ MdChipsCtrl.prototype.appendChip = function(newChip) {
251
283
// Append the new chip onto our list
252
284
var index = this . items . push ( newChip ) ;
253
285
286
+ // Update model validation
287
+ this . ngModelCtrl . $setDirty ( ) ;
288
+ this . validateModel ( ) ;
289
+
254
290
// If they provide the md-on-add attribute, notify them of the chip addition
255
291
if ( this . useOnAdd && this . onAdd ) {
256
292
this . onAdd ( { '$chip' : newChip , '$index' : index } ) ;
@@ -350,13 +386,30 @@ MdChipsCtrl.prototype.resetChipBuffer = function() {
350
386
}
351
387
} ;
352
388
389
+ MdChipsCtrl . prototype . hasMaxChipsReached = function ( ) {
390
+ if ( angular . isString ( this . maxChips ) ) this . maxChips = parseInt ( this . maxChips , 10 ) || 0 ;
391
+
392
+ return this . maxChips > 0 && this . items . length >= this . maxChips ;
393
+ } ;
394
+
395
+ /**
396
+ * Updates the validity properties for the ngModel.
397
+ */
398
+ MdChipsCtrl . prototype . validateModel = function ( ) {
399
+ this . ngModelCtrl . $setValidity ( 'md-max-chips' , ! this . hasMaxChipsReached ( ) ) ;
400
+ } ;
401
+
353
402
/**
354
403
* Removes the chip at the given index.
355
404
* @param index
356
405
*/
357
406
MdChipsCtrl . prototype . removeChip = function ( index ) {
358
407
var removed = this . items . splice ( index , 1 ) ;
359
408
409
+ // Update model validation
410
+ this . ngModelCtrl . $setDirty ( ) ;
411
+ this . validateModel ( ) ;
412
+
360
413
if ( removed && removed . length && this . useOnRemove && this . onRemove ) {
361
414
this . onRemove ( { '$chip' : removed [ 0 ] , '$index' : index } ) ;
362
415
}
@@ -415,7 +468,7 @@ MdChipsCtrl.prototype.selectAndFocusChip = function(index) {
415
468
* Call `focus()` on the chip at `index`
416
469
*/
417
470
MdChipsCtrl . prototype . focusChip = function ( index ) {
418
- this . $element [ 0 ] . querySelector ( 'md-chip[index="' + index + '"] .md -chip-content' ) . focus ( ) ;
471
+ this . $element [ 0 ] . querySelector ( 'md-chip[index="' + index + '"] ._md -chip-content' ) . focus ( ) ;
419
472
} ;
420
473
421
474
/**
@@ -479,10 +532,14 @@ MdChipsCtrl.prototype.configureUserInput = function(inputElement) {
479
532
} ;
480
533
481
534
MdChipsCtrl . prototype . configureAutocomplete = function ( ctrl ) {
482
- if ( ctrl ) {
535
+ if ( ctrl ) {
483
536
this . hasAutocomplete = true ;
537
+
484
538
ctrl . registerSelectedItemWatcher ( angular . bind ( this , function ( item ) {
485
539
if ( item ) {
540
+ // Only append the chip and reset the chip buffer if the max chips limit isn't reached.
541
+ if ( this . hasMaxChipsReached ( ) ) return ;
542
+
486
543
this . appendChip ( item ) ;
487
544
this . resetChipBuffer ( ) ;
488
545
}
0 commit comments