0

I am having the hardest time getting two way binding to work for SELECT elements. I am trying to change the selected element programmably. I've found several Stackoverflow examples for binding the change event for SELECT, but I've not been many going the other way, where your application code changes the selected element.

There have been a few that I've found that use ng-repeat on an OPTION element but I've a) not been able to get it to work, and b) does not seem to be the "Angular Way".

HTML Code:

<div ng-controller="SIController">
<select id="current-command" ng-model="currentCommand"
ng-options="c as c.label for c in availableCommands track by c.id"></select>
<button ng-click="changeSelectedOption()">Select "open"</button>

Controller Code:

var myApp = angular.module('myApp', []);

function SIController($scope) {

    $scope.availableCommands = [
        {id: 'edit',        label: 'Edit'},
        {id: 'open',        label: 'Open'},
        {id: 'close',       label: 'Close'}
    ];

    $scope.currentCommand = "close";
    $scope.changeSelectedOption = function() {
        $scope.currentCommand = 'open';
    };  
};

I can verify that $scope.currentCommand is changing when the button is clicked, but the OPTION does not seem to be getting selected.

Fiddle here

2 Answers 2

1

Is there the working fiddle : http://jsfiddle.net/bzhkkw18/9/

To explain what I've done, there is the name of the function which didn't match on the ng-click and in the controller.

And the main part was the definition of your option. In your ng-options you set the all object. If it's what you really want, you have to do the same in your currentCommand like this :

//Object 2 is close
$scope.currentCommand = $scope.availableCommands[2];
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I think that part of my problem is that when the data goes out of the select object (i.e. clicking it) it comes out in one format, but selecting it via JavaScript requires a different format. Looks like I might have some minimal refactoring to do.
You're welcome. The same format is require in currentCommand. But it was different, on your ng-model you have all the object. And when you set it, you put just the label. You only need to harmonize the values. If you want to save the all object my answer is OK. If you just want to save the label, there is some refactoring to do.
I have a follow up question. In my real app the data binding is working, but it only happens when I call some other command. In order for me to make it work when the model is changed I need to call $scope.$apply() but I don't understand why and I'd rather it be automatic. The method IS being called from a third party library that is handling key bindings.
0

I recently had a similar problem. Take look at my answer. You should modify the way you defined ng-options.

function MyCtrl($scope) {
    $scope.values = [
        {name : "Daily", id : 1},
        {name : "Weekly", id : 2},
        {name : "Monthly", id : 3},
        {name : "Yearly", id : 4}];
    $scope.selectedItem = $scope.values[0].id;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
    <select ng-model="selectedItem" ng-options="selectedItem.id as selectedItem.name for selectedItem in values"></select>
    selectedItem: {{selectedItem}}
</div>

3 Comments

This will really depend about what you want into the "selectedItem". If you want an id, that's a good way. If you need the whole object you need to keep the first syntax.
@Okazari When you do 'ng-options="selectedItem as ....' it binds to the whle object.
Yup, but i just wanted to put a warning. You exemple will only give the "in" into "selectedItem" and that may not be what the op want.

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.