I have written a custom filter that excludes currently selected options from the list of available options for several <select>
inputs.
codepen - http://codepen.io/jusopi/pen/XdjNWa?editors=1010
template implementation
<select class="form-control" ng-model="vc.cols[0].attr"
ng-options="opt.attr as opt.name for opt in vc.opts | excludedAttrs:vc.cols">
filter
.filter('excludedAttrs', function () {
return function (opts, cols) {
return _.differenceWith(opts, cols, function (opt, col) {
return opt.attr === col.attr;
});
};
})
I'm not sure if it's my misunderstanding of Lodash's differenceWith
(API docs) or if there is some subtly in using filters with a <select>
over other inputs.
As I understand differenceWith
, it's meant to compare 2 arrays and utilizes a comparator function that returns true if they are to be excluded. The filter actually works, but why is it not rendering the ng-model
default value properly or the selected value?
The problem with the select not showing the currently selected ng-model
was because the actual <option/>
was not present in the ng-options
due to the filter excluding it in the collection.
In order to fix this, I needed to exclude the currently selected value (i.e. the ng-model
from being ... well, from being excluded. Basically I had to add it back into the filtered ng-options
.
codepen - http://codepen.io/jusopi/pen/XdjNWa?editors=1010
template implementation
<select ng-model="vc.cols[0].attr"
ng-options="opt.attr as opt.name for opt in vc.opts | excludedAttrs:vc.cols:0">
fixed filter
.filter('excludedAttrs', function () {
return function (opts, cols, i) {
// fix
cols = _.without(cols, cols[i]);
// end fix
return _.differenceWith(opts, cols, function (opt, col) {
return opt.attr === col.attr;
});
};
})