I'm trying to add the multiple
attribute to a ui-select
directive based on the value of a certain property using the ng-attr-
directive. Unfortunately, that's not working for me. I've setup a plunker example to showcase what is happening.
Plunker Example
I finally got it after reading through the mentioned GitHub Issue in the Angular Repo.
You need to set up a directive with a higher priority
and a terminal
attribute set to true (which skips the compilation of all other directives, after the compilation of our directive).
Then in the postLink
function we will compile the whole element itself. But before that our own directive needs to be removed (infinite loop!).
Big shot outs to Add directives from directive in AngularJS
angular.module('app')
.directive('multiSelectChecker', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //terminal means: compile this directive only
priority: 50000, //priority means: the higher the priority, the "firster" the directive will be compiled
compile: function compile(element, attrs) {
element.removeAttr("multi-select-checker"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-multi-select-checker"); //also remove the same attribute with data- prefix in case users specify data-multi-select-checker in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
if(scope.options.Multiple == true) {
iElement[0].setAttribute('multiple',''); //set the multiple directive, doing it the JS way, not jqLite way.
}
$compile(iElement)(scope);
}
};
}
};
});
<ui-select ng-model="model.choice" multi-select-checker>
<ui-select-match>{{$item.Title}}</ui-select-match>
<ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
<div ng-bind="item.Title | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
http://plnkr.co/edit/N11hjOFaEkFUoIyeWqzc?p=preview
I did the following:
multi-select-checker
options.Multiple
is true or falseapp.directive('multiSelectChecker', function() {
return {
template: '<ng-include src="getTemplateUrl()"/>',
controller: function($scope) {
$scope.getTemplateUrl = function() {
if($scope.options.Multiple == true) {
console.log("multi-select");
return "multi-select.tpl.html"
}
else {
console.log("single select");
return "single-select.tpl.html"
}
}
}
}
})
<body ng-controller="DemoCtrl">
<multi-select-checker>
</multi-select-checker>
</body>
<ui-select ng-model="model.choice">
<ui-select-match>{{$item.Title}}</ui-select-match>
<ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
<div ng-bind="item.Title | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<ui-select ng-model="model.choice" multiple>
<ui-select-match>{{$item.Title}}</ui-select-match>
<ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
<div ng-bind="item.Title | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
As you can see the two templates only differ by one single directive: 'multiple'. Maybe there are better solutions.
I even can't understand, why the ng-attr-multiple approach isn't working.
In addition I have realized, that there are two seperate input fields being rendered via the ng-attr-multiple approach.
And the single selection case seems to be broken (by removing the multiple directive) - which was in your intial Plnkr as well.
See the working Plnkr here: http://plnkr.co/edit/T9e5tcAkcQLsDV3plfEl?p=preview
Is this what you want to achieve:
<body ng-controller="DemoCtrl">
This works perfectly well:
<ui-select ng-model="model.choice" multiple>
<ui-select-match>{{$item.Title}}</ui-select-match>
<ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
<div ng-bind="item.Title | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<br />
<br />
This does not work:
<ui-select ng-model="model.choice2" multiple="{{options.Multiple}}">
<ui-select-match>{{$item.Title}}</ui-select-match>
<ui-select-choices repeat="item.Id as item in options.SuggestedValues | filter: { Title: $select.search }">
<div ng-bind="item.Title | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</body>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With