I've to write a directive to edit labels for an app.
Each culture (eg: en-US) can have maximum 4 labels per property which are contained into a table :
$scope.suffixes = ["DisplayName", "Description", "Hint", "Help"];
<div class="clear" ng-repeat="label in labelModel | filter:cultureFilter">
<select ng-options="suffix as suffix for suffix in suffixes | filter:suffixFilter(suffix, label.suffix)" ng-model="label.suffix" />
</div>
and here are my controller functions :
$scope.cultureFilter = function (label) {
return (label.culture == $scope.labelState.culture);
}
$scope.suffixFilter = function (suffix, selectedValue) {
//arguments are now : [undefined, "DisplayName"]
return true; // :-(
}
So far, I've been able to filter the ng-repeat based on the culture.
But for my ng-options, I have to filter the strings that are already used. But I also have to keep the current value selected. How can I tell my filter that some value shouldn't be filtered because it's the current selected value?
edit
Now, I'm able to receive the selected value, but I can't receive my suffix anymore
You are almost there with using a filter function, but in your case, I think what you really need is a custom filter. They are actually trivial to write.
A filter is just a factory function registered with the .filter()
helper.
You just need one that takes in the parameters you care about.
//Outer factory function
function SuffixFilter(){
//Inner function which is our filter
return function(items, ignoredItem){
var filteredItems = [];
angular.forEach(items, function(item){
//Your filtering logic may be more complex
// than this. It's only an example
if(item == someCriteria || item == ignoredItem){
filteredItems.push(item);
}
});
return filteredItems;
}
}
angular.module('myModule')
.filter('suffixFilter', SuffixFilter);
And once you have your suffix filter registered, you can simply call it in your markup with the parameter you care about. Angular handles the rest.
<!-- Pass in the current selection to ignore -->
suffixes | suffixFilter:label.suffix
The function parameter doesn't really work that way. It's expecting to evaluate to a function that can be called.
Technically you could return a function and use closures to accomplish what you want. Something like this:
<!-- In your markup -->
filter:suffixFilter(label.suffix)
//In your controller
$scope.suffixFilter = function (selectedValue) {
//this is your actual filter here
return function(item){
//You have access to 'selectedValue' via
// a closure
return item == someCriteria || item === selectedValue;
}
}
So again, while this is certainly possible, I think a custom filter is semantically cleaner.