Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the ng-model of a select tag to get the initially-selected option?

I'm pretty new to Angular, so I may be going about this all wrong...

I have a <select> similar to the following:

<select ng-model="mySelectedValue">
    <option value="">--</option>
    <option ng-repeat="myValue in someDynamicArrayOfValues" value="{{myValue}}" ng-selected="myFunctionForDeterminingWhetherValueIsSelected(myValue)">{{myValue}}</option>
</select>

This mostly works... The dropdown initially renders with the correct option selected, and if I change the selected option, then mySelectedValue will get the new selection. However, mySelectedValue does NOT get the initially-selected option. mySelectedValue is blank until I change the value in the dropdown.

I looked at ng-init, but that seems to get evaluated before someDynamicArrayOfValues is set...

Is there a way I can get mySelectedValue to receive the value in the initially-selected <option>?


UPDATE:
I forgot to mention that I had also tried using ng-options, but haven't had any luck getting that to work in conjunction with determining which option was selected.

I've tried this:

<div ng-show="someDynamicArrayOfValues">
    <select ng-model="mySelectedValue" ng-options="arrayValue for arrayValue in someDynamicArrayOfValues" ng-selected="myFunctionForDeterminingWhetherValueIsSelected(arrayValue)">
        <option value="">--</option>
    </select>
</div>

and this:

<div ng-show="someDynamicArrayOfValues">
    <select ng-model="mySelectedValue" ng-options="arrayValue for arrayValue in someDynamicArrayOfValues" ng-init="myFunctionForSettingSelectedValue()">
        <option value="">--</option>
    </select>
</div>

but neither of those work because the select is built (and ng-init and ng-selected both get evaluated) before someDynamicArrayOfValues has been set and, therefore, before the <select> is even visible. When using <option ng-repeat="...">, the <select> doesn't get built/initialized until after someDynamicArrayOfValues is set, which is why I had been going that direction.

Is there a way to get the ng-options technique to work while, at the same time, having the select dependent on someDynamicArrayOfValues (if ng-options is the better way to go)?


UPDATE 2:
Here's a Plunker (modified from ababashka's answer) that is a little closer to what I'm ultimately trying to achieve: http://plnkr.co/edit/Kj4xalhI28i5IU0hGBLL?p=preview. It's not quite there yet... I'd like it to have each of the 3 dropdowns set with the closest-matching dynamic value once someDynamicArrayOfValues is set.

like image 934
Troy Avatar asked Oct 21 '14 11:10

Troy


People also ask

How do I set default selected value in ng options?

Use ng-init to set default value for ng-options . Save this answer.

How do you get the selected value of an element?

The value of the selected element can be found by using the value property on the selected element that defines the list. This property returns a string representing the value attribute of the <option> element in the list. If no option is selected then nothing will be returned.

How do I change selected option in select tag?

In order to change the selected option by the value attribute, all we have to do is change the value property of the <select> element. The select box will then update itself to reflect the state of this property. This is the easiest and most straightforward way of updating a select box state.

How does ng select work?

The ng-selected directive sets the selected attribute of an <option> element in a <select> list. The option will be selected if the expression inside the ng-selected attribute returns true. The ng-selected directive is necessary to be able to shift the value between true and false .


1 Answers

I think that it will be good it you will use ng-options attribute of select tag. It's an angular directive which creates options according to Array of options. You can take a look at select documentation
If you use your code - your function myFunctionForDeterminingWhetherValueIsSelected works twice for every option at initialization and once for every option item when you select some another option.

Demo with your code: http://plnkr.co/edit/0IVNLHiw3jpz4zMKcB0P?p=preview

Demo for select you could see at description of select directive.

Update

At first, to see when value is changed - you need to use ng-change attribute of select tag, like this:

<select ng-model="mySelectedValue" 
  ng-options="myValue for myValue in someDynamicArrayOfValues"
  ng-change="myFunctionForDeterminingWhetherValueIsSelected()">
  <option value="">--</option>
</select>

Then, i don't know how does myFunctionForSettingSelectedValue look like, but there are 2 variants:

  • This function returns some value - then you need to use ng-init next way.

Controller:

  $scope.someInitFunc = function () {
    return 'One';
  };

HTML:

<select ng-model="mySelectedValue" 
      ng-options="myValue for myValue in someDynamicArrayOfValues"
      ng-change="myFunctionForDeterminingWhetherValueIsSelected()"
      ng-init="mySelectedValue = someInitFunc()">
      <option value="">--</option>
</select>
  • You set value of mySelectedValue in this function - then you do this.

Controller:

$scope.someInitFunc = function () {
  $scope.mySelectedValue = 'One';
};

HTML:

<select ng-model="mySelectedValue" 
  ng-options="myValue for myValue in someDynamicArrayOfValues"
  ng-change="myFunctionForDeterminingWhetherValueIsSelected()"
  ng-init="someInitFunc()">
  <option value="">--</option>
</select>

I have created an example which implements the first version of using ng-init. When new value is selected - it's printed to console.

Also, i moved options to the options.json file. So options are initialized just after ajax request was finished. Everything works great.

Demo: http://plnkr.co/edit/pzjxxTnboKJXJYBGcgNb?p=preview

Update 2

Hello again. I think you don't need to have any ng-init according to your requirements. You can just initiate values of your model when http request is finished. Also i don't understand why do you need ng-change function in this case.

Here is modified code you need from your plunk where values of ng-models are initiated after options are loaded.

JavaScript:

.controller('MainCtrl', function($scope, $http) {
  $scope.someStaticArrayOfValues = ['One', 'Two', 'Three'];
  $scope.mySelectedValues = {};
  $http.get('options.json').then(
    function (response) {
      $scope.someDynamicArrayOfValues = response.data;
      for (var i = 0; i < $scope.someStaticArrayOfValues.length; ++i) {
        $scope.someDynamicArrayOfValues.some(function (value) {
          if (value.substring(0, $scope.someStaticArrayOfValues[i].length) === $scope.someStaticArrayOfValues[i]) {
            $scope.mySelectedValues[$scope.someStaticArrayOfValues[i]] = value;
            return true;
          }
        });
      }
    },
    function (response) {
      console.log('ERROR!');
    }
  );
});

HTML:

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <div ng-show="someDynamicArrayOfValues">
      <ul>
        <li ng-repeat="staticValue in someStaticArrayOfValues">
          {{staticValue}} - 
          <select ng-model="mySelectedValues[staticValue]" 
            ng-options="myValue for myValue in someDynamicArrayOfValues">
            <option value="">--</option>
          </select>
          <h2>{{mySelectedValues[staticValue]}}</h2>
        </li>
      </ul>
    </div>
  </body>

Demo: http://plnkr.co/edit/9Q1MH0esGE1SIJa0m2NV?p=preview

like image 173
ababashka Avatar answered Sep 19 '22 18:09

ababashka