diff --git a/src/uiSelectController.js b/src/uiSelectController.js index 1afccb72e..a6ff2b95f 100644 --- a/src/uiSelectController.js +++ b/src/uiSelectController.js @@ -16,6 +16,7 @@ uis.controller('uiSelectCtrl', ctrl.searchEnabled = uiSelectConfig.searchEnabled; ctrl.sortable = uiSelectConfig.sortable; ctrl.refreshDelay = uiSelectConfig.refreshDelay; + ctrl.paste = uiSelectConfig.paste; ctrl.removeSelected = false; //If selected item(s) should be removed from dropdown list ctrl.closeOnSelect = true; //Initialized inside uiSelect directive link function @@ -295,7 +296,7 @@ uis.controller('uiSelectCtrl', // 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); + item = ctrl.tagging.fct(item); if (!item) return; // if item type is 'string', apply the tagging label } else if ( typeof item === 'string' ) { @@ -491,18 +492,36 @@ uis.controller('uiSelectCtrl', }); - // If tagging try to split by tokens and add items ctrl.searchInput.on('paste', function (e) { - var data = e.originalEvent.clipboardData.getData('text/plain'); - if (data && data.length > 0 && ctrl.taggingTokens.isActivated && ctrl.tagging.fct) { - var items = data.split(ctrl.taggingTokens.tokens[0]); // split by first token only - if (items && items.length > 0) { - angular.forEach(items, function (item) { - var newItem = ctrl.tagging.fct(item); - if (newItem) { - ctrl.select(newItem, true); - } - }); + var data; + + if (window.clipboardData && window.clipboardData.getData) { // IE + data = window.clipboardData.getData('Text'); + } else { + data = (e.originalEvent || e).clipboardData.getData('text/plain'); + } + + // Prepend the current input field text to the paste buffer. + data = ctrl.search + data; + + if (data && data.length > 0) { + // If tagging try to split by tokens and add items + if (ctrl.taggingTokens.isActivated) { + var items = data.split(ctrl.taggingTokens.tokens[0]); // split by first token only + if (items && items.length > 0) { + angular.forEach(items, function (item) { + var newItem = ctrl.tagging.fct ? ctrl.tagging.fct(item) : item; + if (newItem) { + ctrl.select(newItem, true); + } + }); + ctrl.search = EMPTY_SEARCH; + e.preventDefault(); + e.stopPropagation(); + } + } else if (ctrl.paste) { + ctrl.paste(data); + ctrl.search = EMPTY_SEARCH; e.preventDefault(); e.stopPropagation(); } diff --git a/src/uiSelectDirective.js b/src/uiSelectDirective.js index ed3394d01..5b7137b50 100644 --- a/src/uiSelectDirective.js +++ b/src/uiSelectDirective.js @@ -85,6 +85,10 @@ uis.directive('uiSelect', $select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true; }); + attrs.$observe('paste', function() { + $select.paste = scope.$eval(attrs.paste); + }); + attrs.$observe('tagging', function() { if(attrs.tagging !== undefined) { diff --git a/test/select.spec.js b/test/select.spec.js index 3663ab839..e2f009a58 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -173,15 +173,23 @@ describe('ui-select tests', function() { e.keyCode = keyCode; element.trigger(e); } - function triggerPaste(element, text) { + function triggerPaste(element, text, isClipboardEvent) { var e = jQuery.Event("paste"); - e.originalEvent = { + if (isClipboardEvent) { + e.clipboardData = { + getData : function() { + return text; + } + }; + } else { + e.originalEvent = { clipboardData : { getData : function() { return text; } } - }; + }; + } element.trigger(e); } @@ -2063,20 +2071,39 @@ describe('ui-select tests', function() { }); it('should allow paste tag from clipboard', function() { - scope.taggingFunc = function (name) { - return { - name: name, - email: name + '@email.com', - group: 'Foo', - age: 12 - }; - }; + scope.taggingFunc = function (name) { + return { + name: name, + email: name + '@email.com', + group: 'Foo', + age: 12 + }; + }; + + var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"}); + clickMatch(el); + triggerPaste(el.find('input'), 'tag1'); + + expect($(el).scope().$select.selected.length).toBe(1); + expect($(el).scope().$select.selected[0].name).toBe('tag1'); + }); + + it('should allow paste tag from clipboard for generic ClipboardEvent', function() { + scope.taggingFunc = function (name) { + return { + name: name, + email: name + '@email.com', + group: 'Foo', + age: 12 + }; + }; - var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"}); - clickMatch(el); - triggerPaste(el.find('input'), 'tag1'); + var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"}); + clickMatch(el); + triggerPaste(el.find('input'), 'tag1', true); - expect($(el).scope().$select.selected.length).toBe(1); + expect($(el).scope().$select.selected.length).toBe(1); + expect($(el).scope().$select.selected[0].name).toBe('tag1'); }); it('should allow paste multiple tags', function() { @@ -2096,6 +2123,23 @@ describe('ui-select tests', function() { expect($(el).scope().$select.selected.length).toBe(5); }); + it('should allow paste multiple tags with generic ClipboardEvent', function() { + scope.taggingFunc = function (name) { + return { + name: name, + email: name + '@email.com', + group: 'Foo', + age: 12 + }; + }; + + var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"}); + clickMatch(el); + triggerPaste(el.find('input'), ',tag1,tag2,tag3,,tag5,', true); + + expect($(el).scope().$select.selected.length).toBe(5); + }); + it('should add an id to the search input field', function () { var el = createUiSelectMultiple({inputId: 'inid'}); var searchEl = $(el).find('input.ui-select-search');