Skip to content

Commit

Permalink
fix(uiSelectController): Select by click on non-multiple tagging
Browse files Browse the repository at this point in the history
When in tagging mode, not multiple (`taggingLabel === false`), selecting
an item by click was instead calling `taggingFunc()`. This fix checks
for this manual selection, whether `ctrl.search` is filled or not and
acts accordingly.

closes angular-ui#1357
  • Loading branch information
soyuka committed Feb 16, 2016
1 parent b1c4fdc commit 2ed4f8e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 56 deletions.
117 changes: 61 additions & 56 deletions src/uiSelectController.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,69 +294,74 @@ uis.controller('uiSelectCtrl',

// When the user selects an item with ENTER or clicks the dropdown
ctrl.select = function(item, skipFocusser, $event) {
if (item === undefined || !item._uiSelectChoiceDisabled) {

if ( ! ctrl.items && ! ctrl.search && ! ctrl.tagging.isActivated) return;

if (!item || !item._uiSelectChoiceDisabled) {
if(ctrl.tagging.isActivated) {
// if taggingLabel is disabled, we pull from ctrl.search val
if ( ctrl.taggingLabel === false ) {
if ( ctrl.activeIndex < 0 ) {
item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search;
if (!item || angular.equals( ctrl.items[0], item ) ) {
return;
}
} else {
// keyboard nav happened first, user selected from dropdown
item = ctrl.items[ctrl.activeIndex];
}
} else {
// tagging always operates at index zero, taggingLabel === false pushes
// the ctrl.search value without having it injected
if ( ctrl.activeIndex === 0 ) {
// ctrl.tagging pushes items to ctrl.items, so we only have empty val
// for `item` if it is a detected duplicate
if ( item === undefined ) return;

// create new item on the fly if we don't already have one;
// use tagging function if we have one
if ( ctrl.tagging.fct !== undefined && typeof item === 'string' ) {
item = ctrl.tagging.fct(ctrl.search);
if (!item) return;
// if item type is 'string', apply the tagging label
} else if ( typeof item === 'string' ) {
// trim the trailing space
item = item.replace(ctrl.taggingLabel,'').trim();
}
}
}
// search ctrl.selected for dupes potentially caused by tagging and return early if found
if ( ctrl.selected && angular.isArray(ctrl.selected) && ctrl.selected.filter( function (selection) { return angular.equals(selection, item); }).length > 0 ) {
ctrl.close(skipFocusser);
if (item && item._uiSelectChoiceDisabled === true)
return;

if (! ctrl.items && ! ctrl.search && ! ctrl.tagging.isActivated)
return;

if (ctrl.tagging.isActivated) {
//click is made on existing item, prevent from tagging, ctrl.search does not matter
var manualSelection = false;
if ($event && $event.type === 'click' && item) {
manualSelection = true;
}

// if taggingLabel is disabled, we pull from ctrl.search val
if ( ctrl.taggingLabel === false && manualSelection === false) {
if ( ctrl.activeIndex < 0 ) {
item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search;
if (!item || angular.equals( ctrl.items[0], item ) ) {
return;
}
} else {
// keyboard nav happened first, user selected from dropdown
item = ctrl.items[ctrl.activeIndex];
}
} else {
// tagging always operates at index zero, taggingLabel === false pushes
// the ctrl.search value without having it injected
if ( ctrl.activeIndex === 0 ) {
// ctrl.tagging pushes items to ctrl.items, so we only have empty val
// for `item` if it is a detected duplicate
if ( item === undefined ) return;

// create new item on the fly if we don't already have one;
// use tagging function if we have one
if ( ctrl.tagging.fct !== undefined && typeof item === 'string' ) {
item = ctrl.tagging.fct(ctrl.search);
if (!item) return;
// if item type is 'string', apply the tagging label
} else if ( typeof item === 'string' ) {
// trim the trailing space
item = item.replace(ctrl.taggingLabel,'').trim();
}
}
}
// search ctrl.selected for dupes potentially caused by tagging and return early if found
if ( ctrl.selected && angular.isArray(ctrl.selected) && ctrl.selected.filter( function (selection) { return angular.equals(selection, item); }).length > 0 ) {
ctrl.close(skipFocusser);
return;
}
}

$scope.$broadcast('uis:select', item);
$scope.$broadcast('uis:select', item);

var locals = {};
locals[ctrl.parserResult.itemName] = item;
var locals = {};
locals[ctrl.parserResult.itemName] = item;

$timeout(function(){
ctrl.onSelectCallback($scope, {
$item: item,
$model: ctrl.parserResult.modelMapper($scope, locals)
});
});
$timeout(function(){
ctrl.onSelectCallback($scope, {
$item: item,
$model: ctrl.parserResult.modelMapper($scope, locals)
});
});

if (ctrl.closeOnSelect) {
ctrl.close(skipFocusser);
}
if ($event && $event.type === 'click') {
ctrl.clickTriggeredSelect = true;
}
}
if (ctrl.closeOnSelect) {
ctrl.close(skipFocusser);
}
if ($event && $event.type === 'click') {
ctrl.clickTriggeredSelect = true;
}
};

Expand Down
24 changes: 24 additions & 0 deletions test/select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,30 @@ describe('ui-select tests', function() {
expect($(el).scope().$select.selected).toEqual(['idontexist']);
});

it('should allow selecting an item (click) in single select mode with tagging enabled', function() {

scope.taggingFunc = function (name) {
return name;
};

var el = compileTemplate(
'<ui-select ng-model="selection.selected" tagging="taggingFunc" tagging-label="false"> \
<ui-select-match placeholder="Pick one...">{{$select.selected.name}}</ui-select-match> \
<ui-select-choices repeat="person in people | filter: $select.search"> \
<div ng-bind-html="person.name" | highlight: $select.search"></div> \
<div ng-bind-html="person.email | highlight: $select.search"></div> \
</ui-select-choices> \
</ui-select>'
);

clickMatch(el);
setSearchText(el, 'Sam');
clickItem(el, 'Samantha');

expect(scope.selection.selected).toBe(scope.people[5]);
expect(getMatchLabel(el)).toEqual('Samantha');
});

it('should append/transclude content (with correct scope) that users add at <match> tag', function () {

var el = compileTemplate(
Expand Down

0 comments on commit 2ed4f8e

Please sign in to comment.