Print child elements as ng-options of an AngularJS select - javascript

I am iterating through an array of food items and printing out a select for each one. I want to populate the options of the select from child elements of the array. I am trying to do it like this:
<div ng-controller="MyCtrl">
<div ng-repeat="food in foodlist"> {{food.name}}
<select ng-options="unit.title as unit in food.unit" ng-model="unit" ng-change="update()"></select>
{{unit.name}}
</div>
</div>
The foods look like this:
{code: 1, name: 'Yoghurt', "unit":[
{"title":"bottle",
"gram":"45",
"max":"100"
},
{"title":"cup",
"gram":"250",
"max":"12"}
]},
This prints out the title of each food fine, but prints nothing into the selects.
See JSFiddle
I guess that I am calling the child elements incorrectly. Can anyone tell me how to do this correctly?

You have an error in your ng-options. Try this:
<select ng-options="unit.title for unit in food.unit" ng-model="unit" ng-change="update()"></select>
Using 'as' in your expression will allow you to specify what is displayed as the text part of the option. You still need the 'for' part of the statement which is the variable crated for each item in the collection food.unit.
Hope this helps!

Use ng-options like: ng-options="unit.title as unit.title for unit in food.unit"
Also you can use ng-init to avoid empty combo on start:
HTML
<div ng-controller="MyCtrl">
<div ng-repeat="food in foodlist">{{food.name}}
<select
ng-options="unit.title as unit.title for unit in food.unit"
ng-model="unit"
ng-change="update()"
ng-init="unit = food.unit[0].title"
></select>{{unit.name}}</div>
</div>
Demo Fiddle

I populated my drop-down menu in this way.
<html>
<select ng-model="myModel" ng-options="direction for direction in directionOptions"></select>
<controller>
var Directions = ['UP', 'DOWN', 'LEFT', 'RIGHT'];
$scope.directionOptions= Directions;
You can specify what value you want displayed in the drop-down menu by editing the first 'direction' in the ng-options.

Related

Angularjs object-property

I am using this Angular Module but I can not get the work with nested data.
Here is my PLUNKR my output shows country when using object-property="country but when I try to show only states, it doesn't work.
<div class="mrg-top50">
<label>1. Autocomplete field - options list as array of objects</label>
<multiple-autocomplete ng-model="skills" object-property="country" suggestions-arr="skillsList"></multiple-autocomplete>
<label>Selected Model Value : <br />
</label>
{{skills}}
</div>
I could do it in your fiddle like this:
<multiple-autocomplete ng-model="skills" object-property="labels" suggestions-arr="skillsList[0].states"></multiple-autocomplete>
Though this is really dependent on the [0] index , which means only useful when you have just one element in the given array like in the given example.

AngularJS multi-select using ng-repeat

I'm new to AngularJS and JavaScript. I've come up with a way to build a multi-select list, which is working. The ng-model associated with the dropdown is part of a "user" DTO object, specifically a member which contains an array of "groups" the user can belong to. The "master list" of possible groups are read from a database table using a webservice, put in an array and this is what's used to build the dropdown when the page is displayed.
Those elements in the list that are included in the "groups" field of the user object are displayed below the dropdown in a "preview" field. That's all working - if a user has two selected groups, they come up in that pre-field when the page is populated... but I don't understand why these groups are not highlighted in the dropdown. Sometimes they are...like sometimes when I refresh the page, but most of the time when the page is displayed and populated from the user information, these groups contained in the user are not highlighted in the dropdown.
Here's how the code is set up (again, I'm new to AngularJS/JavaScript and webservices so bear with me).
The HTML code is like this:
<div class="form-group">
<label for="Groups" class="col-sm-2 control-label">Group Memberships: </label>
<div class="col-sm-10">
<select name="userGroups" id="userGroups" ng-model="user.userGroups" multiple style="width: 300px;">
<option ng-repeat="group in approverGroups" value="{{group.name}}" selected >{{group.name}}</option>
</select>
<pre>{{user.userGroups.toString()}}</pre>
</div>
</div>
The JavaScript side looks like this. The "get" is used to read all possible groups from a table, and that populates the dropdown:
$http({
method : 'GET',
url : '/pkgAART/rs/ApproverGroupService/approvergroups',
data : {
applicationId : 3
}
}).success(function(result) {
// Create an array from the groups for use
// in the multi-select UI component for groups
var arr = [];
for (var i = 0; i < result.approvergroup.length; i++) {
var id = result.approvergroup[i].approverGroupId;
var value = result.approvergroup[i].name;
var pair = {id : id, name : value };
arr.push(pair);
}
$scope.approverGroups = arr;
});
Here's a screenshot of the page. This is how it looks:
So again, it works, and "SOMETIMES" when I pull up the page, the items listed in the lower <pre> box are actually highlighted in the dropdown, but not often. I don't understand how to ensure they come up highlighted. In the picture I manually clicked these elements. But if I refresh the page, sometimes they are and sometimes they are not.
I think I figured it out. Per Peter's suggestion I changed to ng-options for the dropdown, but modified the array that I use as my options to just use the name string. Here's the HTML
<div class="form-group">
<label for="Groups" class="col-sm-2 control-label">Group Memberships: </label>
<div class="col-sm-10">
<select name="userGroups"
id="userGroups"
ng-model="user.userGroups"
multiple="true"
style="width: 300px;"
ng-options="group for group in approverGroups">
</select>
<pre>{{user.userGroups.toString()}}</pre>
</div>
</div>
and the js file that builds up the array of strings looks like this:
$http({
method : 'GET',
url : '/pkgAART/rs/ApproverGroupService/approvergroups',
data : {
applicationId : 3
}
}).success(function(result) {
// create an array from the groups for use
// in the multi-select UI component for groups
var arr = [];
for (var i = 0; i < result.approvergroup.length; i++) {
var value = result.approvergroup[i].name;
arr.push(value);
}
$scope.approverGroups = arr;
});
It's now showing the multi-select list's items as selected if they are contained in "user.userGroups"
Mark
I think I figured it out.
First off, you should use ng-options in the select instead of ng-repeat on <option>. This makes it so the options are bound to the model of the select.
Check out this fiddle: http://jsfiddle.net/mcxqjngm/3/
Here is the relevant select html:
<select
name="userGroups"
id="userGroups"
ng-model="user.userGroups"
multiple="true"
style="width: 300px;"
ng-options="group.name for group in approverGroups track by group.id">
</select>
The button mimics an ajax call. I gotta run, but I can answer questions in a bit.

Initializing select with AngularJS and ng-repeat

I'm trying to get select-box to start off with a pre-filled option using ng-repeat with AngularJS 1.1.5. Instead the select always starts out with nothing selected. It also has an empty option, which I don't want. I think that there is a side effect of nothing being selected.
I can get this working using ng-options instead of ng-repeat, but I want to use ng-repeat for this case. Although my narrowed down example doesn't show it, I also want to set the title attribute of each option, and there is no way to do that using ng-options, as far as I know.
I don't think this is related to the common AngularJs scope/prototypical inheritance issue. At least I don't see anything obvious when inspecting in Batarang. Plus, when you pick an option in the select with the UI, the model does update correctly.
Here's the HTML:
<body ng-app ng-controller="AppCtrl">
<div>
Operator is: {{filterCondition.operator}}
</div>
<select ng-model="filterCondition.operator">
<option
ng-repeat="operator in operators"
value="{{operator.value}}"
>
{{operator.displayName}}
</option>
</select>
</body>
And the JavaScript:
function AppCtrl($scope) {
$scope.filterCondition={
operator: 'eq'
}
$scope.operators = [
{value: 'eq', displayName: 'equals'},
{value: 'neq', displayName: 'not equal'}
]
}
JS Fiddle for this : http://jsfiddle.net/coverbeck/FxM3B/2/
OK. If you don't want to use the correct way ng-options, you can add ng-selected attribute with a condition check logic for the option directive to to make the pre-select work.
<select ng-model="filterCondition.operator">
<option ng-selected="{{operator.value == filterCondition.operator}}"
ng-repeat="operator in operators"
value="{{operator.value}}">
{{operator.displayName}}
</option>
</select>
Working Demo
For the select tag, angular provides the ng-options directive. It gives you the specific framework to set up options and set a default. Here is the updated fiddle using ng-options that works as expected: http://jsfiddle.net/FxM3B/4/
Updated HTML (code stays the same)
<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>
The fact that angular is injecting an empty option element to the select is that the model object binded to it by default comes with an empty value in when initialized.
If you want to select a default option then you can probably can set it on the scope in the controller
$scope.filterCondition.operator = "your value here";
If you want to an empty option placeholder, this works for me
<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
<option value="">Choose Operator</option>
</select>
Thanks to TheSharpieOne for pointing out the ng-selected option. If that had been posted as an answer rather than as a comment, I would have made that the correct answer.
Here's a working JSFiddle: http://jsfiddle.net/coverbeck/FxM3B/5/.
I also updated the fiddle to use the title attribute, which I had left out in my original post, since it wasn't the cause of the problem (but it is the reason I want to use ng-repeat instead of ng-options).
HTML:
<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator">
<option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option>
</select>
</body>
JS:
function AppCtrl($scope) {
$scope.filterCondition={
operator: 'eq'
}
$scope.operators = [
{value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah'},
{value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'}
]
}
As suggested you need to use ng-options and unfortunately I believe you need to reference the array element for a default (unless the array is an array of strings).
http://jsfiddle.net/FxM3B/3/
The JavaScript:
function AppCtrl($scope) {
$scope.operators = [
{value: 'eq', displayName: 'equals'},
{value: 'neq', displayName: 'not equal'}
]
$scope.filterCondition={
operator: $scope.operators[0]
}
}
The HTML:
<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator.value}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>
If you are using md-select and ng-repeat ing md-option from angular material then you can add ng-model-options="{trackBy: '$value.id'}" to the md-select tag ash shown in this pen
Code:
<md-select ng-model="user" style="min-width: 200px;" ng-model-options="{trackBy: '$value.id'}">
<md-select-label>{{ user ? user.name : 'Assign to user' }}</md-select-label>
<md-option ng-value="user" ng-repeat="user in users">{{user.name}}</md-option>
</md-select>

angular js array of objects for select with ngOptions

I have a character which can contain multiple skills.
Skills are available from an injected service.
What I basically want is this:
<div ng-repeat="skill in character.getSkills()">
<select ng-model="skill" ng-options="select as s.toString() for s in getAllSkills()"></select>
<button ng-click="character.removeSkill(skill)" >Remove Skill</button>
</div>
With this code, the select box doesn't work as I would expect it. Skills are not set in the character, and selections are not kept in the drop down.
Am I missing something?
Thanks in advance,
roemer
After all, I'm referencing the skill in the character.skills array by the $index property in the child scope:
<select ng-model="character.skills[$index]" ng-options="sk as sk.toString() for sk in getAllSkills()"></select>

Empty first element in dropdown list

I am quite a beginner with AngularJS and currently I am working on a web application in Django where I use AngularJS for the frontend part i can say. My problem is that the dropdown list which is populated with objects from a scope always start with a blank element (if i select one from the list, the issue is gone). This create problems because if the user doesn't select anything the POST request normally it will not work anymore. I would like to know how to have something like a preselected value or something similar. Here's part of my code:
Select tag:
<select id="sel" class="input-block-level" ng-model="list_category">
<option ng-repeat="obj in list_categories.data" value="{{obj.id}}">{{obj.name}}</option>
<option value="Other">Other</option>
</select>
$scope.list_categories:
var listcategoryPromise = ListCategory.get();
listcategoryPromise.then(function(response) {
$scope.list_categories = {
meta : response.data.meta,
data : response.data.objects
};
});
Use the directive ng-options and remove the value from the 'Other' option, like this:
<select id="sel" class="input-block-level" ng-model="list_category" ng-options="obj.id as obj.name for obj in list_categories.data">
<option value="">Other</option>
</select>
This ensures that if list_category is empty (no entry selected), the 'Other' option is selected (by default).
jsFiddle: http://jsfiddle.net/bmleite/gkJve/
Find the below working example below you should avoid ng-repeat with options
so please see below sample code with
<body ng-controller="testcontroller">
<select ng-model="item" ng-options="item.ID as item.Title for item in items">
</select>
<span>{{item}}</span>
</body>
App.controller('testcontroller', function ($scope) {
$scope.item = '000001';
$scope.items = [
{ ID: '000001', Title: 'Chicago' },
{ ID: '000002', Title: 'New York' },
{ ID: '000003', Title: 'Washington' }
];
});
You can use a specific syntax for <select> tags with Angularjs.
Inspired from the documentation page:
<select id="sel" class="input-block-level" ng-model="list_category" ng-options="obj.name for obj in list_categories.data">
<option value="Other">Other</option>
</select>
Here's some code directly from the AngularJs.org website about select lists:
<select ng-model="color" ng-options="c.name for c in colors"></select>
First, as you can see, you don't need to use the ng-repeat to build your options list. Angular is going to basically let you do a foreach loop on a collection to build your option list. Second, you have the ng-model which is on the select, but isn't the same as your collections name. This is going to be your item which is actually collected at post time .
function MyCntrl($scope) {
$scope.colors = [
{name:'black', shade:'dark'},
{name:'white', shade:'light'},
{name:'red', shade:'dark'},
{name:'blue', shade:'dark'},
{name:'yellow', shade:'light'}
];
$scope.color = $scope.colors[2]; // red
}
Okay, and here's the javascript controller code. $scope.colors is the collection and $scope.color is the model property which has been assigned to the select list in the html. As you can see from this example the model property is being given a default starting value of the third option in the array. For you, this can be set from the http.get you're using for loading up your page initally.
Now when you're doing the foreach, you're basically grabbing the 'name' value from the collection and you're saying 'show this value' in the dropdown and use this value on the post. By having that inital model property set, you should be able to avoid having an empty option field in your drop down list.
Reference: AngularJS Select
in my opinion this answer is cleaner:
$scope.form = {type : $scope.typeOptions[0].value};
http://jsfiddle.net/MTfRD/2010/
The Blank empty option on top of drop down will appear if you have set ng-model with some value which is not contained in the list options created after the ng-Repeat.
Now if you consider the original post and remove the ng-model or set some valid value in ng-model, it will work fine
or you can set selected first item as
$scope.list_category = $scope.list_categories.data[0].id;

Categories

Resources