Not sure how else to title this. I'm using ng-options to generate a drop down. The source array is of the following form:
[{
id:1,
name: 'Bob'
},
{
id:2,
name: 'Tom'
}...(etc)
]
my ng-options looks like this:
ng-options="item.name as item.name for item in myObj
which I need since the ng-model is to the name elsewhere. However, on the ng-change, I want to send (among other things) the item.id. But I can't figure out how to access that at that point. Not only is item.id undefined in the ng-change, even item is undefined at that point. But, I can't use it in the `ng-options since I need it to model to the name elsewhere.
How do I access item.id for use in the ng-change?
This should do the trick:
item as item.name
Related
The code below show a dropdown list from using ng-repeat. When I edit this entity, I have to make them show a certain value selected already than just showing a whole list. I know that I can put selected keyword when I want to select a certain value.
Then what if I used ng-repeat to populate a dropdown? How can I make a dropdown choose a certain value using the id?
<div ng-if="field.name=='ClienteleId'" class="input-group inputFill">
<select ng-disabled="defaultSaveButtons[$index]" class="form-control inputFill2"
ng-model="field.value" ng-options="clientele.id as clientele.name for clientele in dropdown.clienteleOptions | orderBy:'name' track by clientele.id"></select>
/div>
To set the value of a <select> in AngularJS, you need to change the variable that is set as its ng-model to one of the values in your options.
In your case, you have field.value as your ng-model, and your options use the name attribute as their label and the id attribute as their value. To have one of the items in dropdown.clienteleOptions selected by default, you need to set field.value to the id attribute of the corresponding entry in dropdown.clienteleOptions.
Imagine your options and fields look like this:
$scope.clienteleOptions = [
{id: 1, name: 'test 1'},
{id: 2, name: 'test 2'}
];
$scope.fields = [
{name: 'ClienteleId', value: null}
// ...
];
In your controller somewhere, you would have something like this to have test 2 selected:
$scope.fields[0].value = 2;
Or to make it more dynamic:
$scope.fields.forEach(function (field) {
if (field.name === 'ClienteleId') {
field.value = 2;
}
});
The following code works. My question is whether this is the right way to do it.
The variable devices is an array of objects and when the user selects one the variable selDev gets set to one of those objects. If I make selDev the model via the ng-model attribute then it gets a string, not the original model.
<p>
<label>Device Id:</label>
<select ng-model="selDevIndex"
ng-change="selDev = devices[selDevIndex]">
<option value="">(no device)</option>
<option ng-repeat="device in devices "
value="{{$index}}">
{{device.id}}: {{device.type}} {{device.mfr}}
{{device.serial}}
</option>
</select>
</p>
I find this a little clumsy due to the inclusion of the $index reference. Also this technique would not work if devices was an object an not an array. Is there a better way?
You can use ng-options
HTML:
<select ng-model="selectedModel"
ng-options="device as device.text for device in devices track by device.id">
</select>
CONTROLLER:
$scope.selectedModel;
$scope.devices = [{
id: 1,
text: "Device1"
}, {
id: 2,
text: "Device2"
}];
Check this jsFiddle
If you have to loop over an object instead of an array, check this post
what is the simplest way to display a radio button and dropdown list using templating in angular js? I have a plunker where i'd like to display the radio button group(quest#4) options as dynamic values - i am not sure how to do so. I am having the same issue with the selects(quest#5) as well. Any help is much appreciated.
http://run.plnkr.co/eHxbQn2lm1uTE2JI/
I couldn't see your attempt at using a <select> in your code, so here's an abstracted example, if you had the choices like so:
.controller('AppControl', ($scope)->
$scope.answers =
q1: null
q2: null
$scope.options = {
"option 1": "val1",
"option 2": "val2"
}
)
Then you could make a radio button list would look like this:
<span ng-repeat="(key, value) in options">
<input type="radio" ng-model="answers.q1" ng-value="value"/> {{key}}
</span>
And a select would look like this:
<select ng-model="answers.q2"
ng-options="value as key for (key, value) in options">
</select>
EDIT
To answer the second part of your question below: "how do I use ng-show in this case?":
To do this, you need to add the possibility of having a "show if" type condition in your questions. If there is a condition, then you only want to show the question if that condition is met. Your HTML for each question would change to look like this:
<div ng-repeat="question in questionnaire"
ng-include="'questionnaire'"
ng-show="(question.condition == null) || {{question.condition}}"></div>
Note that you check whether a condition has been specified, and if it hasn't, then the ng-show expression would evaluate to true. If it has, we interpolate that condition so that we can use the same syntax as we would for other ng-shows.
You then just need to adjust your question to include a condition, for example:
{
number: "5",
question: "Which of the following sweets do you like?",
type: "DD",
condition: 'questionnaire[$index-1].answer != "blue"',
values :[
{ name: "hardcandy" },
{ name: "chocolate" },
{ name: "other" },
]
}
questionnaire[$index-1] refers to the previous question ($index is from ng-repeat, check the docs), and .answer only works because I have used ng-model="question.answer" when I answered your previous query. I would personally add this ng-model attribute to all of your questions.
You can see it working here: Plunker
I have an object as below. I have to display this as a drop-down:
var list = [{id:4,name:"abc"},{id:600,name:"def"},{id:200,name:"xyz"}]
In my controller I have a variable that carries a value. This value decided which of the above three items in the array will be selected by default in the drop-down:
$scope.object.setDefault = 600;
When I create a drop-down form item as below:
<select ng-model="object.setDefault" ng-options="r.name for r in list">
I face two problems:
the list is generated as
<option value="0">abc</option>
<option value="1">def</option>
<option value="2">xyz</option>
instead of
<option value="4">abc</option>
<option value="600">def</option>
<option value="200">xyz</option>
No option gets selected by default even though i have ng-model="object.setDefault"
Problem 1:
The generated HTML you're getting is normal. Apparently it's a feature of Angular to be able to use any kind of object as value for a select. Angular does the mapping between the HTML option-value and the value in the ng-model.
Also see Umur's comment in this question: How do I set the value property in AngularJS' ng-options?
Problem 2:
Make sure you're using the following ng-options:
<select ng-model="object.item" ng-options="item.id as item.name for item in list" />
And put this in your controller to select a default value:
object.item = 4
When you use ng-options to populate a select list, it uses the entire object as the selected value, not just the single value you see in the select list. So in your case, you'd need to set
$scope.object.setDefault = {
id:600,
name:"def"
};
or
$scope.object.setDefault = $scope.selectItems[1];
I also recommend just outputting the value of $scope.object.setDefault in your template to see what I'm talking about getting selected.
<pre>{{object.setDefault}}</pre>
In View
<select ng-model="boxmodel"><option ng-repeat="lst in list" value="{{lst.id}}">{{lst.name}}</option></select>
JS:
In side controller
$scope.boxModel = 600;
You can do it with following code(track by),
<select ng-model="modelName" ng-options="data.name for data in list track by data.id" ></select>
This is an old question and you might have got the answer already.
My plnkr explains on my approach to accomplish selecting a default dropdown value. Basically, I have a service which would return the dropdown values [hard coded to test]. I was not able to select the value by default and almost spend a day and finally figured out that I should have set $scope.proofGroupId = "47"; instead of $scope.proofGroupId = 47; in the script.js file. It was my bad and I did not notice that I was setting an integer 47 instead of the string "47". I retained the plnkr as it is just in case if some one would like to see. Hopefully, this would help some one.
<select ng-init="somethingHere = options[0]" ng-model="somethingHere" ng-options="option.name for option in options"></select>
This would get you desired result Dude :) Cheers
Some of the scenarios, object.item would not be loaded or will be undefined.
Use ng-init
<select ng-init="object.item=2" ng-model="object.item"
ng-options="item.id as item.name for item in list"
$scope.item = {
"id": "3",
"name": "ALL",
};
$scope.CategoryLst = [
{ id: '1', name: 'MD' },
{ id: '2', name: 'CRNA' },
{ id: '3', name: 'ALL' }];
<select ng-model="item.id" ng-selected="3" ng-options="i.id as i.name for i in CategoryLst"></select>
we should use name value pair binding values into dropdown.see the
code for more details
function myCtrl($scope) {
$scope.statusTaskList = [
{ name: 'Open', value: '1' },
{ name: 'In Progress', value: '2' },
{ name: 'Complete', value: '3' },
{ name: 'Deleted', value: '4' },
];
$scope.atcStatusTasks = $scope.statusTaskList[0]; // 0 -> Open
}
<select ng-model="atcStatusTasks" ng-options="s.name for s in statusTaskList"></select>
I could help you out with the html:
<option value="">abc</option>
instead of
<option value="4">abc</option>
to set abc as the default value.
Suppose I have the following users:
$scope.users = {
"2": {
email: 'john#gmail.com',
name: 'John'
},
"3": {
email: 'elisa#gmail.com',
name: 'Elisa'
}
}
I would like to create a <select> with the following options:
<option value="3">Elisa</option>
<option value="2">John</option>
In other words, users should be sorted by name.
I tried the following using the (key, value) in expression syntax, but it doesn't work:
<option ng-repeat="(user_id, user) in users | orderBy:'user.name'"
value="{{ user.id }}">
{{ user.name }}
</option>
Live example here.
What am I missing?
Please do not suggest solutions with ng-options as I use ui-select2 which is incompatible with ng-options.
While you would see this in the thread the author's answer references in a link, I thought it would be good to put up one of the mentioned workarounds up on SO:
It is true that this is technically not implemented, but there is an easy work around if you're willing to change your data model slightly: use a custom filter to generate an array of the object's properties (without replacement). If you add the key field to the objects ("id" in the above case), you should be able to get the behavior your looking for:
app.filter("toArray", function(){
return function(obj) {
var result = [];
angular.forEach(obj, function(val, key) {
result.push(val);
});
return result;
};
});
...
$scope.users = {
1: {name: "John", email: "john#gmail.com", id: 1},
2: {name: "Elisa", email: "elisa#gmail.com", id: 2}
};
Here's the ng-repeat directive that could be used:
<option value="{{user.id}}" ng-repeat="user in users | toArray | orderBy:'name'">{{user.name}}</option>
And here's the plunkr.
Notice that the orderBy filter takes name as its parameter and not user.name.
Unfortunately, adding the id property to your objects does create potential for mismatch with it's key in the containing object.
In the link you mentioned in your answer, there are also proposed solutions that create the id property in the user objects on the fly, but I feel like this approach is a little less messy (at the cost of introducing data replication).
OK, I found the answer:
It is not implemented yet :(
Adding to the accepted answer and seeing your data format, you should transform your data as
app.filter('myFilterUsers',function(){
return function(data)
{
var newRes = [];
angular.forEach(data,function(val,key){
val["id"] = key; //Add the ID in the JSON object as you need this as well.
newRes.push(val);
});
return newRes;
}
});