|
1 | 1 | /*!
|
2 | 2 | * ui-select
|
3 | 3 | * http://github.com/angular-ui/ui-select
|
4 |
| - * Version: 0.11.2 - 2015-03-17T04:08:46.474Z |
| 4 | + * Version: 0.11.2 - 2015-05-19T14:16:04.953Z |
5 | 5 | * License: MIT
|
6 | 6 | */
|
7 | 7 |
|
@@ -540,7 +540,9 @@ uis.controller('uiSelectCtrl',
|
540 | 540 | ctrl.clear = function($event) {
|
541 | 541 | ctrl.select(undefined);
|
542 | 542 | $event.stopPropagation();
|
543 |
| - ctrl.focusser[0].focus(); |
| 543 | + $timeout(function() { |
| 544 | + ctrl.focusser[0].focus(); |
| 545 | + }, 0, false); |
544 | 546 | };
|
545 | 547 |
|
546 | 548 | // Toggle dropdown
|
@@ -673,6 +675,148 @@ uis.controller('uiSelectCtrl',
|
673 | 675 |
|
674 | 676 | });
|
675 | 677 |
|
| 678 | + ctrl.searchInput.on('keyup', function(e) { |
| 679 | + if ( ! KEY.isVerticalMovement(e.which) ) { |
| 680 | + $scope.$evalAsync( function () { |
| 681 | + ctrl.activeIndex = ctrl.taggingLabel === false ? -1 : 0; |
| 682 | + }); |
| 683 | + } |
| 684 | + // Push a "create new" item into array if there is a search string |
| 685 | + if ( ctrl.tagging.isActivated && ctrl.search.length > 0 ) { |
| 686 | + |
| 687 | + // return early with these keys |
| 688 | + if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || KEY.isVerticalMovement(e.which) ) { |
| 689 | + return; |
| 690 | + } |
| 691 | + // always reset the activeIndex to the first item when tagging |
| 692 | + ctrl.activeIndex = ctrl.taggingLabel === false ? -1 : 0; |
| 693 | + // taggingLabel === false bypasses all of this |
| 694 | + if (ctrl.taggingLabel === false) return; |
| 695 | + |
| 696 | + var items = angular.copy( ctrl.items ); |
| 697 | + var stashArr = angular.copy( ctrl.items ); |
| 698 | + var newItem; |
| 699 | + var item; |
| 700 | + var hasTag = false; |
| 701 | + var dupeIndex = -1; |
| 702 | + var tagItems; |
| 703 | + var tagItem; |
| 704 | + |
| 705 | + // case for object tagging via transform `ctrl.tagging.fct` function |
| 706 | + if ( ctrl.tagging.fct !== undefined) { |
| 707 | + tagItems = ctrl.$filter('filter')(items,{'isTag': true}); |
| 708 | + if ( tagItems.length > 0 ) { |
| 709 | + tagItem = tagItems[0]; |
| 710 | + } |
| 711 | + // remove the first element, if it has the `isTag` prop we generate a new one with each keyup, shaving the previous |
| 712 | + if ( items.length > 0 && tagItem ) { |
| 713 | + hasTag = true; |
| 714 | + items = items.slice(1,items.length); |
| 715 | + stashArr = stashArr.slice(1,stashArr.length); |
| 716 | + } |
| 717 | + newItem = ctrl.tagging.fct(ctrl.search); |
| 718 | + newItem.isTag = true; |
| 719 | + // verify the the tag doesn't match the value of an existing item |
| 720 | + if ( stashArr.filter( function (origItem) { return angular.equals( origItem, ctrl.tagging.fct(ctrl.search) ); } ).length > 0 ) { |
| 721 | + return; |
| 722 | + } |
| 723 | + newItem.isTag = true; |
| 724 | + // handle newItem string and stripping dupes in tagging string context |
| 725 | + } else { |
| 726 | + // find any tagging items already in the ctrl.items array and store them |
| 727 | + tagItems = ctrl.$filter('filter')(items,function (item) { |
| 728 | + return item.match(ctrl.taggingLabel); |
| 729 | + }); |
| 730 | + if ( tagItems.length > 0 ) { |
| 731 | + tagItem = tagItems[0]; |
| 732 | + } |
| 733 | + item = items[0]; |
| 734 | + // remove existing tag item if found (should only ever be one tag item) |
| 735 | + if ( item !== undefined && items.length > 0 && tagItem ) { |
| 736 | + hasTag = true; |
| 737 | + items = items.slice(1,items.length); |
| 738 | + stashArr = stashArr.slice(1,stashArr.length); |
| 739 | + } |
| 740 | + newItem = ctrl.search+' '+ctrl.taggingLabel; |
| 741 | + if ( _findApproxDupe(ctrl.selected, ctrl.search) > -1 ) { |
| 742 | + return; |
| 743 | + } |
| 744 | + // verify the the tag doesn't match the value of an existing item from |
| 745 | + // the searched data set or the items already selected |
| 746 | + if ( _findCaseInsensitiveDupe(stashArr.concat(ctrl.selected)) ) { |
| 747 | + // if there is a tag from prev iteration, strip it / queue the change |
| 748 | + // and return early |
| 749 | + if ( hasTag ) { |
| 750 | + items = stashArr; |
| 751 | + $scope.$evalAsync( function () { |
| 752 | + ctrl.activeIndex = 0; |
| 753 | + ctrl.items = items; |
| 754 | + }); |
| 755 | + } |
| 756 | + return; |
| 757 | + } |
| 758 | + if ( _findCaseInsensitiveDupe(stashArr) ) { |
| 759 | + // if there is a tag from prev iteration, strip it |
| 760 | + if ( hasTag ) { |
| 761 | + ctrl.items = stashArr.slice(1,stashArr.length); |
| 762 | + } |
| 763 | + return; |
| 764 | + } |
| 765 | + } |
| 766 | + if ( hasTag ) dupeIndex = _findApproxDupe(ctrl.selected, newItem); |
| 767 | + // dupe found, shave the first item |
| 768 | + if ( dupeIndex > -1 ) { |
| 769 | + items = items.slice(dupeIndex+1,items.length-1); |
| 770 | + } else { |
| 771 | + items = []; |
| 772 | + items.push(newItem); |
| 773 | + items = items.concat(stashArr); |
| 774 | + } |
| 775 | + $scope.$evalAsync( function () { |
| 776 | + ctrl.activeIndex = 0; |
| 777 | + ctrl.items = items; |
| 778 | + }); |
| 779 | + } |
| 780 | + |
| 781 | + }); |
| 782 | + |
| 783 | + function _findCaseInsensitiveDupe(arr) { |
| 784 | + if ( arr === undefined || ctrl.search === undefined ) { |
| 785 | + return false; |
| 786 | + } |
| 787 | + var hasDupe = arr.filter( function (origItem) { |
| 788 | + if ( ctrl.search.toUpperCase() === undefined || origItem === undefined ) { |
| 789 | + return false; |
| 790 | + } |
| 791 | + return origItem.toUpperCase() === ctrl.search.toUpperCase(); |
| 792 | + }).length > 0; |
| 793 | + |
| 794 | + return hasDupe; |
| 795 | + } |
| 796 | + function _findApproxDupe(haystack, needle) { |
| 797 | + var dupeIndex = -1; |
| 798 | + if(angular.isArray(haystack)) { |
| 799 | + var tempArr = angular.copy(haystack); |
| 800 | + for (var i = 0; i <tempArr.length; i++) { |
| 801 | + // handle the simple string version of tagging |
| 802 | + if ( ctrl.tagging.fct === undefined ) { |
| 803 | + // search the array for the match |
| 804 | + if ( tempArr[i]+' '+ctrl.taggingLabel === needle ) { |
| 805 | + dupeIndex = i; |
| 806 | + } |
| 807 | + // handle the object tagging implementation |
| 808 | + } else { |
| 809 | + var mockObj = tempArr[i]; |
| 810 | + mockObj.isTag = true; |
| 811 | + if ( angular.equals(mockObj, needle) ) { |
| 812 | + dupeIndex = i; |
| 813 | + } |
| 814 | + } |
| 815 | + } |
| 816 | + } |
| 817 | + return dupeIndex; |
| 818 | + } |
| 819 | + |
676 | 820 | // If tagging try to split by tokens and add items
|
677 | 821 | ctrl.searchInput.on('paste', function (e) {
|
678 | 822 | var data = e.originalEvent.clipboardData.getData('text/plain');
|
@@ -1268,147 +1412,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
|
1268 | 1412 | return true;
|
1269 | 1413 | }
|
1270 | 1414 |
|
1271 |
| - $select.searchInput.on('keyup', function(e) { |
1272 |
| - |
1273 |
| - if ( ! KEY.isVerticalMovement(e.which) ) { |
1274 |
| - scope.$evalAsync( function () { |
1275 |
| - $select.activeIndex = $select.taggingLabel === false ? -1 : 0; |
1276 |
| - }); |
1277 |
| - } |
1278 |
| - // Push a "create new" item into array if there is a search string |
1279 |
| - if ( $select.tagging.isActivated && $select.search.length > 0 ) { |
1280 |
| - |
1281 |
| - // return early with these keys |
1282 |
| - if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC || KEY.isVerticalMovement(e.which) ) { |
1283 |
| - return; |
1284 |
| - } |
1285 |
| - // always reset the activeIndex to the first item when tagging |
1286 |
| - $select.activeIndex = $select.taggingLabel === false ? -1 : 0; |
1287 |
| - // taggingLabel === false bypasses all of this |
1288 |
| - if ($select.taggingLabel === false) return; |
1289 |
| - |
1290 |
| - var items = angular.copy( $select.items ); |
1291 |
| - var stashArr = angular.copy( $select.items ); |
1292 |
| - var newItem; |
1293 |
| - var item; |
1294 |
| - var hasTag = false; |
1295 |
| - var dupeIndex = -1; |
1296 |
| - var tagItems; |
1297 |
| - var tagItem; |
1298 |
| - |
1299 |
| - // case for object tagging via transform `$select.tagging.fct` function |
1300 |
| - if ( $select.tagging.fct !== undefined) { |
1301 |
| - tagItems = $select.$filter('filter')(items,{'isTag': true}); |
1302 |
| - if ( tagItems.length > 0 ) { |
1303 |
| - tagItem = tagItems[0]; |
1304 |
| - } |
1305 |
| - // remove the first element, if it has the `isTag` prop we generate a new one with each keyup, shaving the previous |
1306 |
| - if ( items.length > 0 && tagItem ) { |
1307 |
| - hasTag = true; |
1308 |
| - items = items.slice(1,items.length); |
1309 |
| - stashArr = stashArr.slice(1,stashArr.length); |
1310 |
| - } |
1311 |
| - newItem = $select.tagging.fct($select.search); |
1312 |
| - newItem.isTag = true; |
1313 |
| - // verify the the tag doesn't match the value of an existing item |
1314 |
| - if ( stashArr.filter( function (origItem) { return angular.equals( origItem, $select.tagging.fct($select.search) ); } ).length > 0 ) { |
1315 |
| - return; |
1316 |
| - } |
1317 |
| - newItem.isTag = true; |
1318 |
| - // handle newItem string and stripping dupes in tagging string context |
1319 |
| - } else { |
1320 |
| - // find any tagging items already in the $select.items array and store them |
1321 |
| - tagItems = $select.$filter('filter')(items,function (item) { |
1322 |
| - return item.match($select.taggingLabel); |
1323 |
| - }); |
1324 |
| - if ( tagItems.length > 0 ) { |
1325 |
| - tagItem = tagItems[0]; |
1326 |
| - } |
1327 |
| - item = items[0]; |
1328 |
| - // remove existing tag item if found (should only ever be one tag item) |
1329 |
| - if ( item !== undefined && items.length > 0 && tagItem ) { |
1330 |
| - hasTag = true; |
1331 |
| - items = items.slice(1,items.length); |
1332 |
| - stashArr = stashArr.slice(1,stashArr.length); |
1333 |
| - } |
1334 |
| - newItem = $select.search+' '+$select.taggingLabel; |
1335 |
| - if ( _findApproxDupe($select.selected, $select.search) > -1 ) { |
1336 |
| - return; |
1337 |
| - } |
1338 |
| - // verify the the tag doesn't match the value of an existing item from |
1339 |
| - // the searched data set or the items already selected |
1340 |
| - if ( _findCaseInsensitiveDupe(stashArr.concat($select.selected)) ) { |
1341 |
| - // if there is a tag from prev iteration, strip it / queue the change |
1342 |
| - // and return early |
1343 |
| - if ( hasTag ) { |
1344 |
| - items = stashArr; |
1345 |
| - scope.$evalAsync( function () { |
1346 |
| - $select.activeIndex = 0; |
1347 |
| - $select.items = items; |
1348 |
| - }); |
1349 |
| - } |
1350 |
| - return; |
1351 |
| - } |
1352 |
| - if ( _findCaseInsensitiveDupe(stashArr) ) { |
1353 |
| - // if there is a tag from prev iteration, strip it |
1354 |
| - if ( hasTag ) { |
1355 |
| - $select.items = stashArr.slice(1,stashArr.length); |
1356 |
| - } |
1357 |
| - return; |
1358 |
| - } |
1359 |
| - } |
1360 |
| - if ( hasTag ) dupeIndex = _findApproxDupe($select.selected, newItem); |
1361 |
| - // dupe found, shave the first item |
1362 |
| - if ( dupeIndex > -1 ) { |
1363 |
| - items = items.slice(dupeIndex+1,items.length-1); |
1364 |
| - } else { |
1365 |
| - items = []; |
1366 |
| - items.push(newItem); |
1367 |
| - items = items.concat(stashArr); |
1368 |
| - } |
1369 |
| - scope.$evalAsync( function () { |
1370 |
| - $select.activeIndex = 0; |
1371 |
| - $select.items = items; |
1372 |
| - }); |
1373 |
| - } |
1374 |
| - }); |
1375 |
| - function _findCaseInsensitiveDupe(arr) { |
1376 |
| - if ( arr === undefined || $select.search === undefined ) { |
1377 |
| - return false; |
1378 |
| - } |
1379 |
| - var hasDupe = arr.filter( function (origItem) { |
1380 |
| - if ( $select.search.toUpperCase() === undefined || origItem === undefined ) { |
1381 |
| - return false; |
1382 |
| - } |
1383 |
| - return origItem.toUpperCase() === $select.search.toUpperCase(); |
1384 |
| - }).length > 0; |
1385 |
| - |
1386 |
| - return hasDupe; |
1387 |
| - } |
1388 |
| - function _findApproxDupe(haystack, needle) { |
1389 |
| - var dupeIndex = -1; |
1390 |
| - if(angular.isArray(haystack)) { |
1391 |
| - var tempArr = angular.copy(haystack); |
1392 |
| - for (var i = 0; i <tempArr.length; i++) { |
1393 |
| - // handle the simple string version of tagging |
1394 |
| - if ( $select.tagging.fct === undefined ) { |
1395 |
| - // search the array for the match |
1396 |
| - if ( tempArr[i]+' '+$select.taggingLabel === needle ) { |
1397 |
| - dupeIndex = i; |
1398 |
| - } |
1399 |
| - // handle the object tagging implementation |
1400 |
| - } else { |
1401 |
| - var mockObj = tempArr[i]; |
1402 |
| - mockObj.isTag = true; |
1403 |
| - if ( angular.equals(mockObj, needle) ) { |
1404 |
| - dupeIndex = i; |
1405 |
| - } |
1406 |
| - } |
1407 |
| - } |
1408 |
| - } |
1409 |
| - return dupeIndex; |
1410 |
| - } |
1411 |
| - |
1412 | 1415 | $select.searchInput.on('blur', function() {
|
1413 | 1416 | $timeout(function() {
|
1414 | 1417 | $selectMultiple.activeMatchIndex = -1;
|
|
0 commit comments