Jbird
Jbird

Reputation: 2886

How do I define select option values in AngularJS

...while maintaining model bindings?

I have a select menu like so:

<select class="form-control" ng-model="activeTask" ng-options="task.title for task in tasks"> </select>

That populates some text like so:

<span>{{activeTask.title}}</span>

The Projects resource grabs some json here (which is working fine):

function TimerCtrl($scope, Projects) {
    $scope.projects = Projects.get({}, {isArray:true}, function(projects) {
        $scope.tasks = $scope.projects[0].tasks;
        $scope.activeProject = $scope.projects[0];
        $scope.activeTask = $scope.tasks[0];
    });
}

This is the Projects service (which is working fine as well):

angular.module('projectServices', ['ngResource']).
factory('Projects', function($resource) {
    return $resource('data/projects.json', {}, {
        get: {method:'GET', isArray:true}
    });
});

and this is the JSON (which is also fine):

[
    {
        "title":"Chores",
        "url_title":"chores",
        "category":"Home",
        "tasks": [
            {"title":"Cleaning", "url_title":"cleaning"},
            {"title":"Yard Work", "url_title":"yard_work"},
            {"title":"Walking the Dogs", "url_title":"url_title"}
        ]
    },
    {
        "title":"Personal Website",
        "url_title":"personal_website",
        "category":"Work",
        "tasks": [
            {"title":"Design", "url_title":"design"},
            {"title":"Front End Dev", "url_title":"front_end_dev"},
            {"title":"Node Dev", "url_title":"node_dev"},
            {"title":"PHP Dev", "url_title":"php_dev"}
        ]
    }
]

Everything works fine with the numeric values that Angular automatically creates. My problem is...the values need to be the url-friendly string task.url_title but the option text should be task.title.

Any help would be greatly appreciated. I want to go drink a beer!

So, here's the solution I went with:

I used the task object itself as the value like so:

<select class="form-control" ng-model="activeTask" ng-options="task as task.title for task in tasks">

This allowed me to easily bind the span value to display the task title, not url_title:

<span>{{activeTask.title}}</span>

Thanks to @sza for his pointing me in the right direction. His suggestions are in the comments of the correct answer.

Upvotes: 0

Views: 231

Answers (2)

zs2020
zs2020

Reputation: 54541

You can change the comprehension expression to

ng-options="task.url_title as task.title for task in tasks"

Working Demo

Upvotes: 1

matsko
matsko

Reputation: 22223

You need to use ng-options="...". Also use ng-model="..." or otherwise it won't work.

Here's the breakdown of it:

<select ng-options="ITEM.VALUE as ITEM.LABEL for ITEM in ITEMS" ng-model="val">
  <option>placeholder value which goes at the top of the element</option>
</select>

Upvotes: 0

Related Questions