Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

Commit 1ad6f60

Browse files
committed
fix(paste): add paste support
Add paste="expression" to allow custom paste handling. Allow pasting in tagging mode when the tagging function is not defined. In IE use window.clipboardData so jQuery is not required. Fixes #910, #704, #789, #848, #429
2 parents 1502a58 + 1f25ec5 commit 1ad6f60

File tree

3 files changed

+94
-28
lines changed

3 files changed

+94
-28
lines changed

Diff for: src/uiSelectController.js

+31-13
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ uis.controller('uiSelectCtrl',
1616
ctrl.searchEnabled = uiSelectConfig.searchEnabled;
1717
ctrl.sortable = uiSelectConfig.sortable;
1818
ctrl.refreshDelay = uiSelectConfig.refreshDelay;
19+
ctrl.paste = uiSelectConfig.paste;
1920

2021
ctrl.removeSelected = false; //If selected item(s) should be removed from dropdown list
2122
ctrl.closeOnSelect = true; //Initialized inside uiSelect directive link function
@@ -340,7 +341,7 @@ uis.controller('uiSelectCtrl',
340341
// create new item on the fly if we don't already have one;
341342
// use tagging function if we have one
342343
if ( ctrl.tagging.fct !== undefined && typeof item === 'string' ) {
343-
item = ctrl.tagging.fct(ctrl.search);
344+
item = ctrl.tagging.fct(item);
344345
if (!item) return;
345346
// if item type is 'string', apply the tagging label
346347
} else if ( typeof item === 'string' ) {
@@ -536,20 +537,37 @@ uis.controller('uiSelectCtrl',
536537

537538
});
538539

539-
// If tagging try to split by tokens and add items
540540
ctrl.searchInput.on('paste', function (e) {
541-
var data = e.originalEvent.clipboardData.getData('text/plain');
542-
if (data && data.length > 0 && ctrl.taggingTokens.isActivated) {
543-
// split by first token only
544-
var separator = KEY.toSeparator(ctrl.taggingTokens.tokens[0]);
545-
var items = data.split(separator);
546-
if (items && items.length > 0) {
541+
var data;
542+
543+
if (window.clipboardData && window.clipboardData.getData) { // IE
544+
data = window.clipboardData.getData('Text');
545+
} else {
546+
data = (e.originalEvent || e).clipboardData.getData('text/plain');
547+
}
548+
549+
// Prepend the current input field text to the paste buffer.
550+
data = ctrl.search + data;
551+
552+
if (data && data.length > 0) {
553+
// If tagging try to split by tokens and add items
554+
if (ctrl.taggingTokens.isActivated) {
555+
var items = data.split(ctrl.taggingTokens.tokens[0]); // split by first token only
556+
if (items && items.length > 0) {
547557
var oldsearch = ctrl.search;
548-
angular.forEach(items, function (item) {
549-
ctrl.search = item;
550-
ctrl.select(item, true);
551-
});
552-
ctrl.search = oldsearch;
558+
angular.forEach(items, function (item) {
559+
var newItem = ctrl.tagging.fct ? ctrl.tagging.fct(item) : item;
560+
if (newItem) {
561+
ctrl.select(newItem, true);
562+
}
563+
});
564+
ctrl.search = EMPTY_SEARCH;
565+
e.preventDefault();
566+
e.stopPropagation();
567+
}
568+
} else if (ctrl.paste) {
569+
ctrl.paste(data);
570+
ctrl.search = EMPTY_SEARCH;
553571
e.preventDefault();
554572
e.stopPropagation();
555573
}

Diff for: src/uiSelectDirective.js

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ uis.directive('uiSelect',
9393
$select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true;
9494
});
9595

96+
attrs.$observe('paste', function() {
97+
$select.paste = scope.$eval(attrs.paste);
98+
});
99+
96100
attrs.$observe('tagging', function() {
97101
if(attrs.tagging !== undefined)
98102
{

Diff for: test/select.spec.js

+59-15
Original file line numberDiff line numberDiff line change
@@ -173,15 +173,23 @@ describe('ui-select tests', function() {
173173
e.keyCode = keyCode;
174174
element.trigger(e);
175175
}
176-
function triggerPaste(element, text) {
176+
function triggerPaste(element, text, isClipboardEvent) {
177177
var e = jQuery.Event("paste");
178-
e.originalEvent = {
178+
if (isClipboardEvent) {
179+
e.clipboardData = {
180+
getData : function() {
181+
return text;
182+
}
183+
};
184+
} else {
185+
e.originalEvent = {
179186
clipboardData : {
180187
getData : function() {
181188
return text;
182189
}
183190
}
184-
};
191+
};
192+
}
185193
element.trigger(e);
186194
}
187195

@@ -2095,20 +2103,39 @@ describe('ui-select tests', function() {
20952103
});
20962104

20972105
it('should allow paste tag from clipboard', function() {
2098-
scope.taggingFunc = function (name) {
2099-
return {
2100-
name: name,
2101-
email: name + '@email.com',
2102-
group: 'Foo',
2103-
age: 12
2104-
};
2105-
};
2106+
scope.taggingFunc = function (name) {
2107+
return {
2108+
name: name,
2109+
email: name + '@email.com',
2110+
group: 'Foo',
2111+
age: 12
2112+
};
2113+
};
2114+
2115+
var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"});
2116+
clickMatch(el);
2117+
triggerPaste(el.find('input'), 'tag1');
2118+
2119+
expect($(el).scope().$select.selected.length).toBe(1);
2120+
expect($(el).scope().$select.selected[0].name).toBe('tag1');
2121+
});
2122+
2123+
it('should allow paste tag from clipboard for generic ClipboardEvent', function() {
2124+
scope.taggingFunc = function (name) {
2125+
return {
2126+
name: name,
2127+
email: name + '@email.com',
2128+
group: 'Foo',
2129+
age: 12
2130+
};
2131+
};
21062132

2107-
var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"});
2108-
clickMatch(el);
2109-
triggerPaste(el.find('input'), 'tag1');
2133+
var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"});
2134+
clickMatch(el);
2135+
triggerPaste(el.find('input'), 'tag1', true);
21102136

2111-
expect($(el).scope().$select.selected.length).toBe(1);
2137+
expect($(el).scope().$select.selected.length).toBe(1);
2138+
expect($(el).scope().$select.selected[0].name).toBe('tag1');
21122139
});
21132140

21142141
it('should allow paste multiple tags', function() {
@@ -2128,6 +2155,23 @@ describe('ui-select tests', function() {
21282155
expect($(el).scope().$select.selected.length).toBe(5);
21292156
});
21302157

2158+
it('should allow paste multiple tags with generic ClipboardEvent', function() {
2159+
scope.taggingFunc = function (name) {
2160+
return {
2161+
name: name,
2162+
email: name + '@email.com',
2163+
group: 'Foo',
2164+
age: 12
2165+
};
2166+
};
2167+
2168+
var el = createUiSelectMultiple({tagging: 'taggingFunc', taggingTokens: ",|ENTER"});
2169+
clickMatch(el);
2170+
triggerPaste(el.find('input'), ',tag1,tag2,tag3,,tag5,', true);
2171+
2172+
expect($(el).scope().$select.selected.length).toBe(5);
2173+
});
2174+
21312175
it('should split pastes on ENTER (and with undefined tagging function)', function() {
21322176
var el = createUiSelectMultiple({tagging: true, taggingTokens: "ENTER|,"});
21332177
clickMatch(el);

0 commit comments

Comments
 (0)