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

feat(chips): Add md-on-remove attribute. #4098

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/components/chips/chips.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ describe('<md-chips>', function() {
'<md-chips ng-model="items"></md-chips>';
var CHIP_APPEND_TEMPLATE =
'<md-chips ng-model="items" md-on-append="appendChip($chip)"></md-chips>';
var CHIP_REMOVE_TEMPLATE =
'<md-chips ng-model="items" md-on-remove="removeChip($chip, $index)"></md-chips>';

describe('with no overrides', function() {

Expand Down Expand Up @@ -111,6 +113,23 @@ describe('<md-chips>', function() {
expect(scope.items[3]).toBe('GrapeGrape');
});

it('should call the remove method when removing a chip', function() {
var element = buildChips(CHIP_REMOVE_TEMPLATE);
var ctrl = element.controller('mdChips');

scope.removeChip = jasmine.createSpy('removeChip');

element.scope().$apply(function() {
ctrl.items = ['Grape'];
ctrl.removeChip(0);
});

expect(scope.removeChip).toHaveBeenCalled();
expect(scope.removeChip.calls.mostRecent().args[0]).toBe('Grape'); // Chip
expect(scope.removeChip.calls.mostRecent().args[1]).toBe(0); // Index
});


it('should handle appending an object chip', function() {
var element = buildChips(CHIP_APPEND_TEMPLATE);
var ctrl = element.controller('mdChips');
Expand Down
17 changes: 16 additions & 1 deletion src/components/chips/js/chipsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,17 @@ MdChipsCtrl.prototype.useMdOnAppendExpression = function() {
this.useMdOnAppend = 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
* controller cannot know on its own/from the scope whether an expression was
* actually provided.
*/
MdChipsCtrl.prototype.useMdOnRemoveExpression = function() {
this.useMdOnRemove = true;
};

/**
* Gets the input buffer. The input buffer can be the model bound to the
* default input item {@code this.chipBuffer}, the {@code selectedItem}
Expand Down Expand Up @@ -234,7 +245,11 @@ MdChipsCtrl.prototype.resetChipBuffer = function() {
* @param index
*/
MdChipsCtrl.prototype.removeChip = function(index) {
this.items.splice(index, 1);
var removed = this.items.splice(index, 1);

if (removed && removed.length && this.useMdOnRemove && this.mdOnRemove) {
this.mdOnRemove({ '$chip': removed[0], '$index': index });
}
};

MdChipsCtrl.prototype.removeChipAndFocusInput = function (index) {
Expand Down
7 changes: 7 additions & 0 deletions src/components/chips/js/chipsDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
* the input and delete buttons
* @param {expression} md-on-append An expression expected to convert the input string into an
* object when adding a chip.
* @param {expression} md-on-remove An expression which will be called when a chip has been
* removed.
* @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
Expand Down Expand Up @@ -161,6 +163,7 @@
placeholder: '@',
secondaryPlaceholder: '@',
mdOnAppend: '&',
mdOnRemove: '&',
deleteHint: '@',
deleteButtonLabel: '@',
requireMatch: '=?mdRequireMatch'
Expand Down Expand Up @@ -244,6 +247,10 @@
// when appending chips.
if (attrs.mdOnAppend) mdChipsCtrl.useMdOnAppendExpression();

// If an `md-on-remove` attribute was set, tell the controller to use the expression
// when removing chips.
if (attrs.mdOnRemove) mdChipsCtrl.useMdOnRemoveExpression();

// 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
// configure the controller.
Expand Down