Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 5f5ae45

Browse files
IgnigenaThomasBurleson
authored andcommitted
feat(chips): add support for custom separator keys
Add the ability for chips to be created on keydown of any key code in the `md-separator-keys` attribute. Custom key codes are supported in addition to common ones defined in `$mdConstant.KEY_CODE`. Closes #5279. Closes #5281.
1 parent b52f254 commit 5f5ae45

File tree

6 files changed

+106
-16
lines changed

6 files changed

+106
-16
lines changed

src/components/chips/chips.spec.js

100644100755
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ describe('<md-chips>', function() {
344344

345345
expect(enterEvent.preventDefault).toHaveBeenCalled();
346346
}));
347+
347348
});
348349

349350
it('focuses/blurs the component when focusing/blurring the input', inject(function() {
@@ -364,6 +365,50 @@ describe('<md-chips>', function() {
364365
});
365366

366367
describe('custom inputs', function() {
368+
369+
describe('separator-keys', function() {
370+
var SEPARATOR_KEYS_CHIP_TEMPLATE =
371+
'<md-chips ng-model="items" md-separator-keys="keys"></md-chips>';
372+
373+
it('should create a new chip when a comma is entered', inject(function($mdConstant) {
374+
scope.keys = [$mdConstant.KEY_CODE.ENTER, $mdConstant.KEY_CODE.COMMA];
375+
var element = buildChips(SEPARATOR_KEYS_CHIP_TEMPLATE);
376+
var ctrl = element.controller('mdChips');
377+
378+
var commaInput = {
379+
type: 'keydown',
380+
keyCode: $mdConstant.KEY_CODE.COMMA,
381+
which: $mdConstant.KEY_CODE.COMMA,
382+
preventDefault: jasmine.createSpy('preventDefault')
383+
};
384+
385+
ctrl.chipBuffer = 'Test';
386+
element.find('input').triggerHandler(commaInput);
387+
388+
expect(commaInput.preventDefault).toHaveBeenCalled();
389+
}));
390+
391+
it('supports custom separator key codes', inject(function($mdConstant) {
392+
var semicolon = 186;
393+
scope.keys = [$mdConstant.KEY_CODE.ENTER, $mdConstant.KEY_CODE.COMMA, semicolon];
394+
395+
var element = buildChips(SEPARATOR_KEYS_CHIP_TEMPLATE);
396+
var ctrl = element.controller('mdChips');
397+
398+
var semicolonInput = {
399+
type: 'keydown',
400+
keyCode: semicolon,
401+
which: semicolon,
402+
preventDefault: jasmine.createSpy('preventDefault')
403+
};
404+
405+
ctrl.chipBuffer = 'Test';
406+
element.find('input').triggerHandler(semicolonInput);
407+
408+
expect(semicolonInput.preventDefault).toHaveBeenCalled();
409+
}));
410+
});
411+
367412
describe('md-autocomplete', function() {
368413
var AUTOCOMPLETE_CHIPS_TEMPLATE = '\
369414
<md-chips ng-model="items">\
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<div ng-controller="CustomSeparatorCtrl as ctrl" layout="column" ng-cloak>
2+
<md-content class="md-padding" layout="column">
3+
4+
<h2 class="md-title">Use <code>md-separator-keys</code> to customize the key codes which trigger chip creation.</h2>
5+
<p>Common key codes found in <code>$mdConstant.KEY_CODE</code> can be used alongside your own.</p>
6+
<md-chips
7+
ng-model="ctrl.tags"
8+
md-separator-keys="ctrl.keys"
9+
placeholder="Enter a tag"
10+
secondary-placeholder="Comma separated tags"></md-chips>
11+
<br/>
12+
13+
<h2 class="md-title">Add custom separator key codes such as semicolon for e-mails.</h2>
14+
<md-chips
15+
ng-model="ctrl.contacts"
16+
md-separator-keys="ctrl.customKeys"></md-chips>
17+
18+
</md-content>
19+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
(function () {
2+
'use strict';
3+
angular
4+
.module('chipsCustomSeparatorDemo', ['ngMaterial'])
5+
.controller('CustomSeparatorCtrl', DemoCtrl);
6+
7+
function DemoCtrl ($mdConstant) {
8+
// Use common key codes found in $mdConstant.KEY_CODE...
9+
this.keys = [$mdConstant.KEY_CODE.ENTER, $mdConstant.KEY_CODE.COMMA];
10+
this.tags = [];
11+
12+
// Any key code can be used to create a custom separator
13+
var semicolon = 186;
14+
this.customKeys = [$mdConstant.KEY_CODE.ENTER, $mdConstant.KEY_CODE.COMMA, semicolon];
15+
this.contacts = ['test@example.com'];
16+
}
17+
})();

src/components/chips/js/chipsController.js

100644100755
Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) {
107107
}
108108

109109
/**
110-
* Handles the keydown event on the input element: <enter> appends the
111-
* buffer to the chip list, while backspace removes the last chip in the list
112-
* if the current buffer is empty.
110+
* Handles the keydown event on the input element: by default <enter> appends
111+
* the buffer to the chip list, while backspace removes the last chip in the
112+
* list if the current buffer is empty.
113113
* @param event
114114
*/
115115
MdChipsCtrl.prototype.inputKeydown = function(event) {
@@ -120,19 +120,25 @@ MdChipsCtrl.prototype.inputKeydown = function(event) {
120120
return;
121121
}
122122

123-
switch (event.keyCode) {
124-
case this.$mdConstant.KEY_CODE.ENTER:
125-
if ((this.hasAutocomplete && this.requireMatch) || !chipBuffer) break;
126-
event.preventDefault();
127-
this.appendChip(chipBuffer);
128-
this.resetChipBuffer();
129-
break;
130-
case this.$mdConstant.KEY_CODE.BACKSPACE:
131-
if (chipBuffer) break;
132-
event.preventDefault();
133-
event.stopPropagation();
134-
if (this.items.length) this.selectAndFocusChipSafe(this.items.length - 1);
135-
break;
123+
if (event.keyCode === this.$mdConstant.KEY_CODE.BACKSPACE) {
124+
if (chipBuffer) return;
125+
event.preventDefault();
126+
event.stopPropagation();
127+
if (this.items.length) this.selectAndFocusChipSafe(this.items.length - 1);
128+
return;
129+
}
130+
131+
// By default <enter> appends the buffer to the chip list.
132+
if (!this.separatorKeys || this.separatorKeys.length < 1) {
133+
this.separatorKeys = [this.$mdConstant.KEY_CODE.ENTER];
134+
}
135+
136+
// Support additional separator key codes in an array of `md-separator-keys`.
137+
if (this.separatorKeys.indexOf(event.keyCode) !== -1) {
138+
if ((this.hasAutocomplete && this.requireMatch) || !chipBuffer) return;
139+
event.preventDefault();
140+
this.appendChip(chipBuffer);
141+
this.resetChipBuffer();
136142
}
137143
};
138144

src/components/chips/js/chipsDirective.js

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
* the delete key will remove the chip.
8484
* @param {string=} delete-button-label A label for the delete button. Also hidden and read by
8585
* screen readers.
86+
* @param {expression=} md-separator-keys An array of key codes used to separate chips.
8687
*
8788
* @usage
8889
* <hljs lang="html">
@@ -181,6 +182,7 @@
181182
onSelect: '&mdOnSelect',
182183
deleteHint: '@',
183184
deleteButtonLabel: '@',
185+
separatorKeys: '=?mdSeparatorKeys',
184186
requireMatch: '=?mdRequireMatch'
185187
}
186188
};

src/core/util/constant.js

100644100755
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function MdConstantFactory($sniffer) {
1414

1515
return {
1616
KEY_CODE: {
17+
COMMA: 188,
1718
ENTER: 13,
1819
ESCAPE: 27,
1920
SPACE: 32,

0 commit comments

Comments
 (0)