diff --git a/dist/select.css b/dist/select.css index 43216a153..e98302d0c 100644 --- a/dist/select.css +++ b/dist/select.css @@ -1,7 +1,7 @@ /*! * ui-select * http://github.com/angular-ui/ui-select - * Version: 0.7.0 - 2014-09-09T01:02:43.612Z + * Version: 0.7.0 - 2014-10-06T12:29:59.832Z * License: MIT */ @@ -144,6 +144,13 @@ background-color: #428bca; } +.ui-select-bootstrap .ui-select-choices-row.disabled>a, +.ui-select-bootstrap .ui-select-choices-row.active.disabled>a { + color: #777; + cursor: not-allowed; + background-color: #fff; +} + /* fix hide/show angular animation */ .ui-select-match.ng-hide-add, .ui-select-search.ng-hide-add { diff --git a/dist/select.min.css b/dist/select.css.min.css similarity index 84% rename from dist/select.min.css rename to dist/select.css.min.css index 8b0c793e2..181465e97 100644 --- a/dist/select.min.css +++ b/dist/select.css.min.css @@ -1,6 +1,6 @@ /*! * ui-select * http://github.com/angular-ui/ui-select - * Version: 0.7.0 - 2014-09-09T01:02:43.612Z + * Version: 0.7.0 - 2014-10-06T12:29:59.832Z * License: MIT - */.ui-select-highlight{font-weight:700}.ui-select-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.ng-dirty.ng-invalid>a.select2-choice{border-color:#D44950}.select2-result-single{padding-left:0}.selectize-input.selectize-focus{border-color:#007FBB!important}.selectize-control>.selectize-dropdown,.selectize-control>.selectize-input>input{width:100%}.ng-dirty.ng-invalid>div.selectize-input{border-color:#D44950}.btn-default-focus{color:#333;background-color:#EBEBEB;border-color:#ADADAD;text-decoration:none;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.input-group>.ui-select-bootstrap.dropdown{position:static}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control{border-radius:4px 0 0 4px}.ui-select-bootstrap>.ui-select-match{text-align:left}.ui-select-bootstrap>.ui-select-match>.caret{position:absolute;top:45%;right:15px}.ui-select-bootstrap>.ui-select-choices{width:100%;height:auto;max-height:200px;overflow-x:hidden}.ui-select-multiple.ui-select-bootstrap{height:auto;padding:.3em}.ui-select-multiple.ui-select-bootstrap input.ui-select-search{background-color:transparent!important;border:none;outline:0;height:1.666666em}.ui-select-multiple.ui-select-bootstrap .ui-select-match .close{font-size:1.6em;line-height:.75}.ui-select-bootstrap .ui-select-choices-row>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.ui-select-bootstrap .ui-select-choices-row>a:focus,.ui-select-bootstrap .ui-select-choices-row>a:hover{text-decoration:none;color:#262626;background-color:#f5f5f5}.ui-select-bootstrap .ui-select-choices-row.active>a{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.ui-select-match.ng-hide-add,.ui-select-search.ng-hide-add{display:none!important}.ui-select-bootstrap.ng-dirty.ng-invalid>button.btn.ui-select-match{border-color:#D44950} \ No newline at end of file + */.ui-select-highlight{font-weight:700}.ui-select-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.ng-dirty.ng-invalid>a.select2-choice{border-color:#D44950}.select2-result-single{padding-left:0}.selectize-input.selectize-focus{border-color:#007FBB!important}.selectize-control>.selectize-dropdown,.selectize-control>.selectize-input>input{width:100%}.ng-dirty.ng-invalid>div.selectize-input{border-color:#D44950}.btn-default-focus{color:#333;background-color:#EBEBEB;border-color:#ADADAD;text-decoration:none;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.input-group>.ui-select-bootstrap.dropdown{position:static}.input-group>.ui-select-bootstrap>input.ui-select-search.form-control{border-radius:4px 0 0 4px}.ui-select-bootstrap>.ui-select-match{text-align:left}.ui-select-bootstrap>.ui-select-match>.caret{position:absolute;top:45%;right:15px}.ui-select-bootstrap>.ui-select-choices{width:100%;height:auto;max-height:200px;overflow-x:hidden}.ui-select-multiple.ui-select-bootstrap{height:auto;padding:.3em}.ui-select-multiple.ui-select-bootstrap input.ui-select-search{background-color:transparent!important;border:none;outline:0;height:1.666666em}.ui-select-multiple.ui-select-bootstrap .ui-select-match .close{font-size:1.6em;line-height:.75}.ui-select-bootstrap .ui-select-choices-row>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.ui-select-bootstrap .ui-select-choices-row>a:focus,.ui-select-bootstrap .ui-select-choices-row>a:hover{text-decoration:none;color:#262626;background-color:#f5f5f5}.ui-select-bootstrap .ui-select-choices-row.active>a{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.ui-select-bootstrap .ui-select-choices-row.active.disabled>a,.ui-select-bootstrap .ui-select-choices-row.disabled>a{color:#777;cursor:not-allowed;background-color:#fff}.ui-select-match.ng-hide-add,.ui-select-search.ng-hide-add{display:none!important}.ui-select-bootstrap.ng-dirty.ng-invalid>button.btn.ui-select-match{border-color:#D44950} \ No newline at end of file diff --git a/dist/select.js b/dist/select.js index ad1611186..8b9f1c3ab 100755 --- a/dist/select.js +++ b/dist/select.js @@ -1,7 +1,7 @@ /*! * ui-select * http://github.com/angular-ui/ui-select - * Version: 0.7.0 - 2014-09-09T01:02:43.608Z + * Version: 0.7.0 - 2014-10-06T12:29:59.829Z * License: MIT */ @@ -164,6 +164,7 @@ ctrl.resetSearchInput = undefined; // Initialized inside uiSelect directive link function ctrl.refreshDelay = undefined; // Initialized inside uiSelectChoices directive link function ctrl.multiple = false; // Initialized inside uiSelect directive link function + ctrl.disableChoiceExpression = undefined; // Initialized inside uiSelect directive link function ctrl.isEmpty = function() { return angular.isUndefined(ctrl.selected) || ctrl.selected === null || ctrl.selected === ''; @@ -307,24 +308,45 @@ return ctrl.items.indexOf(itemScope[ctrl.itemProperty]) === ctrl.activeIndex; }; + ctrl.isDisabled = function(itemScope) { + var itemIndex = ctrl.items.indexOf(itemScope[ctrl.itemProperty]); + var isDisabled = false; + var item; + + if (itemIndex >= 0 && !angular.isUndefined(ctrl.disableChoiceExpression)) { + item = ctrl.items[itemIndex]; + isDisabled = !!(itemScope.$eval(ctrl.disableChoiceExpression)); // force the boolean value + item._uiSelectChoiceDisabled = isDisabled; // store this for later reference + } + + return isDisabled; + }; + // When the user clicks on an item inside the dropdown ctrl.select = function(item) { - var locals = {}; - locals[ctrl.parserResult.itemName] = item; + if (!item || !item._uiSelectChoiceDisabled) { + if(ctrl.tagging.isActivated && !item && ctrl.search.length > 0) { + // create new item on the fly + item = ctrl.tagging.fct !== undefined ? ctrl.tagging.fct(ctrl.search) : ctrl.search; + } - ctrl.onSelectCallback($scope, { - $item: item, - $model: ctrl.parserResult.modelMapper($scope, locals) - }); + var locals = {}; + locals[ctrl.parserResult.itemName] = item; - if(ctrl.multiple){ - ctrl.selected.push(item); - ctrl.sizeSearchInput(); - } else { - ctrl.selected = item; + ctrl.onSelectCallback($scope, { + $item: item, + $model: ctrl.parserResult.modelMapper($scope, locals) + }); + + if(ctrl.multiple){ + ctrl.selected.push(item); + ctrl.sizeSearchInput(); + } else { + ctrl.selected = item; + } + ctrl.close(); } - ctrl.close(); }; // Closes the dropdown @@ -338,6 +360,13 @@ } }; + // Toggle dropdown + ctrl.toggle = function(e) { + if (ctrl.open) ctrl.close(); else ctrl.activate(); + e.preventDefault(); + e.stopPropagation(); + }; + // Remove item from multiple select ctrl.removeChoice = function(index){ ctrl.selected.splice(index, 1); @@ -371,7 +400,7 @@ break; case KEY.UP: if (!ctrl.open && ctrl.multiple) ctrl.activate(false, true); //In case its the search input in 'multiple' mode - else if (ctrl.activeIndex > 0) { ctrl.activeIndex--; } + else if (ctrl.activeIndex > 0 || (ctrl.search.length === 0 && ctrl.tagging.isActivated)) { ctrl.activeIndex--; } break; case KEY.TAB: //TODO: Que hacemos en modo multiple? @@ -470,7 +499,7 @@ processed = _handleMatchSelection(key); } - if (!processed && ctrl.items.length > 0) { + if (!processed && (ctrl.items.length > 0 || ctrl.tagging.isActivated)) { processed = _handleDropDownSelection(key); } @@ -550,6 +579,8 @@ var $select = ctrls[0]; var ngModel = ctrls[1]; + var searchInput = element.querySelectorAll('input.ui-select-search'); + $select.multiple = angular.isDefined(attrs.multiple); $select.onSelectCallback = $parse(attrs.onSelect); @@ -625,6 +656,21 @@ //Idea from: https://github.com/ivaynberg/select2/blob/79b5bf6db918d7560bdd959109b7bcfb47edaf43/select2.js#L1954 var focusser = angular.element(""); + + if(attrs.tabindex){ + //tabindex might be an expression, wait until it contains the actual value before we set the focusser tabindex + attrs.$observe('tabindex', function(value) { + //If we are using multiple, add tabindex to the search input + if($select.multiple){ + searchInput.attr("tabindex", value); + } else { + focusser.attr("tabindex", value); + } + //Remove the tabindex on the parent so that it is not focusable + element.removeAttr("tabindex"); + }); + } + $compile(focusser)(scope); $select.focusser = focusser; @@ -695,6 +741,19 @@ $select.resetSearchInput = resetSearchInput !== undefined ? resetSearchInput : true; }); + attrs.$observe('tagging', function() { + if(attrs.tagging !== undefined) + { + // $eval() is needed otherwise we get a string instead of a function or a boolean + var taggingEval = scope.$eval(attrs.tagging); + $select.tagging = {isActivated: true, fct: taggingEval !== true ? taggingEval : undefined}; + } + else + { + $select.tagging = {isActivated: false, fct: undefined}; + } + }); + if ($select.multiple){ scope.$watchCollection('$select.selected', function(newValue) { //On v1.2.19 the 2nd and 3rd parameteres are ignored @@ -802,6 +861,8 @@ $select.parseRepeatAttr(attrs.repeat, groupByExp); //Result ready at $select.parserResult + $select.disableChoiceExpression = attrs.uiDisableChoice; + if(groupByExp) { var groups = element.querySelectorAll('.ui-select-choices-group'); if (groups.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-group but got '{0}'.", groups.length); @@ -825,7 +886,7 @@ scope.$watch('$select.search', function(newValue) { if(newValue && !$select.open && $select.multiple) $select.activate(false, true); - $select.activeIndex = 0; + $select.activeIndex = $select.tagging.isActivated ? -1 : 0; $select.refresh(attrs.refresh); }); @@ -890,16 +951,16 @@ }); }()); -angular.module("ui.select").run(["$templateCache", function($templateCache) {$templateCache.put("bootstrap/choices.tpl.html","