7

Now I am trying to get the value from select dropdown, but it return undefined. The thing is in html level it works as expect, Here is my code:

<div class='subcontent'>            
  <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y"><label for="me" class='choosemethod'>Me</label>
  <input id="company" type="radio"  ng-model="paymentmethod" value="N" class='choosemethod'><label for="company" class='choosemethod'>My Company</label><br/>
  <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>

<div class='paymentmethods subcontent' ng-switch on="paymentmethod">
  <select ng-model='selectedmethod' ng-init="selectedmethod=Memethods[0]" id='methods' ng-switch-when='Y'>
    <option ng-repeat="method in Memethods" value="{{method}}">{{method}}</option>
  </select>

  <select ng-model='selectedmethod' ng-init="selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
    <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
  </select>

  <div class='clear'></div>
  <label for ='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
</div>

In js:

$scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
$scope.companies = ['Company Paid','MyAMEX'];

it shows fine in page, but when I try to get the value, it shows undefined. any idea?

1
  • 1
    Have you looked into setting up the select options with the ng-options directive? Then you don't have to generate the options tags yourself, and it has other advantages as well. I found it to be easier than I expected once I tried it. The docs can explain it far better than I can: docs.angularjs.org/api/ng/directive/ngOptions Commented Feb 24, 2015 at 18:16

3 Answers 3

10

This is the classic "angular dot notation" issue.

Here is a working example

Basically, ng-switch creates a new scope, so when the select sets the selectedmethod property, it is doing so on the new scope, not the controller scope as you are expecting. One solution is to create a parent object for your model.

angular.module('app',[])
.controller('main', function($scope){
  $scope.selection = {};
  $scope.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
  $scope.companies = ['Company Paid','MyAMEX'];
})

and note how it's referenced differently in the html:

<select ng-model='selection.selectedmethod' ng-init="selection.selectedmethod=companies[0]" ng-switch-when='N' style='float:left'>
  <option ng-repeat='companyoption in companies' value="{{companyoption}}">{{companyoption}}</option>
</select>

A different (maybe better) way would be to use the "ControllerAs" syntax, which has the effect of doing this for you.

angular.module('app',[])
    .controller('main', function($scope){

      this.Memethods = ['Same as Card/Account Name','American Express','American Express Corp','Cash','Checking','MasterCard','My Visa','VISA'];
      this.companies = ['Company Paid','MyAMEX'];
    })

<body ng-app="app" ng-controller="main as main">
  <div class='subcontent'>
    <input id="me" type="radio" class='choosemethod' ng-model="paymentmethod" value="Y">
    <label for="me" class='choosemethod'>Me</label>
    <input id="company" type="radio" ng-model="paymentmethod" value="N" class='choosemethod'>
    <label for="company" class='choosemethod'>My Company</label>
    <br/>
    <span class='helptext'>Who makes payments to this account?</span><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>
  </div>

  <div class='paymentmethods subcontent' ng-switch on="paymentmethod">
    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.Memethods[0]" id='methods' ng-switch-when='Y'>
      <option ng-repeat="method in main.Memethods" value="{{method}}">{{method}}</option>
    </select>

    <select ng-model='main.selectedmethod' ng-init="main.selectedmethod=main.companies[0]" ng-switch-when='N' style='float:left'>
      <option ng-repeat='companyoption in main.companies' value="{{companyoption}}">{{companyoption}}</option>
    </select>

    <div class='clear'></div>
    <label for='methods'>Payment Method</label><span class='help' style='margin-left:20px;width:20px;height:20px;'>help</span>

  </div>
  <div>{{main.selectedmethod}}</div>
</body>
Sign up to request clarification or add additional context in comments.

3 Comments

This is what I need, I thought it could be scope problem, but couldn't know where and why. Thanks man!
Well explained, though I believe your code example for the "controller as" syntax is not 100% correct - don't you need to change the rest of the references to Memethods and companies to be main.Memethods/main.companies? Anything that is a property of the controller instance is only available on the scope via the scope property, which in this case is "main".
That's what I get for putting an answer together on an ipad. Edited. Thx
1

you can refer to this simple example

html code :

<div ng-controller="Main" ng-app>
    <div>selections = {{selections}}</div>

    <div>
      <p>Model doesn't get updated when selecting:</p>
      <select ng-repeat="selection in selections" ng-model="selection" ng-options="i.id as i.name for i in items">
        <option value=""></option>
      </select>
    </div>

js code:

function Main($scope) {

    $scope.selections = ["", "id-2", ""];

    $scope.reset = function() {
        $scope.selections = ["", "", ""];
    };

    $scope.sample = function() {
        $scope.selections = [ "id-1", "id-2", "id-3" ];
    }

    $scope.items = [{
        id: 'id-1',
        name: 'Name 1'},
    {
        id: 'id-2',
        name: 'Name 2'},
    {
        id: 'id-3',
        name: 'Name 3'}];
}

Comments

1

The ng-model inside value must have Initialize before it represents. So the ng-init comes before the ng-model. inside the options $first is used for select the first value.

<select ng-init= "selectedmethod=companies[0]" ng-model='selectedmethod' ng-switch-when='N' style='float:left'>
    <option ng-repeat='companyoption in companies' value="{{companyoption}}" ng-selected="$first">{{companyoption}} 
    </option>
</select>

Comments

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.