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

Kevin Schroeder
  • 1,296
  • 11
  • 23

2 Answers2

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];
Pierre-Alexandre Moller
  • 2,354
  • 1
  • 20
  • 29
  • 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. – Kevin Schroeder Jul 28 '15 at 14:06
  • 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. – Pierre-Alexandre Moller Jul 28 '15 at 14:10
  • 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. – Kevin Schroeder Jul 30 '15 at 13:35
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>
Community
  • 1
  • 1
Andrzej Gis
  • 13,706
  • 14
  • 86
  • 130
  • 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 Jul 28 '15 at 13:55
  • @Okazari When you do 'ng-options="selectedItem as ....' it binds to the whle object. – Andrzej Gis Jul 28 '15 at 14:00
  • 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. – Okazari Jul 28 '15 at 14:03