Stefan
Stefan

Reputation: 382

AngularJS Select Options Preselection

I'v some problems with preselection of a select-input in angularJS. The select-box get filled by an array.

<select class="form-control" 
ng-model="userCtrl.selected_country" 
ng-options="country.name for country in userCtrl.available_countries track by country.id">
</select>

e.g. a selected country is filled with an ID (which I get by an API).

userCtrl.selected_country = 4;

But it won't work. I also have tried to do it with options and ng-selected.

<option ng-repeat="country in userCtrl.available_countries"
ng-selected="{{ country.id == userCtrl.selected_country }}"
value="{{ country.id }}">
{{ country.name }}
</option>

Why I can't make the selection like this? THIS "works", in the source code I see at the correct option selected="true" - but on the view you don't see it... very strange.

My "solution" now is, that I fill my ng-model with the correct value of the source-array "available_countries". Unnecessary many steps?!

  1. Load data (select fills) of API
  2. Load data (addresses) of API
  3. Manipulate all referenc-IDs (like country_id, state_id) to the select-fill-objects (for preselection)
  4. User editing happens => user clicks update
  5. Change all select-fill-objects back to the reference-id
  6. Save addresses now
  7. repeat step 3

3., 5. and 7. are unnecessary if I could preselect just with an number. Is this anyhow possible?

Thanks for help :-) Stefan

Upvotes: 1

Views: 277

Answers (3)

rsobon
rsobon

Reputation: 1022

Extending @zeroglagL answer a bit.

In your example ng-options directive is used in a way telling AngularJS that both ng-model AND option should be objects with the same structure:

// JSON representation of userCtrl.selected_country is an object
{
    name: "Poland",
    id: 1 
}

// JSON representation of userCtrl.available_countries in an array of objects
[
{
    name: "Poland",
    id: 1 
}
{
    name: "USA",
    id: 2
}
]

So basically when you use:

ng-options="country.name for country in userCtrl.available_countries track by country.id"

You tell AngularJS to create option object for each country in the userCtrl.available_countries array, with country.name as a label and country.id as a value of each option. AngularJS will also assume that ng-model is going to be an object and will "bind" options with a model by id property of both objects.

So you have to build your ng-model the way I described above.

Or you can use ng-options in other way (as stated by @zeroglagL):

ng-options="country.id as country.name for country in userCtrl.available_countries"

In this approach you tell AngularJS to treat both options and ng-model as scalar ids only (and not objects). There is no need to "bind" objects by their ids anymore because AngularJS will simply compare integer values when preselecting option. This way userCtrl.available_countries can be in fact array of objects, but ng-model value (after selection or preselection) will only contain id

Upvotes: 3

a better oliver
a better oliver

Reputation: 26848

The model has to match the option's value. In your case the model is an id and the option value the whole object.

Either you make the model an object too, or you do

ng-options="country.id as country.name for country in userCtrl.available_countries"

Upvotes: 1

willoller
willoller

Reputation: 7330

To get this to work, you have to bind the ng-model to the object you want to select, not the id. So, try this:

$scope.userCtrl.selected_country = $scope.userCtrl.available_countries[4];

Upvotes: 0

Related Questions