Bind ng-options value and label to ng-model
Asked Answered
T

3

7

I'm using ng-options to generate a select tag whose options are locations. The labels are the location names, and the values are the location ID (in database).

I've bound the value (location ID) to an ng-model attribute, but I'd also like to bind the label (location name) to a different ng-model attribute. (I need to separate the id field since this will be POSTed to a server that expects this particular attribute.) What's the best way to do this in Angular?

My code:

<div ng-app="app"><div ng-controller="edit">
  <select ng-model="purchase.pickUpLocationId" ng-options="loc.id as loc.name for loc in purchase.availableLocations"></select>

  <!-- This is the model not yet bound: -->
  <p>You have selected {{ purchase.pickUpLocationName }}</p>

</div></div>

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

app.controller('edit', ['$scope', function($scope) {
    $scope.purchase = {
        pickUpLocationId: 30,
        availableLocations: [
            {id: 20, name: "Charleston, SC"},
            {id: 30, name: "Atlanta, GA"},
            {id: 40, name: "Richmond, VA"},
        ]
    };
}]);
Tera answered 22/4, 2015 at 16:35 Comment(0)
S
9

You can change to the following and bind to the entire object. You'll still have access to id later on for whatever you wish to do with it

<select ng-model="selected" ng-options="loc as loc.name for loc in purchase.availableLocations"></select>

<p>You have selected {{ selected.name }}</p>
<p>You havd id too! {{ selected.id }}</p>

JSFiddle Link

Schist answered 22/4, 2015 at 16:49 Comment(4)
This doesn't seem to use the default location set in the controller, even if I set $scope.purchase.selected = {id: 30, name: "Atlanta, GA" };. How should this be done?Tera
@Tera you can add something like $scope.selected = $scope.purchase.availableLocations[1];Schist
Almost, but I actually need to GET and POST the purchase object to a backend server with a pickUpLocationId field. Would I need to loop through the availableLocations to find the matching object after GETing purchase? or can I somehow bind pickUpLocationId to selected.id? or does Angular convention dictate abstracting this problem to a separate module, e.g. for data serialization?Tera
@Tera this may be a good candidate for http transformations. If you scroll down to per request transformations if you need to change your object property nameSchist
T
3

My suggestion is to model as a hash first

{
   "20": "Charleston, SC",
   "30": "Atlanta, GA"
}

and then use {{availableLocations[purchase.pickUpLocationId]}}

and make ng-options as

<select ng-model="purchase.pickUpLocationId" ng-options="id as label for (id, label) in purchase.availableLocations"></select>
Taft answered 22/4, 2015 at 16:41 Comment(3)
it should be purchase.pickUpLocationIdAnachronistic
Are you saying I should store availableLocations as a hash? How would ng-options work in that case?Tera
I have updated it. Thanks @Anachronistic for pointing out the typo, fixed it.Taft
M
0

Updated scniro answer

<div ng-app="app">
<div ng-controller="ctrl">
     <select ng-model="selected" ng-options="opt as opt.language for opt in tableResult.locales"></select>        
     <p>You have selected {{ selected.language }}</p>
     <p>You havd id too! {{ selected.localeId }}</p>
     <p>
     </p>
     <input type="text" value="{{selected.localeId}} : {{selected.language}}" style="width:50%;"/>

</div>

JSFIDDLE -Bind ng options value and label

Mortgagee answered 4/10, 2016 at 10:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.