diff --git a/src/bootstrap/choices.tpl.html b/src/bootstrap/choices.tpl.html index c3f78e2e7..6cf3185db 100644 --- a/src/bootstrap/choices.tpl.html +++ b/src/bootstrap/choices.tpl.html @@ -5,7 +5,7 @@
- +
diff --git a/src/bootstrap/match-multiple.tpl.html b/src/bootstrap/match-multiple.tpl.html index be9e92da7..7dd272435 100644 --- a/src/bootstrap/match-multiple.tpl.html +++ b/src/bootstrap/match-multiple.tpl.html @@ -1,12 +1,13 @@  × diff --git a/src/bootstrap/match.tpl.html b/src/bootstrap/match.tpl.html index 1dc23cd98..8267113a1 100644 --- a/src/bootstrap/match.tpl.html +++ b/src/bootstrap/match.tpl.html @@ -1,6 +1,8 @@
    -
  • +
diff --git a/src/select2/match-multiple.tpl.html b/src/select2/match-multiple.tpl.html index 8a9dd85b1..ae6c64696 100644 --- a/src/select2/match-multiple.tpl.html +++ b/src/select2/match-multiple.tpl.html @@ -5,8 +5,8 @@ -->
  • + ng-class="$select.matchClass(this, $index, {'select2-search-choice-focus':$selectMultiple.activeMatchIndex === $index, 'select2-locked':$select.isLocked(this, $index)})" + ng-style="$select.matchStyle(this, $index)" ui-select-sort="$select.selected">
  • diff --git a/src/select2/match.tpl.html b/src/select2/match.tpl.html index 826fec056..0ccbe713f 100644 --- a/src/select2/match.tpl.html +++ b/src/select2/match.tpl.html @@ -4,7 +4,8 @@ do not work: [class^="select2-choice"] --> {{$select.placeholder}} diff --git a/src/selectize/choices.tpl.html b/src/selectize/choices.tpl.html index 6c193a7c6..eeaf68adb 100644 --- a/src/selectize/choices.tpl.html +++ b/src/selectize/choices.tpl.html @@ -3,7 +3,8 @@
    -
    +
    diff --git a/src/selectize/match-multiple.tpl.html b/src/selectize/match-multiple.tpl.html index 49d37b2d7..6be054c0b 100644 --- a/src/selectize/match-multiple.tpl.html +++ b/src/selectize/match-multiple.tpl.html @@ -1,7 +1,8 @@
    diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index bbe8c88c3..ae208c355 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -59,6 +59,8 @@ uis.directive('uiSelectChoices', $select.onHighlightCallback = attrs.onHighlight; $select.minimumInputLength = parseInt(attrs.minimumInputLength) || 0; $select.dropdownPosition = attrs.position ? attrs.position.toLowerCase() : uiSelectConfig.dropdownPosition; + $select.choiceClassExpression = attrs.uiChoiceClass; + $select.choiceStyleExpression = attrs.uiChoiceStyle; scope.$watch('$select.search', function(newValue) { if(newValue && !$select.open && $select.multiple) $select.activate(false, true); diff --git a/src/uiSelectController.js b/src/uiSelectController.js index 0d1c595eb..119cae920 100644 --- a/src/uiSelectController.js +++ b/src/uiSelectController.js @@ -42,6 +42,10 @@ uis.controller('uiSelectCtrl', ctrl.tagging = {isActivated: false, fct: undefined}; ctrl.taggingTokens = {isActivated: false, tokens: undefined}; ctrl.lockChoiceExpression = undefined; // Initialized inside uiSelectMatch directive link function + ctrl.matchClassExpression = undefined; // Initialized inside uiSelectMatch directive link function + ctrl.matchStyleExpression = undefined; // Initialized inside uiSelectMatch directive link function + ctrl.choiceClassExpression = undefined; // Initialized inside uiSelectChoices directive link function + ctrl.choiceStyleExpression = undefined; // Initialized inside uiSelectChoices directive link function ctrl.clickTriggeredSelect = false; ctrl.$filter = $filter; ctrl.$element = $element; @@ -519,6 +523,107 @@ uis.controller('uiSelectCtrl', }; } + // Inspired from anguar.js arrayClasses + // Turns a ng-class style argument into a array of string, + // and fill noClass with the classes given in ``{className: false}`` + function arrayClasses(classVal, noClass) { + var classes = []; + if (Array.isArray(classVal)) { + classVal.forEach(function(v) { + classes = classes.concat(arrayClasses(v, noClass)); + }); + } else if (typeof classVal === 'string') { + return classVal.split(' '); + } else if (typeof classVal === 'object') { + for(var k in classVal) { + if (classVal[k]) { + classes = classes.concat(k.split(' ')); + } else { + /*jshint loopfunc: true */ + k.split(' ').forEach(function(c){ + noClass[c] = true; + }); + } + } + } + return classes; + } + + // Gives the ng-class argument for + ctrl.matchClass = function(itemScope, itemIndex, deflt) { + deflt = deflt || {}; + if(!ctrl.matchClassExpression) return deflt; + // create a context with a $match object (if itemIndex is given) + var context = {}; + if(typeof itemIndex === 'number'){ + context.$match = { + active: itemScope.$selectMultiple.activeMatchIndex == itemIndex, + locked: ctrl.isLocked(itemScope, itemIndex), + }; + } + // evaluate ui-match-class attribute + var classes = itemScope.$eval(ctrl.matchClassExpression, context) || {}; + // all this code is used to disable default classes when recieved in ``{className: false}`` + // if it is overkill, a simple ``return [classes, deflt];`` makes the job + if(!deflt) return classes; + var noClass = {}; + classes = arrayClasses(classes, noClass); + arrayClasses(deflt, {}).forEach(function(c){ + if(!noClass[c]) classes.push(c); + }); + return classes; + }; + + // Gives the ng-style argument for + ctrl.matchStyle = function(itemScope, itemIndex) { + if(!ctrl.matchStyleExpression) return {}; + // create a context with a $match object (if itemIndex is given) + var context = {}; + if(typeof itemIndex === 'number'){ + context.$match = { + active: itemScope.$selectMultiple.activeMatchIndex == itemIndex, + locked: ctrl.isLocked(itemScope, itemIndex), + }; + } + // evaluate ui-match-styke attribute + return itemScope.$eval(ctrl.matchStyleExpression, context) || {}; + }; + + // Gives the ng-class argument for + ctrl.choiceClass = function(itemScope, deflt) { + deflt = deflt || {}; + if(!ctrl.choiceClassExpression) return deflt; + // create a context with a $choice object + var context = {}; + context.$choice = { + active: ctrl.isActive(itemScope), + disabled: ctrl.isDisabled(itemScope), + }; + // evaluate ui-choice-class attribute + var classes = itemScope.$eval(ctrl.choiceClassExpression, context) || {}; + // all this code is used to disable default classes when recieved in ``{className: false}`` + // if it is overkill, a simple ``return [classes, deflt];`` makes the job + if(!deflt) return classes; + var noClass = {}; + classes = arrayClasses(classes, noClass); + arrayClasses(deflt, {}).forEach(function(c){ + if(!noClass[c]) classes.push(c); + }); + return classes; + }; + + // Gives the ng-style argument for + ctrl.choiceStyle = function(itemScope) { + if(!ctrl.choiceStyleExpression) return {}; + // create a context with a $choice object + var context = {}; + context.$choice = { + active: ctrl.isActive(itemScope), + disabled: ctrl.isDisabled(itemScope), + }; + // evaluate ui-choice-style attribute + return itemScope.$eval(ctrl.choiceStyleExpression, context) || {}; + }; var sizeWatch = null; var updaterScheduled = false; diff --git a/src/uiSelectMatchDirective.js b/src/uiSelectMatchDirective.js index ef9bdcf33..f02c10c1f 100644 --- a/src/uiSelectMatchDirective.js +++ b/src/uiSelectMatchDirective.js @@ -17,6 +17,8 @@ uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) { }, link: function(scope, element, attrs, $select) { $select.lockChoiceExpression = attrs.uiLockChoice; + $select.matchClassExpression = attrs.uiMatchClass; + $select.matchStyleExpression = attrs.uiMatchStyle; attrs.$observe('placeholder', function(placeholder) { $select.placeholder = placeholder !== undefined ? placeholder : uiSelectConfig.placeholder; });