diff --git a/src/components/chips/chips.spec.js b/src/components/chips/chips.spec.js index 0d28a884197..9d28fe304be 100644 --- a/src/components/chips/chips.spec.js +++ b/src/components/chips/chips.spec.js @@ -6,6 +6,8 @@ describe('', function() { ''; var CHIP_REMOVE_TEMPLATE = ''; + var CHIP_SELECT_TEMPLATE = + ''; var CHIP_READONLY_AUTOCOMPLETE_TEMPLATE = '' + ' ' + @@ -134,6 +136,21 @@ describe('', function() { }); + it('should call the select method when selecting a chip', function() { + var element = buildChips(CHIP_SELECT_TEMPLATE); + var ctrl = element.controller('mdChips'); + + scope.selectChip = jasmine.createSpy('selectChip'); + + element.scope().$apply(function() { + ctrl.items = ['Grape']; + ctrl.selectChip(0); + }); + + expect(scope.selectChip).toHaveBeenCalled(); + expect(scope.selectChip.calls.mostRecent().args[0]).toBe('Grape'); + }); + it('should handle appending an object chip', function() { var element = buildChips(CHIP_APPEND_TEMPLATE); var ctrl = element.controller('mdChips'); @@ -394,9 +411,9 @@ describe('', function() { }); }); -// ******************************* -// Internal helper methods -// ******************************* + // ******************************* + // Internal helper methods + // ******************************* function buildChips(str) { var container; diff --git a/src/components/chips/js/chipsController.js b/src/components/chips/js/chipsController.js index e5eb67646f7..7f76c8043df 100644 --- a/src/components/chips/js/chipsController.js +++ b/src/components/chips/js/chipsController.js @@ -67,11 +67,18 @@ function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) { this.chipBuffer = ''; /** - * Whether to use the mdOnAppend expression to transform the chip buffer + * Whether to use the onAppend expression to transform the chip buffer * before appending it to the list. * @type {boolean} */ - this.useMdOnAppend = false; + this.useOnAppend = false; + + /** + * Whether to use the onSelect expression to notify the component's user + * after selecting a chip from the list. + * @type {boolean} + */ + this.useOnSelect = false; } /** @@ -181,8 +188,8 @@ MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { * @param newChip */ MdChipsCtrl.prototype.appendChip = function(newChip) { - if (this.useMdOnAppend && this.mdOnAppend) { - newChip = this.mdOnAppend({'$chip': newChip}); + if (this.useOnAppend && this.onAppend) { + newChip = this.onAppend({'$chip': newChip}); } if (this.items.indexOf(newChip) + 1) return; this.items.push(newChip); @@ -191,23 +198,34 @@ MdChipsCtrl.prototype.appendChip = function(newChip) { /** * Sets whether to use the md-on-append expression. This expression is * bound to scope and controller in {@code MdChipsDirective} as - * {@code mdOnAppend}. Due to the nature of directive scope bindings, the + * {@code onAppend}. Due to the nature of directive scope bindings, the * controller cannot know on its own/from the scope whether an expression was * actually provided. */ -MdChipsCtrl.prototype.useMdOnAppendExpression = function() { - this.useMdOnAppend = true; +MdChipsCtrl.prototype.useOnAppendExpression = function() { + this.useOnAppend = true; }; /** * Sets whether to use the md-on-remove expression. This expression is * bound to scope and controller in {@code MdChipsDirective} as - * {@code mdOnRemove}. Due to the nature of directive scope bindings, the + * {@code onRemove}. Due to the nature of directive scope bindings, the + * controller cannot know on its own/from the scope whether an expression was + * actually provided. + */ +MdChipsCtrl.prototype.useOnRemoveExpression = function() { + this.useOnRemove = true; +}; + +/* + * Sets whether to use the md-on-select expression. This expression is + * bound to scope and controller in {@code MdChipsDirective} as + * {@code onSelect}. Due to the nature of directive scope bindings, the * controller cannot know on its own/from the scope whether an expression was * actually provided. */ -MdChipsCtrl.prototype.useMdOnRemoveExpression = function() { - this.useMdOnRemove = true; +MdChipsCtrl.prototype.useOnSelectExpression = function() { + this.useOnSelect = true; }; /** @@ -247,8 +265,8 @@ MdChipsCtrl.prototype.resetChipBuffer = function() { MdChipsCtrl.prototype.removeChip = function(index) { var removed = this.items.splice(index, 1); - if (removed && removed.length && this.useMdOnRemove && this.mdOnRemove) { - this.mdOnRemove({ '$chip': removed[0], '$index': index }); + if (removed && removed.length && this.useOnRemove && this.onRemove) { + this.onRemove({ '$chip': removed[0], '$index': index }); } }; @@ -280,6 +298,11 @@ MdChipsCtrl.prototype.selectAndFocusChipSafe = function(index) { MdChipsCtrl.prototype.selectChip = function(index) { if (index >= -1 && index <= this.items.length) { this.selectedChip = index; + + // Fire the onSelect if provided + if (this.useOnSelect && this.onSelect) { + this.onSelect({'$chip': this.items[this.selectedChip] }); + } } else { this.$log.warn('Selected Chip index out of bounds; ignoring.'); } diff --git a/src/components/chips/js/chipsDirective.js b/src/components/chips/js/chipsDirective.js index 042fc444b40..ac15fe91299 100644 --- a/src/components/chips/js/chipsDirective.js +++ b/src/components/chips/js/chipsDirective.js @@ -68,6 +68,7 @@ * object when adding a chip. * @param {expression} md-on-remove An expression which will be called when a chip has been * removed. + * @param {expression} md-on-select An expression which will be called when a chip is selected. * @param {string=} delete-hint A string read by screen readers instructing users that pressing * the delete key will remove the chip. * @param {string=} delete-button-label A label for the delete button. Also hidden and read by @@ -162,8 +163,9 @@ readonly: '=readonly', placeholder: '@', secondaryPlaceholder: '@', - mdOnAppend: '&', - mdOnRemove: '&', + onAppend: '&mdOnAppend', + onRemove: '&mdOnRemove', + onSelect: '&mdOnSelect', deleteHint: '@', deleteButtonLabel: '@', requireMatch: '=?mdRequireMatch' @@ -245,11 +247,15 @@ // If an `md-on-append` attribute was set, tell the controller to use the expression // when appending chips. - if (attrs.mdOnAppend) mdChipsCtrl.useMdOnAppendExpression(); + if (attrs.mdOnAppend) mdChipsCtrl.useOnAppendExpression(); // If an `md-on-remove` attribute was set, tell the controller to use the expression // when removing chips. - if (attrs.mdOnRemove) mdChipsCtrl.useMdOnRemoveExpression(); + if (attrs.mdOnRemove) mdChipsCtrl.useOnRemoveExpression(); + + // If an `md-on-select` attribute was set, tell the controller to use the expression + // when selecting chips. + if (attrs.mdOnSelect) mdChipsCtrl.useOnSelectExpression(); // The md-autocomplete and input elements won't be compiled until after this directive // is complete (due to their nested nature). Wait a tick before looking for them to