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

Commit 2eaf5aa

Browse files
author
Brian Feister
committed
Merge branch 'master' into tagging-support
Conflicts: dist/select.js src/select.js
2 parents 0d2399e + d24f9bf commit 2eaf5aa

File tree

14 files changed

+333
-104
lines changed

14 files changed

+333
-104
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ AngularJS-native version of [Select2](http://ivaynberg.github.io/select2/) and [
44

55
- [Demo](http://plnkr.co/edit/a3KlK8dKH3wwiiksDSn2?p=preview)
66
- [Demo Multiselect](http://plnkr.co/edit/juqoNOt1z1Gb349XabQ2?p=preview)
7-
- [Bootstrap theme](http://plnkr.co/edit/QCwSM75ilH2Vh6D9aMA4?p=preview)
87

98
Check [examples](https://github.com/angular-ui/ui-select/blob/master/examples).
109

bower.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ui-select",
3-
"version": "0.7.0",
3+
"version": "0.8.3",
44
"homepage": "https://github.com/angular-ui/ui-select",
55
"authors": [
66
"AngularUI"
@@ -13,14 +13,17 @@
1313
"node_modules",
1414
"bower_components",
1515
"src",
16-
"test"
16+
"test",
17+
"gulpfile.js",
18+
"karma.conf.js",
19+
"examples"
1720
],
1821
"dependencies": {
19-
"angular": "~1.2"
22+
"angular": ">=1.2.18"
2023
},
2124
"devDependencies": {
2225
"jquery": "~1.11",
23-
"angular-sanitize": "~1.2",
24-
"angular-mocks": "~1.2"
26+
"angular-sanitize": ">=1.2.18",
27+
"angular-mocks": ">=1.2.18"
2528
}
2629
}

dist/select.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
* ui-select
33
* http://github.com/angular-ui/ui-select
4-
* Version: 0.7.0 - 2014-10-06T12:29:59.832Z
4+
* Version: 0.8.3 - 2014-10-14T18:22:05.435Z
55
* License: MIT
66
*/
77

@@ -121,6 +121,10 @@
121121
line-height: 0.75;
122122
}
123123

124+
.ui-select-multiple.ui-select-bootstrap .ui-select-match-item{
125+
outline: 0;
126+
}
127+
124128
.ui-select-bootstrap .ui-select-choices-row>a {
125129
display: block;
126130
padding: 3px 20px;

dist/select.css.min.css

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/select.js

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
* ui-select
33
* http://github.com/angular-ui/ui-select
4-
* Version: 0.7.0 - 2014-10-06T12:29:59.829Z
4+
* Version: 0.8.3 - 2014-10-14T18:22:05.432Z
55
* License: MIT
66
*/
77

@@ -27,9 +27,11 @@
2727
END: 35,
2828
BACKSPACE: 8,
2929
DELETE: 46,
30+
COMMAND: 91,
3031
isControl: function (e) {
3132
var k = e.which;
3233
switch (k) {
34+
case KEY.COMMAND:
3335
case KEY.SHIFT:
3436
case KEY.CTRL:
3537
case KEY.ALT:
@@ -190,6 +192,7 @@
190192
ctrl.activate = function(initSearchValue, avoidReset) {
191193
if (!ctrl.disabled && !ctrl.open) {
192194
if(!avoidReset) _resetSearchInput();
195+
ctrl.focusser.prop('disabled', true); //Will reactivate it on .close()
193196
ctrl.open = true;
194197
ctrl.activeMatchIndex = -1;
195198

@@ -269,10 +272,14 @@
269272
if (ctrl.multiple){
270273
//Remove already selected items
271274
$scope.$watchCollection('$select.selected', function(selectedItems){
272-
if (!selectedItems) return;
273275
var data = ctrl.parserResult.source($scope);
274-
var filteredItems = data.filter(function(i) {return selectedItems.indexOf(i) < 0;});
275-
setItemsFn(filteredItems);
276+
if (!selectedItems.length) {
277+
setItemsFn(data);
278+
}else{
279+
var filteredItems = data.filter(function(i) {return selectedItems.indexOf(i) < 0;});
280+
setItemsFn(filteredItems);
281+
}
282+
ctrl.sizeSearchInput();
276283
});
277284
}
278285

@@ -305,12 +312,19 @@
305312
};
306313

307314
ctrl.isActive = function(itemScope) {
315+
<<<<<<< HEAD
308316
if ( typeof itemScope[ctrl.itemProperty] === 'undefined') {
309317
return false;
310318
}
319+
=======
320+
return ctrl.open && ctrl.items.indexOf(itemScope[ctrl.itemProperty]) === ctrl.activeIndex;
321+
>>>>>>> master
311322
};
312323

313324
ctrl.isDisabled = function(itemScope) {
325+
326+
if (!ctrl.open) return;
327+
314328
var itemIndex = ctrl.items.indexOf(itemScope[ctrl.itemProperty]);
315329
var isDisabled = false;
316330
var item;
@@ -325,14 +339,9 @@
325339
};
326340

327341
// When the user clicks on an item inside the dropdown
328-
ctrl.select = function(item) {
329-
330-
if (!item || !item._uiSelectChoiceDisabled) {
331-
if(ctrl.tagging.isActivated && !item && ctrl.search.length > 0) {
332-
// create new item on the fly
333-
item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search;
334-
}
342+
ctrl.select = function(item, skipFocusser) {
335343

344+
if (item === undefined || !item._uiSelectChoiceDisabled) {
336345
var locals = {};
337346
locals[ctrl.parserResult.itemName] = item;
338347

@@ -347,17 +356,19 @@
347356
} else {
348357
ctrl.selected = item;
349358
}
350-
ctrl.close();
359+
ctrl.close(skipFocusser);
351360
}
352361
};
353362

354363
// Closes the dropdown
355-
ctrl.close = function() {
356-
if (ctrl.open) {
357-
_resetSearchInput();
358-
ctrl.open = false;
364+
ctrl.close = function(skipFocusser) {
365+
if (!ctrl.open) return;
366+
_resetSearchInput();
367+
ctrl.open = false;
368+
if (!ctrl.multiple){
359369
$timeout(function(){
360-
ctrl.focusser[0].focus();
370+
ctrl.focusser.prop('disabled', false);
371+
if (!skipFocusser) ctrl.focusser[0].focus();
361372
},0,false);
362373
}
363374
};
@@ -371,9 +382,18 @@
371382

372383
// Remove item from multiple select
373384
ctrl.removeChoice = function(index){
385+
var removedChoice = ctrl.selected[index];
386+
var locals = {};
387+
locals[ctrl.parserResult.itemName] = removedChoice;
388+
374389
ctrl.selected.splice(index, 1);
375390
ctrl.activeMatchIndex = -1;
376391
ctrl.sizeSearchInput();
392+
393+
ctrl.onRemoveCallback($scope, {
394+
$item: removedChoice,
395+
$model: ctrl.parserResult.modelMapper($scope, locals)
396+
});
377397
};
378398

379399
ctrl.getPlaceholder = function(){
@@ -382,14 +402,28 @@
382402
return ctrl.placeholder;
383403
};
384404

405+
var containerSizeWatch;
385406
ctrl.sizeSearchInput = function(){
386407
var input = _searchInput[0],
387408
container = _searchInput.parent().parent()[0];
388409
_searchInput.css('width','10px');
389-
$timeout(function(){
410+
var calculate = function(){
390411
var newWidth = container.clientWidth - input.offsetLeft - 10;
391412
if(newWidth < 50) newWidth = container.clientWidth;
392413
_searchInput.css('width',newWidth+'px');
414+
};
415+
$timeout(function(){ //Give tags time to render correctly
416+
if (container.clientWidth === 0 && !containerSizeWatch){
417+
containerSizeWatch = $scope.$watch(function(){ return container.clientWidth;}, function(newValue){
418+
if (newValue !== 0){
419+
calculate();
420+
containerSizeWatch();
421+
containerSizeWatch = null;
422+
}
423+
});
424+
}else if (!containerSizeWatch) {
425+
calculate();
426+
}
393427
}, 0, false);
394428
};
395429

@@ -402,11 +436,10 @@
402436
break;
403437
case KEY.UP:
404438
if (!ctrl.open && ctrl.multiple) ctrl.activate(false, true); //In case its the search input in 'multiple' mode
405-
else if (ctrl.activeIndex > 0 || (ctrl.search.length === 0 && ctrl.tagging.isActivated)) { ctrl.activeIndex--; }
439+
else if (ctrl.activeIndex > 0) { ctrl.activeIndex--; }
406440
break;
407441
case KEY.TAB:
408-
//TODO: Que hacemos en modo multiple?
409-
if (!ctrl.multiple) ctrl.select(ctrl.items[ctrl.activeIndex]);
442+
if (!ctrl.multiple || ctrl.open) ctrl.select(ctrl.items[ctrl.activeIndex], true);
410443
break;
411444
case KEY.ENTER:
412445
if(ctrl.open){
@@ -500,8 +533,8 @@
500533
if(ctrl.multiple && KEY.isHorizontalMovement(key)){
501534
processed = _handleMatchSelection(key);
502535
}
503-
504-
if (!processed && (ctrl.items.length > 0 || ctrl.tagging.isActivated)) {
536+
537+
if (!processed && ctrl.items.length > 0) {
505538
processed = _handleDropDownSelection(key);
506539
}
507540

@@ -522,7 +555,6 @@
522555
_searchInput.on('blur', function() {
523556
$timeout(function() {
524557
ctrl.activeMatchIndex = -1;
525-
ctrl.activeIndex = 0;
526558
});
527559
});
528560

@@ -583,19 +615,20 @@
583615

584616
var searchInput = element.querySelectorAll('input.ui-select-search');
585617

586-
$select.multiple = angular.isDefined(attrs.multiple);
618+
$select.multiple = (angular.isDefined(attrs.multiple)) ? (attrs.multiple === '') ? true : (attrs.multiple.toLowerCase() === 'true') : false;
587619

588620
$select.onSelectCallback = $parse(attrs.onSelect);
621+
$select.onRemoveCallback = $parse(attrs.onRemove);
589622

590623
//From view --> model
591624
ngModel.$parsers.unshift(function (inputValue) {
592625
var locals = {},
593626
result;
594627
if ($select.multiple){
595628
var resultMultiple = [];
596-
for (var j = inputValue.length - 1; j >= 0; j--) {
629+
for (var j = $select.selected.length - 1; j >= 0; j--) {
597630
locals = {};
598-
locals[$select.parserResult.itemName] = inputValue[j];
631+
locals[$select.parserResult.itemName] = $select.selected[j];
599632
result = $select.parserResult.modelMapper(scope, locals);
600633
resultMultiple.unshift(result);
601634
}
@@ -695,7 +728,7 @@
695728
e.preventDefault();
696729
e.stopPropagation();
697730
$select.select(undefined);
698-
scope.$digest();
731+
scope.$apply();
699732
return;
700733
}
701734

@@ -743,24 +776,13 @@
743776
$select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true;
744777
});
745778

746-
attrs.$observe('tagging', function() {
747-
if(attrs.tagging !== undefined)
748-
{
749-
// $eval() is needed otherwise we get a string instead of a function or a boolean
750-
var taggingEval = scope.$eval(attrs.tagging);
751-
$select.tagging = {isActivated: true, fct: taggingEval !== true ? taggingEval : undefined};
752-
}
753-
else
754-
{
755-
$select.tagging = {isActivated: false, fct: undefined};
756-
}
757-
});
758-
759779
if ($select.multiple){
760-
scope.$watchCollection('$select.selected', function(newValue) {
761-
//On v1.2.19 the 2nd and 3rd parameteres are ignored
762-
//On v1.3.0-beta+ 3rd parameter (revalidate) is true, to force $parsers to recreate model
763-
ngModel.$setViewValue(newValue, null, true);
780+
scope.$watchCollection(function(){ return ngModel.$modelValue; }, function(newValue, oldValue) {
781+
if (oldValue != newValue)
782+
ngModel.$modelValue = null; //Force scope model value and ngModel value to be out of sync to re-run formatters
783+
});
784+
scope.$watchCollection('$select.selected', function() {
785+
ngModel.$setViewValue(Date.now()); //Set timestamp as a unique string to force changes
764786
});
765787
focusser.prop('disabled', true); //Focusser isn't needed if multiple
766788
}else{
@@ -888,7 +910,7 @@
888910

889911
scope.$watch('$select.search', function(newValue) {
890912
if(newValue && !$select.open && $select.multiple) $select.activate(false, true);
891-
$select.activeIndex = $select.tagging.isActivated ? -1 : 0;
913+
$select.activeIndex = 0;
892914
$select.refresh(attrs.refresh);
893915
});
894916

@@ -929,7 +951,7 @@
929951
});
930952

931953
if($select.multiple){
932-
$select.sizeSearchInput();
954+
$select.sizeSearchInput();
933955
}
934956

935957
}
@@ -954,7 +976,7 @@
954976
}());
955977

956978
angular.module("ui.select").run(["$templateCache", function($templateCache) {$templateCache.put("bootstrap/choices.tpl.html","<ul class=\"ui-select-choices ui-select-choices-content dropdown-menu\" role=\"menu\" aria-labelledby=\"dLabel\" ng-show=\"$select.items.length > 0\"><li class=\"ui-select-choices-group\"><div class=\"divider\" ng-show=\"$select.isGrouped && $index > 0\"></div><div ng-show=\"$select.isGrouped\" class=\"ui-select-choices-group-label dropdown-header\">{{$group.name}}</div><div class=\"ui-select-choices-row\" ng-class=\"{active: $select.isActive(this), disabled: $select.isDisabled(this)}\"><a href=\"javascript:void(0)\" class=\"ui-select-choices-row-inner\"></a></div></li></ul>");
957-
$templateCache.put("bootstrap/match-multiple.tpl.html","<span class=\"ui-select-match\"><span ng-repeat=\"$item in $select.selected\"><button style=\"margin-right: 3px;\" class=\"ui-select-match-item btn btn-default btn-xs\" tabindex=\"-1\" type=\"button\" ng-disabled=\"$select.disabled\" ng-click=\"$select.activeMatchIndex = $index;\" ng-class=\"{\'btn-primary\':$select.activeMatchIndex === $index}\"><span class=\"close ui-select-match-close\" ng-hide=\"$select.disabled\" ng-click=\"$select.removeChoice($index)\">&nbsp;&times;</span> <span uis-transclude-append=\"\"></span></button></span></span>");
979+
$templateCache.put("bootstrap/match-multiple.tpl.html","<span class=\"ui-select-match\"><span ng-repeat=\"$item in $select.selected\"><span style=\"margin-right: 3px;\" class=\"ui-select-match-item btn btn-default btn-xs\" tabindex=\"-1\" type=\"button\" ng-disabled=\"$select.disabled\" ng-click=\"$select.activeMatchIndex = $index;\" ng-class=\"{\'btn-primary\':$select.activeMatchIndex === $index}\"><span class=\"close ui-select-match-close\" ng-hide=\"$select.disabled\" ng-click=\"$select.removeChoice($index)\">&nbsp;&times;</span> <span uis-transclude-append=\"\"></span></span></span></span>");
958980
$templateCache.put("bootstrap/match.tpl.html","<button type=\"button\" class=\"btn btn-default form-control ui-select-match\" tabindex=\"-1\" ng-hide=\"$select.open\" ng-disabled=\"$select.disabled\" ng-class=\"{\'btn-default-focus\':$select.focus}\" ;=\"\" ng-click=\"$select.activate()\"><span ng-show=\"$select.searchEnabled && $select.isEmpty()\" class=\"text-muted\">{{$select.placeholder}}</span> <span ng-hide=\"$select.isEmpty()\" ng-transclude=\"\"></span> <span class=\"caret ui-select-toggle\" ng-click=\"$select.toggle($event)\"></span></button>");
959981
$templateCache.put("bootstrap/select-multiple.tpl.html","<div class=\"ui-select-multiple ui-select-bootstrap dropdown form-control\" ng-class=\"{open: $select.open}\"><div><div class=\"ui-select-match\"></div><input type=\"text\" autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\" spellcheck=\"false\" class=\"ui-select-search input-xs\" placeholder=\"{{$select.getPlaceholder()}}\" ng-disabled=\"$select.disabled\" ng-hide=\"$select.disabled\" ng-click=\"$select.activate()\" ng-model=\"$select.search\"></div><div class=\"ui-select-choices\"></div></div>");
960982
$templateCache.put("bootstrap/select.tpl.html","<div class=\"ui-select-bootstrap dropdown\" ng-class=\"{open: $select.open}\"><div class=\"ui-select-match\"></div><input type=\"text\" autocomplete=\"off\" tabindex=\"-1\" class=\"form-control ui-select-search\" placeholder=\"{{$select.placeholder}}\" ng-model=\"$select.search\" ng-show=\"$select.searchEnabled && $select.open\"><div class=\"ui-select-choices\"></div></div>");

dist/select.js.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/select.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)