1

I have an array of objects in $scope.currentSChannels.scgsLink This array of objects have something like

$scope.currentSChannels.scgsLink = [{channelId:1, sCgsLinkId:1, groupNo:1, percentage: 50, expireHrs:4},{channelId:1, sCgsLinkId:2, groupNo:2, percentage:50, expireHrs:1}]

and I also have the following select list

<div class="col-md-4">
                <select class="form-control" ng-model="newLink.groupNo"
                        name="groupNo" id="groupNo" 
                        ng-options="t.value as t.text for t in metaData.spGroups"></select>
            </div>

I need to filter that list to not show already selected items in the $scope.currentSChannels.scgsLink groupNo column. I looked at http://christian.fei.ninja/Angular-Filter-already-selected-items-from-ng-options/ and also at AngularJS ng-options to exclude specific object and both seem to be close but not enough as I need to filter against an array and a particular column in that array. How should I implement that filtering?

2 Answers 2

2

The template is getting a bit tricky. Assuming selectedLink is the variable that points to the selected groupNo

ng-options="t.value as t.text for t in metaData.spGroups | filter: {value: '!' + currentSChannels.scgsLink[selectedLink].groupNo}"

See this fiddle : the second select contains the same collection as the first one, excluded what is already selected.

Edit: Solution above is for excluding elements according to one value. So as to exclude the elements according to a collection of values, a custom filter would suit best:

Filter

app.filter('channelFilter', function () {
    return function (metadata, exclusions) {
        var filterFunction = function (metadata) {
            // return the metadata object if exclusions array does NOT contain his groupNo
            return !exclusions.some(function (exclusion) {  
                return exclusion.groupNo === metadata.value;
            });
        };

        return metadatas.filter(filterFunction);
    };
});

Usage

ng-options="metadata in metadatas | channelFilter: exclusions"

Template

ng-options="t.value as t.text for t in metaData.spGroups | channelFilter: currentSChannels.scgsLink"

Fiddle

That said, would be more efficient to group selected links by groupNo to avoid searches in the array, and filter in the controller.

Sign up to request clarification or add additional context in comments.

7 Comments

What is selectedLink in your example? I want to implement NOT IN filter where I want to exclude all already selected groups. As I shown in my example, I already have 2 groups assigned. I want to allow to select only groups which are not already in that complex property (that property is an array of objects as I've shown).
"I need to filter against an array and a particular column in that array". According to the sentence I thought you needed to filter against one item only. If you need to filter against all elements of scgsLink, I would define a custom filter...
That's what I was thinking as well, but that sample in the blog post is not clear to me. It also seems to work for one item only. Can you help me writing this custom filter where I would pass an array and a particular column in array to work against?
Yep. Btw do you have in your project any js library like lodash or underscore?
I've searched solution and we don't use underscore.js although I see few comments telling the code is borrowed from it. We do use lodash already
|
1

I wanted to make it a bit more generic, so I've done the following

http://jsfiddle.net/96m4sfu8/

app.filter('excludeFrom', function () {
    return function (inputArray, excludeArray, excludeColumnName, inputColumnName) {
        if (inputColumnName==undefined)
            inputColumnName = 'value';
		var filterFunction = function (inputItem) {
            return !excludeArray.some(function (excludeItem) {
                return excludeItem[excludeColumnName] === inputItem[inputColumnName];
            });
        };

        return inputArray.filter(filterFunction);
    };
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.