From 1a6cc3e629dd32cc6942cf558d799d97f98188df Mon Sep 17 00:00:00 2001 From: Fredrik de Vibe Date: Mon, 27 Oct 2014 15:24:14 +0100 Subject: [PATCH] Add option 'limit' to limit the number of items that can be selected in multiple mode. --- src/select.js | 5 +++++ test/select.spec.js | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/select.js b/src/select.js index b9abb8031..12d76c1fb 100644 --- a/src/select.js +++ b/src/select.js @@ -520,6 +520,10 @@ processed = _handleMatchSelection(key); } + if (!processed && ctrl.multiple && ctrl.limit !== undefined && ctrl.limit <= ctrl.selected.length) { + processed = true; + } + if (!processed && ctrl.items.length > 0) { processed = _handleDropDownSelection(key); } @@ -605,6 +609,7 @@ $select.onSelectCallback = $parse(attrs.onSelect); $select.onRemoveCallback = $parse(attrs.onRemove); + $select.limit = (angular.isDefined(attrs.limit)) ? parseInt(attrs.limit, 10) : undefined; //From view --> model ngModel.$parsers.unshift(function (inputValue) { diff --git a/test/select.spec.js b/test/select.spec.js index 2c5224ac3..8b9a90181 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -107,11 +107,15 @@ describe('ui-select tests', function() { return el.scope().$select.open && el.hasClass('open'); } + function createKeydownEvent(keyCode) { + var event = jQuery.Event("keydown"); + event.which = keyCode; + event.keyCode = keyCode; + return event; + } + function triggerKeydown(element, keyCode) { - var e = jQuery.Event("keydown"); - e.which = keyCode; - e.keyCode = keyCode; - element.trigger(e); + element.trigger(createKeydownEvent(keyCode)); } function setSearchText(el, text) { @@ -1011,6 +1015,7 @@ describe('ui-select tests', function() { if (attrs.disabled !== undefined) { attrsHtml += ' ng-disabled="' + attrs.disabled + '"'; } if (attrs.required !== undefined) { attrsHtml += ' ng-required="' + attrs.required + '"'; } if (attrs.tabindex !== undefined) { attrsHtml += ' tabindex="' + attrs.tabindex + '"'; } + if (attrs.limit !== undefined) { attrsHtml += ' limit="' + attrs.limit + '"'; } } return compileTemplate( @@ -1307,6 +1312,36 @@ describe('ui-select tests', function() { expect(el.find('.ui-select-match-item').length).toBe(2); }); + it('should allow more searches if limit is set but not reached', function () { + var el, + searchInput, + event = createKeydownEvent('a'), + preventDefaultCalled = false; + scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; + el = createUiSelectMultiple({limit: 3}); + searchInput = el.find('.ui-select-search'); + event.preventDefault = function () { + preventDefaultCalled = true; + }; + searchInput.trigger(event); + expect(preventDefaultCalled).toBe(false); + }); + + it('should not allow more searches if limit is set and reached', function () { + var el, + searchInput, + event = createKeydownEvent('a'), + preventDefaultCalled = false; + scope.selection.selectedMultiple = [scope.people[4], scope.people[5], scope.people[6]]; + el = createUiSelectMultiple({limit: 3}); + searchInput = el.find('.ui-select-search'); + event.preventDefault = function () { + preventDefaultCalled = true; + }; + searchInput.trigger(event); + expect(preventDefaultCalled).toBe(true); + }); + it('should parse the items correctly using single property binding', function() { scope.selection.selectedMultiple = ['wladimir@email.com', 'samantha@email.com'];