click2install click2install - 3 months ago 141
AngularJS Question

How to bind to multiple in md-select inside directive

Trying to create a simple directive that shows a textbox or dropdown depending on whether an array is passed for a

model
property on the scope.

Anything except explicitly setting
false
in the directive markup e.g.,
multiple="false"
, results in a multi-select dropdown.

Why is this not working? Also, md-select value binding is not working (although textbox binding is working), I suspect for the same reason.

Plunkr available here illustrating the issue

Consumer

<div ng-app='home' layout-padding layout="row">
<content-filter ng-repeat="filter in filters" flex="filter.width" model="filter.model" value="filter.value"></content-filter>
</div>


Consumer Controller

app.controller('MainCtrl', function($scope)
{
$scope.filters =
[
{
model:
{
multiSelect: false,
items:
[
{
label: 'All',
value: 'all'
},
{
label: 'Fail',
value: 'fail'
},
{
label: 'Success',
value: 'success'
}
]
},
value: 'all',
width: '50%'
},
{
value: '123',
width: '50%'
}
];
});


Directive

app.directive('contentFilter', function()
{
return {
restrict: 'E',
replace: false,
template: '\
<md-input-container flex layout="fill" ng-if="model && model.items.length">\
<md-select ng-model="value" multiple="model.multiSelect === true">\
<md-option ng-repeat="item in model.items" ng-value="{{ item.value }}">{{ item.label }}</md-option>\
</md-select>\
</md-input-container>\
<md-input-container flex layout="fill" ng-if="!model">\
<input type="text" aria-label="{{ label }}" ng-model="value" />\
</md-input-container>',
scope:
{
value: '=',
model: '=?'
}
};
});

Answer

Probably this is not the answer you are looking for...

I've tried to conditionally set multiple attribute to md-select and nothing seems to be work (ng-attr-multiple, ng-multiple...). Probably it's an angular-material bug.

So, as a workaround, you could conditionally add two md-selects, depending on the atribute model.multiSelect value: one with multiple attribute and the other one without it. Example:

<md-input-container flex layout="fill" ng-if="model && !model.multiSelect && model.items.length">\
    <md-select ng-model="value">\
     <md-option ng-repeat="item in model.items" value="{{ item.value }}">{{ item.label }}</md-option>\
    </md-select>\
</md-input-container>\
<md-input-container flex layout="fill" ng-if="model && model.multiSelect && model.items.length">\
    <md-select ng-model="[value]" multiple>\
     <md-option ng-repeat="item in model.items" value="{{ item.value }}">{{ item.label }}</md-option>\
    </md-select>\
</md-input-container>\

IMPORTANT: Keep in mind that if the md-select is multiple, the value binded needs to be an array, so you will have to change ng-model="value" per ng-model="[value]", as you can see in the previous code.

I've forked your plunker and you can see a working example here

Hope it helps. Anyway, I'll be waiting for other answers.