Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the selected item in angularJS select directive

Tags:

I have a problem with setting the selected item in angular's select directive. I don't know if this is a bug or a conscious design from the designers of angular. It sure makes the select directive a lot less useful though.

Description:

My app communicates with a REST API to receive an entity from the database. The API dictates that relations of the object are sent with an ID property only so that you can retrieve them in subsequent requests if needed.

Example:

{ id : 1, customerName : "some name", city : {id : 12}} 

where city is another entity that can be retrieved through a different REST endpoint using the city id and looks like so:

{ id: 12, name : "New York"}

I need to create a form to edit the customer entity with a dropdown menu with all possible cities so that the user can select the appopriate city from the list. The list must initially display the customer's city as retrieved from the JSON object.

The form looks like this:

 <form>
  <input type="text" ng-model="customer.name"/>
  <select ng-model="customer.city" ng-options="i as i.name for i in cities"></select>
 </form> 

And the controller looks like this:

app.controller('MainCtrl', function ($scope, $http) {
    $http.get(serviceurl + 'admin/rest/customer/' + id + "/", {
        params: {"accept": "json"},
        withCredentials: true
    }).then(function (response) {
                $scope.customer = response.data.item;
            });
    $http.get(serviceurl + 'admin/rest/city/', {
        params: {"accept": "json"},
        withCredentials: true
    }).then(function (response) {
                $scope.cities = response.data.items;
                // THIS LINE LOADS THE ACTUAL DATA FROM JSON
                $scope.customer.city = $scope.findCity($scope.customer.city);
            });
    $scope.findCity = function (city) {
        for (var i = 0; i < $scope.cities.length; i++) {
            if ($scope.cities[i].id == city.id) {
                return $scope.cities[i];
            }
        }
    }
});

What should happen: once the full details of the City object are loaded the select directive must set the city that was loaded as the selected item in the list.

What happens: the list displays an empty item and there's no way to initialize the selected item if the selected item from objects outside the array of items.

DEMO of the issue here: http://plnkr.co/edit/NavukDb34mjjnQOP4HE9?p=preview

Is there a solutions for this? Can the selected item be set programmatically in a generic way so that the AJAX calls and select logic be refactored into a reusable AJAX based select widget ?

like image 995
javito Avatar asked Mar 10 '13 18:03

javito


People also ask

How do I set default value in ng-options?

Use ng-init to set default value for ng-options .

What is Ng selected?

Definition and Usage. 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 .

Which directive is used to assign values to the variables in AngularJS?

ng-init directive It is used to declare and assign values to the variables for an AngularJS application.

How do I filter with Ng-options?

In AngularJS when you are using ng-options, you can filter out the options by calling a custom function you have in the controller. Let's say you have following set of employees and when you display all these employees inside HTML select using ng-options, you can see all the employees in a dropdown.


1 Answers

It is as simple as this

<select
    ng-model="item"
    ng-options="item.name for item in items track by item.name">

Then inside you controller:

// all items
$scope.items = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
// set the active one
$scope.item = {name: 'b'};
// or just
$scope.item = $scope.items[1]

Check out the http://docs.angularjs.org/api/ng.directive:select From there:

trackexpr: Used when working with an array of objects. The result of this expression will be used to identify the objects in the array. The trackexpr will most likely refer to the value variable (e.g. value.propertyName).

The rest is just assigning a value to the $scope.item variable and angular will figure out which element should be set as active by checking the item's name property.

like image 55
simo Avatar answered Sep 18 '22 18:09

simo