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

Commit

Permalink
fix(chips): do not trim the input model.
Browse files Browse the repository at this point in the history
* The chips input should not trim the text, because otherwise the buffer will be always falsey, even when there are spaces in the input, and this would cause the backspace not to work.

Fixes #7243

Closes #7748

# Conflicts:
#	src/components/chips/js/chipsController.js
  • Loading branch information
devversion authored and ThomasBurleson committed Apr 1, 2016
1 parent b05b1f7 commit d7c389d
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 5 deletions.
51 changes: 51 additions & 0 deletions src/components/chips/chips.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,59 @@ describe('<md-chips>', function() {
expect(enterEvent.preventDefault).toHaveBeenCalled();
}));

it('should trim the buffer when a chip will be added', inject(function($mdConstant) {
var element = buildChips(BASIC_CHIP_TEMPLATE);
var ctrl = element.controller('mdChips');
var input = element.find('input');

// This string contains a lot of spaces, which should be trimmed.
input.val(' Test ');
input.triggerHandler('input');

expect(ctrl.chipBuffer).toBeTruthy();

var enterEvent = {
type: 'keydown',
keyCode: $mdConstant.KEY_CODE.ENTER,
which: $mdConstant.KEY_CODE.ENTER
};

input.triggerHandler(enterEvent);

expect(scope.items).toEqual(['Apple', 'Banana', 'Orange', 'Test']);
}));

it('should not trim the input text of the input', inject(function($mdConstant) {
var element = buildChips(BASIC_CHIP_TEMPLATE);
var ctrl = element.controller('mdChips');
var input = element.find('input');

input.val(' ');
input.triggerHandler('input');

expect(ctrl.chipBuffer).toBeTruthy();

var enterEvent = {
type: 'keydown',
keyCode: $mdConstant.KEY_CODE.BACKSPACE,
which: $mdConstant.KEY_CODE.BACKSPACE,
preventDefault: jasmine.createSpy('preventDefault')
};

input.triggerHandler(enterEvent);

expect(enterEvent.preventDefault).not.toHaveBeenCalled();

input.val('');
input.triggerHandler('input');

input.triggerHandler(enterEvent);

expect(enterEvent.preventDefault).toHaveBeenCalledTimes(1);
}));
});


it('focuses/blurs the component when focusing/blurring the input', inject(function() {
var element = buildChips(BASIC_CHIP_TEMPLATE);
var ctrl = element.controller('mdChips');
Expand Down
67 changes: 62 additions & 5 deletions src/components/chips/js/chipsController.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ angular
* @param $mdConstant
* @param $log
* @param $element
* @param $mdUtil
* @constructor
*/
function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) {
function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout, $mdUtil) {
/** @type {$timeout} **/
this.$timeout = $timeout;

Expand Down Expand Up @@ -50,6 +51,8 @@ function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) {
/** @type {boolean} */
this.hasAutocomplete = false;

/** @type {string} */
this.enableChipEdit = $mdUtil.parseAttributeBoolean(this.mdEnableChipEdit);

/**
* Hidden hint text for how to delete a chip. Used to give context to screen readers.
Expand Down Expand Up @@ -137,18 +140,47 @@ MdChipsCtrl.prototype.inputKeydown = function(event) {
if (this.separatorKeys.indexOf(event.keyCode) !== -1) {
if ((this.hasAutocomplete && this.requireMatch) || !chipBuffer) return;
event.preventDefault();
this.appendChip(chipBuffer);

// Only append the chip and reset the chip buffer if the max chips limit isn't reached.
if (this.hasMaxChipsReached()) return;

this.appendChip(chipBuffer.trim());
this.resetChipBuffer();
}
};


/**
* Updates the content of the chip at given index
* @param chipIndex
* @param chipContents
*/
MdChipsCtrl.prototype.updateChipContents = function(chipIndex, chipContents){
if(chipIndex >= 0 && chipIndex < this.items.length) {
this.items[chipIndex] = chipContents;
this.ngModelCtrl.$setDirty();
}
};


/**
* Returns true if a chip is currently being edited. False otherwise.
* @return {boolean}
*/
MdChipsCtrl.prototype.isEditingChip = function(){
return !!this.$element[0].getElementsByClassName('_md-chip-editing').length;
};


/**
* Handles the keydown event on the chip elements: backspace removes the selected chip, arrow
* keys switch which chips is active
* @param event
*/
MdChipsCtrl.prototype.chipKeydown = function (event) {
if (this.getChipBuffer()) return;
if (this.isEditingChip()) return;

switch (event.keyCode) {
case this.$mdConstant.KEY_CODE.BACKSPACE:
case this.$mdConstant.KEY_CODE.DELETE:
Expand Down Expand Up @@ -242,7 +274,7 @@ MdChipsCtrl.prototype.appendChip = function(newChip) {
var identical = this.items.some(function(item){
return angular.equals(newChip, item);
});
if(identical) return;
if (identical) return;
}

// Check for a null (but not undefined), or existing chip and cancel appending
Expand All @@ -251,6 +283,10 @@ MdChipsCtrl.prototype.appendChip = function(newChip) {
// Append the new chip onto our list
var index = this.items.push(newChip);

// Update model validation
this.ngModelCtrl.$setDirty();
this.validateModel();

// If they provide the md-on-add attribute, notify them of the chip addition
if (this.useOnAdd && this.onAdd) {
this.onAdd({ '$chip': newChip, '$index': index });
Expand Down Expand Up @@ -350,13 +386,30 @@ MdChipsCtrl.prototype.resetChipBuffer = function() {
}
};

MdChipsCtrl.prototype.hasMaxChipsReached = function() {
if (angular.isString(this.maxChips)) this.maxChips = parseInt(this.maxChips, 10) || 0;

return this.maxChips > 0 && this.items.length >= this.maxChips;
};

/**
* Updates the validity properties for the ngModel.
*/
MdChipsCtrl.prototype.validateModel = function() {
this.ngModelCtrl.$setValidity('md-max-chips', !this.hasMaxChipsReached());
};

/**
* Removes the chip at the given index.
* @param index
*/
MdChipsCtrl.prototype.removeChip = function(index) {
var removed = this.items.splice(index, 1);

// Update model validation
this.ngModelCtrl.$setDirty();
this.validateModel();

if (removed && removed.length && this.useOnRemove && this.onRemove) {
this.onRemove({ '$chip': removed[0], '$index': index });
}
Expand Down Expand Up @@ -415,7 +468,7 @@ MdChipsCtrl.prototype.selectAndFocusChip = function(index) {
* Call `focus()` on the chip at `index`
*/
MdChipsCtrl.prototype.focusChip = function(index) {
this.$element[0].querySelector('md-chip[index="' + index + '"] .md-chip-content').focus();
this.$element[0].querySelector('md-chip[index="' + index + '"] ._md-chip-content').focus();
};

/**
Expand Down Expand Up @@ -479,10 +532,14 @@ MdChipsCtrl.prototype.configureUserInput = function(inputElement) {
};

MdChipsCtrl.prototype.configureAutocomplete = function(ctrl) {
if ( ctrl ){
if ( ctrl ) {
this.hasAutocomplete = true;

ctrl.registerSelectedItemWatcher(angular.bind(this, function (item) {
if (item) {
// Only append the chip and reset the chip buffer if the max chips limit isn't reached.
if (this.hasMaxChipsReached()) return;

this.appendChip(item);
this.resetChipBuffer();
}
Expand Down
1 change: 1 addition & 0 deletions src/components/chips/js/chipsDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
ng-model="$mdChipsCtrl.chipBuffer"\
ng-focus="$mdChipsCtrl.onInputFocus()"\
ng-blur="$mdChipsCtrl.onInputBlur()"\
ng-trim="false"\
ng-keydown="$mdChipsCtrl.inputKeydown($event)">';

var CHIP_DEFAULT_TEMPLATE = '\
Expand Down

0 comments on commit d7c389d

Please sign in to comment.