2


a question to angular js. Let's say I have an array of objects eg:

items = [
{"id":1,"name":"AAA"},
{"id":2,"name":"BBB"},
{"id":3,"name":"CCC"},
{"id":4,"name":"DDD"}
]

Now I have 2 or 3 selects in my view.

<select type="text" class="form-control form-control-small" 
ng-model="itemId" ng-options="item.id as item.name for item in items">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemId" ng-options="item.id as item.name for item in items">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemId" ng-options="item.id as item.name for item in items">
</select>

So how can I assure that I have all 4 options in the first select, 3 options in the second one (all minus selected), two in the third one (also all minus selected) and so on. And how can I update the subsequent selects whenever there is a change in any of the selects.
Many thanks in advance for ideas.

3
  • question is not clear. please edit it, or post a fiddle demonstrating it. Commented Feb 19, 2015 at 10:28
  • May i ask why do you need this functionality? Maybe multiselect will be enought? Commented Feb 19, 2015 at 10:31
  • I just have such a requirement, I'd like to do it with multiselect, but this solution is impossible for me. Commented Feb 19, 2015 at 10:57

3 Answers 3

1

You need to create a filter.
Note: I am using the ES5 filter function, it won't work on IE8 unless your use a shim

yourModule.filter('exclude', function () {
    return function (items, exclude) {
        return items.filter(function (item) {
            return exclude.indexOf(item.id) === -1;
        });
    });
});

And in your markup

<select type="text" class="form-control form-control-small" 
ng-model="itemId1" ng-options="item.id as item.name for item in items">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemId2" ng-options="item.id as item.name for item in items | exclude:[itemId1]">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemId3" ng-options="item.id as item.name for item in items | exclude:[itemId1, itemId2]">
</select>

If you want to update your selects if there is a change in the first or second one, use ngChange directive for resetting or changing other model values.

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

4 Comments

The solution will be probably sth like this, but I can not name my ng-model like "id1", "id2". I add the new select dinamically on demand so every "row" has the same model
exclude.indexOf(item) === -1; in this line it should be exclude.indexOf(item.id) as we are matching ids and not entire item @Thomas Roch
Thanks @mohamedrias but no need for you to copy paste.
Thanks it worked for me. Anyway I was able to change the requirements so I run it with multiselect :)
1
Module.filter('exclude', function () {
    return function (items, exclude) {
        return items.filter(function (item) {
            return exclude.indexOf(item.id) === -1; // Checking if the itemid is present already in the array
        });
    }
});

And in your markup

<select type="text" class="form-control form-control-small" 
ng-model="itemIdA" ng-options="item.id as item.name for item in items">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemIdB" ng-options="item.id as item.name for item in items | exclude:[itemIdA]">
</select>

<select type="text" class="form-control form-control-small" 
ng-model="itemIdC" ng-options="item.id as item.name for item in items | exclude:[itemIdA, itemIdB]">
</select>

Comments

0

I actually found a better (imho) solition. We just add a boolean field to the array, like:

{"id":1,"name":"AAA", "show" : true}

and filter to ng-options:

 ng-options="item as item.name for item in items | filter : {"show : true}"

When selecting an item from the list we need to update to "show" value to false, so it won't be visible on the next select and update again to value true when when it is necessary. Anyway thx a lot for your help :)

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.