Select element in angular not updating modelValue on second selection

All we need is an easy explanation of the problem, so here it is.

I’ve got a select element bound to a model in an angular view. When filling out the form with the keyboard, I noticed that if you down arrow to the second option the value, the model still represents the first value. This only happens when using the keyboard to fill out the form.

Set up is pretty simple, using angular 1.4.3:

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

app.controller('myController', function() {
  var vm = this;

  vm.options = [{
    Id: 1,
    Value: 'A'
  }, {
    Id: 2,
    Value: 'B'
  }, {
    Id: 3,
    Value: 'C'
  }]
});
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>

<body ng-app="app">
  <div ng-controller="myController as ctrl">
    <p>
      Model is not updated on second down button push. Repro:
      <ol>
        <li>Tab to select element</li>
        <li>Hit down and notice the optionId updated to 1</li>
        <li>Hit down again and notice that the displayed value changes to B, but optionId stays as 1</li>
        <li>Hit down again and notice that the displayed value changes to C, and optionId changes to 3</li>
        <li>Hit up and notice that displayed value changes to B, and optionId changes to 2</li>
      </ol>
      Why doesn't the optionId = 2 on the initial selection of B
    </p>
    <select id="mySelect" ng-options="item.Id as item.Value for item in ctrl.options" ng-model="ctrl.optionId" style="width:200px">
    </select>
    <div><strong>optionId: {{ctrl.optionId}}</strong>
    </div>
  </div>
</body>

Why doesn’t the model update on the second down arrow press?

Update
Here’s a plunker that exhibits the behavior, http://plnkr.co/edit/Hiu67NTR3Gpk9jByZtQD?p=info

2nd Update
Here’s a modified plunker that implements the workaround Matt proposed. This workaround causes the desired behavior in Chrome, Firefox, and Internet Explorer

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I believe your problem clones a pre-existing angular issue which has a work around available.

Feel free to browse the issue and trace the conversation and some of the duplicates.

The work around suggested for Chrome/Safari/Firefox looks like this:

directive('changeOnKeyup', function changeOnKeyupDirective() {
  return function changeOnKeyupPostLink(scope, elem) {
    elem.on('keyup', elem.triggerHandler.bind(elem, 'change'));
  };
});

Edit:

The OP’s issue in the comments above was closed as a duplicate for this reason.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply