Skip to content

Commit 5ca372a

Browse files
committed
disable opacity set to zero cause of flickering when typing in ddl see (angular-ui#1298)
remove opacity change in dist fix lost focus (on backspace or adding new tag) when append-to-body is used fixing bug - when typing a letter that exists in one of the items in the ddl and then deleting it causes the (tag new item) to persists fix bug: when using closeOnSelect with tagging - hitting the enter key sets the new tag but keeps the search input value tagging: --making sure no empty elements gets in on paste operation --fix dupes search added isNewTagDuplication optional user method to check if new tag (when using tagging where each tag is an object) already exists in the list adding safety check that the control is still open cause _ensureHighlightVisible is called using a timeout adding public to gitignore ignoring public folder fix tagging: when using 'tagging' (add tags on the fly) with refreshDelay, the keyup event fires before or after the 'refresh' (attr) method. added a fix to implement the refresh-delay for the keyup event as well making sure new tag (tag added on the fly) is removed when already exists in the list of tags fix bug when filtering reverting back list folder (before fork state)
1 parent 4467b82 commit 5ca372a

File tree

6 files changed

+182
-116
lines changed

6 files changed

+182
-116
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/.idea
44
/.tmp
55
.DS_Store
6+
public

dist/select.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88

9-
(function () {
9+
(function () {
1010
"use strict";
1111

1212
var KEY = {
@@ -284,7 +284,7 @@ uis.controller('uiSelectCtrl',
284284
if (ctrl.searchInput.length !== 1) {
285285
throw uiSelectMinErr('searchInput', "Expected 1 input.ui-select-search but got '{0}'.", ctrl.searchInput.length);
286286
}
287-
287+
288288
ctrl.isEmpty = function() {
289289
return angular.isUndefined(ctrl.selected) || ctrl.selected === null || ctrl.selected === '';
290290
};
@@ -388,7 +388,7 @@ uis.controller('uiSelectCtrl',
388388
//If collection is an Object, convert it to Array
389389

390390
var originalSource = ctrl.parserResult.source;
391-
391+
392392
//When an object is used as source, we better create an array and use it as 'source'
393393
var createArrayFromObject = function(){
394394
var origSrc = originalSource($scope);
@@ -434,7 +434,7 @@ uis.controller('uiSelectCtrl',
434434
ctrl.items = [];
435435
} else {
436436
if (!angular.isArray(items)) {
437-
throw uiSelectMinErr('items', "Expected an array but got '{0}'.", items);
437+
throw uiSelectMinErr('items', "Expected an array but got '{0}'.", items);
438438
} else {
439439
//Remove already selected items (ex: while searching)
440440
//TODO Should add a test
@@ -1181,7 +1181,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
11811181
$select = $scope.$select,
11821182
ngModel;
11831183

1184-
//Wait for link fn to inject it
1184+
//Wait for link fn to inject it
11851185
$scope.$evalAsync(function(){ ngModel = $scope.ngModel; });
11861186

11871187
ctrl.activeMatchIndex = -1;
@@ -1193,7 +1193,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
11931193

11941194
ctrl.refreshComponent = function(){
11951195
//Remove already selected items
1196-
//e.g. When user clicks on a selection, the selected array changes and
1196+
//e.g. When user clicks on a selection, the selected array changes and
11971197
//the dropdown should remove that item
11981198
$select.refreshItems();
11991199
$select.sizeSearchInput();
@@ -1292,7 +1292,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
12921292
};
12931293
if (!inputValue) return resultMultiple; //If ngModel was undefined
12941294
for (var k = inputValue.length - 1; k >= 0; k--) {
1295-
//Check model array of currently selected items
1295+
//Check model array of currently selected items
12961296
if (!checkFnMultiple($select.selected, inputValue[k])){
12971297
//Check model array of all items available
12981298
if (!checkFnMultiple(data, inputValue[k])){
@@ -1303,8 +1303,8 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec
13031303
}
13041304
return resultMultiple;
13051305
});
1306-
1307-
//Watch for external model changes
1306+
1307+
//Watch for external model changes
13081308
scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {
13091309
if (oldValue != newValue){
13101310
ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters
@@ -1865,7 +1865,7 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE
18651865

18661866
// if (isObjectCollection){
18671867
//00000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000556666660000077777777777755000000000000000000000088888880000000
1868-
match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(([\w\.]+)?\s*(|\s*[\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
1868+
match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(([\w\.]+)?\s*(|\s*[\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
18691869

18701870
// 1 Alias
18711871
// 2 Item
@@ -1899,7 +1899,7 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE
18991899
expression += ' track by ' + this.trackByExp;
19001900
}
19011901
return expression;
1902-
}
1902+
}
19031903
};
19041904

19051905
};

src/uiSelectController.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,17 @@ uis.controller('uiSelectCtrl',
220220
// Debounce
221221
// See https://github.com/angular-ui/bootstrap/blob/0.10.0/src/typeahead/typeahead.js#L155
222222
// FYI AngularStrap typeahead does not have debouncing: https://github.com/mgcrea/angular-strap/blob/v2.0.0-rc.4/src/typeahead/typeahead.js#L177
223-
if (_refreshDelayPromise) {
224-
$timeout.cancel(_refreshDelayPromise);
223+
if (ctrl.refreshDelay > 0) {
224+
if (_refreshDelayPromise) {
225+
$timeout.cancel(_refreshDelayPromise);
226+
}
227+
_refreshDelayPromise = $timeout(function () {
228+
$scope.$eval(refreshAttr);
229+
}, ctrl.refreshDelay);
225230
}
226-
_refreshDelayPromise = $timeout(function() {
231+
else {
227232
$scope.$eval(refreshAttr);
228-
}, ctrl.refreshDelay);
233+
}
229234
}
230235
};
231236

@@ -305,7 +310,12 @@ uis.controller('uiSelectCtrl',
305310
}
306311
}
307312
// search ctrl.selected for dupes potentially caused by tagging and return early if found
308-
if ( ctrl.selected && angular.isArray(ctrl.selected) && ctrl.selected.filter( function (selection) { return angular.equals(selection, item); }).length > 0 ) {
313+
if (ctrl.selected && angular.isArray(ctrl.selected) && ctrl.selected.filter(function (selection) {
314+
return ctrl.isNewTagDuplication !== angular.noop ? ctrl.isNewTagDuplication($scope, {
315+
newItem: item,
316+
existingItem: angular.copy(selection)
317+
}) : angular.equals(angular.copy(selection), item);
318+
}).length > 0) {
309319
ctrl.close(skipFocusser);
310320
return;
311321
}
@@ -326,6 +336,9 @@ uis.controller('uiSelectCtrl',
326336
if (ctrl.closeOnSelect) {
327337
ctrl.close(skipFocusser);
328338
}
339+
else {
340+
_resetSearchInput();
341+
}
329342
if ($event && $event.type === 'click') {
330343
ctrl.clickTriggeredSelect = true;
331344
}
@@ -496,6 +509,7 @@ uis.controller('uiSelectCtrl',
496509
var data = e.originalEvent.clipboardData.getData('text/plain');
497510
if (data && data.length > 0 && ctrl.taggingTokens.isActivated && ctrl.tagging.fct) {
498511
var items = data.split(ctrl.taggingTokens.tokens[0]); // split by first token only
512+
items = items.filter(Boolean);
499513
if (items && items.length > 0) {
500514
angular.forEach(items, function (item) {
501515
var newItem = ctrl.tagging.fct(item);
@@ -517,6 +531,9 @@ uis.controller('uiSelectCtrl',
517531

518532
// See https://github.com/ivaynberg/select2/blob/3.4.6/select2.js#L1431
519533
function _ensureHighlightVisible() {
534+
if (!ctrl.open) {
535+
return;
536+
}
520537
var container = $element.querySelectorAll('.ui-select-choices-content');
521538
var choices = container.querySelectorAll('.ui-select-choices-row');
522539
if (choices.length < 1) {

src/uiSelectDirective.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ uis.directive('uiSelect',
4646

4747
$select.onSelectCallback = $parse(attrs.onSelect);
4848
$select.onRemoveCallback = $parse(attrs.onRemove);
49+
$select.isNewTagDuplication = $parse(attrs.isNewTagDuplication);
4950

5051
//Limit the number of selections allowed
5152
$select.limit = (angular.isDefined(attrs.limit)) ? parseInt(attrs.limit, 10) : undefined;
@@ -253,6 +254,8 @@ uis.directive('uiSelect',
253254
element[0].style.left = '';
254255
element[0].style.top = '';
255256
element[0].style.width = originalWidth;
257+
258+
$select.setFocus();
256259
}
257260

258261
// Hold on to a reference to the .ui-select-dropdown element for direction support.
@@ -300,7 +303,7 @@ uis.directive('uiSelect',
300303
}
301304

302305
// Hide the dropdown so there is no flicker until $timeout is done executing.
303-
dropdown[0].style.opacity = 0;
306+
//dropdown[0].style.opacity = 0;
304307

305308
// Delay positioning the dropdown until all choices have been added so its height is correct.
306309
$timeout(function(){

0 commit comments

Comments
 (0)