Using ng-options to get attribute in array - angularjs

js-fiddle: https://jsfiddle.net/4z5ufbuu/
I'm trying to select a value from an array I have via a select option. here are my options:
$scope.categories = [
{ type: "Web Application", cssClass: "webApplication" },
{ type: "Unity", cssClass: "unity" },
];
$scope.filterValue = "";
I have it so the select displays the "type" but I want the "filterValue" to represent the cssClass.
I have seen this page:
https://stackoverflow.com/a/12384319/9132034
but dont really understand this answer:
obj = { '1': '1st', '2': '2nd' };
<select ng-options="k as v for (k,v) in obj"></select>
guidance would be absolutely perfect or even the solution but that is up to you :)

You need to update your ng-options to be:
ng-options="item.cssClass as item.type for item in categories track by item.cssClass"
This is saying to use item.cssClass as the value while displaying type as the label
it is documented in the angularjs official documentation https://docs.angularjs.org/#ngOptions-info
Edit: updated JS Fiddle https://jsfiddle.net/4z5ufbuu/4/

Related

ng-options selected data return object

I have a array of object { id:x, name: 's' } and using ng-options to create drop down with default selected data. This is working fine so far.
Now when I select one of the option and see the selected data, it return complete object but i need only name field as well as default value must be selected on load.
// in controller
vm.teams = [
{
id: 1,
name:'First'
},
{
id: 2,
name:'Second'
},
{
id: 3,
name:'Third'
}
];
vm.teamFormData = {
team: ''
};
vm.getTeam = function(formData) {
$log.debug(formData); << here I get object
}
// in View
<select ng-init="vm.teamFormData.team = vm.teams[0]"
ng-model="vm.teamFormData.team"
ng-options="t.name for t in vm.teams track by t.id" >
</select>
Here is my working plunker
Your ngOptions syntax is slightly off - it's value as text for item in array
ng-options="t.name as t.name for t in vm.teams track by t.id"
And your ngInit then becomes
ng-init="vm.teamFormData.team = vm.teams[0].name"
Side note - you probably don't want ngInit - there's no real use case in your above example for it. Instead, just set the property in the controller.
See plunkr: https://plnkr.co/edit/7SGIdtfjucMnMqiEa7JY?p=preview

AngularJS: refresh ng-options when property source object changes

Full description:
I have list of options with multiple properties (not just key-value pair):
[
{
id: 1,
name: "111",
some: "qqq"
},
{
id: 2,
name: "222",
some: "www"
}
];
And select defined as:
<select name="mySelect" id="mySelect"
ng-options="option.name for option in opts track by option.id"
ng-model="mod1"></select>
Depending on app logic, extra property may change:
{
id: 2,
name: "222",
some: "www1"
}
But actual list in Select doesn't change!
However, if name changes, then entire optionList will be refreshed.
In short you can see demo on JSFiddle OR JSFiddle. I prepared 2 very similar examples:
When button is clicked only extra property updates
When button is clicked - both extra property and key receive new value
Does anybody know solution?
UPDATE
For now I'm solving that issue with update + delay + update solution:
this.click = function(){
$scope.opts = {};
$timeout(function() {
$scope.opts = { /* NEW OBJECT */};
}, 0);
}
OK, so I think I understand what you want, which is to be able to select an option whose nested values may have changed since the list was rendered in the DOM.
Based on that understanding, I believe that the plunker I have created illustrates a solution for you. If you select one of the options, and change the child value in the input field, two-way binding will update the model.
Basically, it is taking the users selection, and on select change, re-assigning the selected object to reference the original option in the options array. This will allow two-way binding to occur. If you view the code, you will see that the input fields are updating the option list itself ($scope.options), where-as the model that is being displayed is $scope.formData.model.
https://plnkr.co/edit/DLhI7t7XBw9EbIezBCjI?p=preview
HTML
<select
name="mySelect"
id="mySelect"
ng-model="formData.model"
ng-change="onChange(formData.model)"
ng-options="option.name for option in options track by option.id"></select>
SELECTED CHILD: {{formData.model.child.name}}
<hr>
<div ng-repeat="option in options">
Child Name for {{ option.name }}: <input ng-model="option.child.name">
</div>
JS
$scope.onChange = function(option) {
angular.forEach($scope.options,function(optionItem){
if (optionItem.id == option.id){
$scope.formData.model = optionItem;
}
})
}
$scope.options = [
{
id: 1,
name: "111",
child: {
id: 11,
name: "111-1"
}
},
{
id: 2,
name: "222",
child: {
id: 22,
name: "222-1"
}
}
];
$scope.formData = {
model: $scope.options[0]
};
Call $apply whenever you want to apply changes made.
$scope.$apply();
This will tell AngularJS to refresh.

Kendo DropdownList and ng-model doesn't work

I have a Kendo Dropdownlist bound to an ObservableArray/DataSource. It duly fills the values from array. But when I bind ng-model to a property, the dropdownlist fails to select the value.
HTML:
<select kendo-drop-down-list k-options="dropOptions" ng-model="user.id"></select>
JS:
var users = [
{ id: 1, name: 'A' },
{ id: 2, name: 'B' },
{ id: 3, name: 'C' },
{ id: 4, name: 'D' },
{ id: 5, name: 'E' },
{ id: 6, name: 'F' }
];
var usersDataSource = new kendo.data.ObservableArray(users);
$scope.dropOptions = {
dataSource: usersDataSource,
dataTextField: 'name',
dataValueField: 'id',
optionLabel: "Select one..."
};
$scope.welcome = "World";
$scope.user = { id: 3 }
$scope.user = { id: 3 } should force dropdownlist to select C.
Here is link to Plunkr:
http://plnkr.co/edit/BxTqWet5sz725ZtKEKJr?p=preview
How can I for dropdownlist to make selection based on value assigned in property bound with ng-model. I have used k-ng-model as well, but it doesn't work. Please help me what am I doing wrong here. Thank you.
Edit: The selection in dropdownlist is not hardcoded. It will be fetched from database.
I was using Angular 1.4.9 with Kendo v2015.3.1111. Downgrading to Angular 1.4.8 made it work.
I got a solution that works.
<select kendo-drop-down-list
k-options="odsSoluciones"
k-data-text-field="'descripcion'"
k-data-value-field="'solucionId'"
k-value="prescDPIntercambio.solucionDPId"
ng-model="prescDPIntercambio.solucionDPId">
</select>
$scope.odsSoluciones =
dataSource: new kendo.data.DataSource({
data: solucionesModel.data,
}),
};
In my case odsSoluciones returns an array with "solucionId" and "descripcion" fields and prescDPIntercambio.solucionDPId is the value I want to see selected
Kendo dropdown value does not reflect selection based on ng-model. Instead it provides a new attribute : k-ng-model
For a basic example, have a look at this: k-ng-model
Just add k-value = "user.id"to the template.
Working Plunker
<div ng-controller="AppCtrl">
<h1>Hello {{ welcome }}!</h1>
<div>Selected value is {{ user.id }}</div>
<select kendo-drop-down-list
k-options="dropOptions"
ng-model="user.id"
value= 3
class="glow"></select>
</div>
There is a wierd situation where when I declare the ng-model as an object for example $scope.abc.xyz = "test" ,the bind works whereas if I do $scope.abc = "test" , the bind does not work.
Not sure what the issue is :)

Setting default value in select drop-down using Angularjs

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.

How to sort object data source in ng-repeat in AngularJS?

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;
}
});

Resources