From 361642a4513c2f98228f9439860ca95282da5c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Lambert?= Date: Sat, 3 Jun 2017 18:53:22 +0200 Subject: [PATCH 1/2] add ui-match-class, ui-match-style, ui-choice-class and ui-choice-style in order to customize results --- src/bootstrap/choices.tpl.html | 2 +- src/bootstrap/match-multiple.tpl.html | 3 +- src/bootstrap/match.tpl.html | 2 + src/select2/choices.tpl.html | 4 +- src/select2/match-multiple.tpl.html | 4 +- src/select2/match.tpl.html | 3 +- src/selectize/choices.tpl.html | 3 +- src/selectize/match-multiple.tpl.html | 3 +- src/uiSelectChoicesDirective.js | 2 + src/uiSelectController.js | 66 +++++++++++++++++++++++++++ src/uiSelectMatchDirective.js | 2 + 11 files changed, 86 insertions(+), 8 deletions(-) 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..0a7a9a846 100644 --- a/src/bootstrap/match-multiple.tpl.html +++ b/src/bootstrap/match-multiple.tpl.html @@ -6,7 +6,8 @@ type="button" ng-disabled="$select.disabled" ng-click="$selectMultiple.activeMatchIndex = $index;" - ng-class="{'btn-primary':$selectMultiple.activeMatchIndex === $index, 'select-locked':$select.isLocked(this, $index)}" + ng-class="$select.matchClass(this, $index, {'btn-primary':$selectMultiple.activeMatchIndex === $index, 'select-locked':$select.isLocked(this, $index)})" + ng-style="$select.matchStyle(this, $index)" ui-select-sort="$select.selected">  × diff --git a/src/bootstrap/match.tpl.html b/src/bootstrap/match.tpl.html index 1dc23cd98..44f1e8aa1 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..9a41f469c 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,68 @@ uis.controller('uiSelectCtrl', }; } + ctrl.matchClass = function(itemScope, itemIndex, deflt) { + deflt = deflt || {}; + if(!ctrl.matchClassExpression) return deflt; + var context = {}; + if(typeof itemIndex === 'number'){ + context.$match = { + active: itemScope.$selectMultiple.activeMatchIndex == itemIndex, + locked: ctrl.isLocked(itemScope, itemIndex), + }; + } + var cls = itemScope.$eval(ctrl.matchClassExpression, context); + if(typeof cls === 'string'){ + cls.split(/\s+/).forEach(function(c){ + deflt[c] = true; + }); + }else if(cls){ + for(var c in cls) deflt[c] = cls[c]; + } + return deflt; + }; + + ctrl.matchStyle = function(itemScope, itemIndex) { + if(!ctrl.matchStyleExpression) return {}; + var context = {}; + if(typeof itemIndex === 'number'){ + context.$match = { + active: itemScope.$selectMultiple.activeMatchIndex == itemIndex, + locked: ctrl.isLocked(itemScope, itemIndex), + }; + } + return itemScope.$eval(ctrl.matchStyleExpression, context) || {}; + }; + + ctrl.choiceClass = function(itemScope, deflt) { + deflt = deflt || {}; + if(!ctrl.choiceClassExpression) return deflt; + var context = {}; + context.$choice = { + active: ctrl.isActive(itemScope), + disabled: ctrl.isDisabled(itemScope), + }; + var cls = itemScope.$eval(ctrl.choiceClassExpression, context); + if(typeof cls === 'string'){ + cls.split(/\s+/).forEach(function(c){ + deflt[c] = true; + }); + }else if(cls){ + for(var c in cls) deflt[c] = cls[c]; + } + return deflt; + }; + + ctrl.choiceStyle = function(itemScope) { + if(!ctrl.choiceStyleExpression) return {}; + var context = {}; + context.$choice = { + active: ctrl.isActive(itemScope), + disabled: ctrl.isDisabled(itemScope), + }; + 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; }); From 9502d294ead2af629e23def54313d727ca1f13e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Lambert?= Date: Thu, 15 Jun 2017 11:58:00 +0200 Subject: [PATCH 2/2] refactor class merging and add comments --- src/bootstrap/match-multiple.tpl.html | 4 +- src/bootstrap/match.tpl.html | 4 +- src/uiSelectController.js | 77 ++++++++++++++++++++------- 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/bootstrap/match-multiple.tpl.html b/src/bootstrap/match-multiple.tpl.html index 0a7a9a846..7dd272435 100644 --- a/src/bootstrap/match-multiple.tpl.html +++ b/src/bootstrap/match-multiple.tpl.html @@ -1,12 +1,12 @@  × diff --git a/src/bootstrap/match.tpl.html b/src/bootstrap/match.tpl.html index 44f1e8aa1..8267113a1 100644 --- a/src/bootstrap/match.tpl.html +++ b/src/bootstrap/match.tpl.html @@ -1,7 +1,7 @@
    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 = { @@ -533,19 +561,23 @@ uis.controller('uiSelectCtrl', locked: ctrl.isLocked(itemScope, itemIndex), }; } - var cls = itemScope.$eval(ctrl.matchClassExpression, context); - if(typeof cls === 'string'){ - cls.split(/\s+/).forEach(function(c){ - deflt[c] = true; - }); - }else if(cls){ - for(var c in cls) deflt[c] = cls[c]; - } - return deflt; + // 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 = { @@ -553,39 +585,46 @@ uis.controller('uiSelectCtrl', 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), }; - var cls = itemScope.$eval(ctrl.choiceClassExpression, context); - if(typeof cls === 'string'){ - cls.split(/\s+/).forEach(function(c){ - deflt[c] = true; - }); - }else if(cls){ - for(var c in cls) deflt[c] = cls[c]; - } - return deflt; + // 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; ctrl.sizeSearchInput = function() {