20

So, What I'm trying to do is fairly simple with vanilla JS, but I'm using AngularJS and I would like to know how to do it the best way within the framework. I want to update the selected options in a multiple select box. I do not want to add or remove any of the options. Here is what my HTML looks like:

<select multiple>
    <option value="1">Blue</option>
    <option value="2">Green</option>
    <option value="3">Yellow</option>
    <option value="4">Red</option>
</select>

Using the following array, I'd like to programmatically select/deselect options from this list:

[{id:1, name:"Blue"},{id:4, name:"Red"}]

When I set this array in the scope, I want the select box to deselect anything that is not Blue or Red and select Blue and Red. The standard response that I've seen on the Google Groups is to use ng-repeat. However, I can't recreate the list every time because the list of selected values is incomplete. As far as I can tell, AngularJS has no mechanism for this, and I'm at a loss as to how I would do this without resorting to using jQuery.

1
  • I feel pretty confident I could solve this if you make me a jsbin.com or similar site example that I can look at and leave some notes on what is wrong / what you expect, etc. I find angular makes a lot of things pretty easy. :) Commented Sep 12, 2013 at 6:23

1 Answer 1

29

ngModel is pretty awesome! If you specify the indexes as a model selectedValues

<select multiple ng-model="selectedValues">

built from your list (selected) in a $watch

$scope.$watch('selected', function(nowSelected){
    // reset to nothing, could use `splice` to preserve non-angular references
    $scope.selectedValues = [];

    if( ! nowSelected ){
        // sometimes selected is null or undefined
        return;
    }

    // here's the magic
    angular.forEach(nowSelected, function(val){
        $scope.selectedValues.push( val.id.toString() );
    });
});

ngModel will automatically select them for you.

Note that this data binding is one-way (selected to UI). If you're wanting to use the <select> UI to build your list, I'd suggest refactoring the data (or using another $watch but those can be expensive).

Yes, selectedValues needs to contain strings, not numbers. (At least it did for me :)

Full example at http://jsfiddle.net/JB3Un/

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

5 Comments

Thanks for the answer! I do unfortunately need this to be two-way, it's for an edit-style page. Is there a way you would refactor this to make it work in a multiple select box? My problem is mainly that I'm not how to approach this with Angular.
If all you're looking for is ['red','blue'] then use those as the values of your <option> elements, as in jsfiddle.net/JB3Un/1
I think this came down to a lack of understanding about Angular on my part. Because I was more or less decoupling the model I was using from the view, I needed to have an intermediary variable to handle transferring between the two. I load the list of values with AJAX, so I just added some code to put the values into selectValues instead of using $watch. Your answer helped me a lot in figuring that out, thank you so much!
The magic is in the .push(). Changing the array with assignment does NOT work.
@PixnBits Steller answer!

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.