ngOptions two level object display - javascript

I have this structure:
model = [
{
name: 'name1',
items: [
{
name: 'subobj1'
},
{
name: 'subobj2'
}]
},
{
name: 'name2',
items: [
{
name: 'subobj1'
},
{
name: 'subobj2'
}]
},
....
]
Question is: How do I write ngOptions attrbiute to output this object like this?:
<select>
<optgroup label="name1">
<label>subobj1</label>
<label>subobj2></label>
</optgroup>
....
</group>
Also - ngRepeat is not an option. I have to do this ngOptions alone for plugin being used to work.

ngOptions doesn't support multi-dimensional arrays. You must flatten your array first.
Read more in this answer.
I used a filter:
app.filter('flatten' , function(){
return function(array){
return array.reduce(function(flatten, group){
group.items.forEach(function(item){
flatten.push({ group: group.name , name: item.name})
})
return flatten;
},[]);
}
})
And the markup:
<select ng-model="select"
ng-options="item.name
group by item.group
for item in model | flatten"></select>

<select>
<option ng-repeat-start="m in model" ng-bind="m.name"></option>
<option ng-repeat-end ng-repeat="item in m.items" ng-bind="item.name"></option>
</select>
You might add something like style="font-weight: bold;" on the first option (which is the group label, by the way) and something like style="padding-left: 15px;" on the second option line, which is another repeat for all the first option line.
So basically by doing this you just add 2 levels (without optgroup tag, mind you) to your select.

Related

convert ng-repeat to ng-option error

I have this following html code for select tags.
<option ng-repeat="option in AllData" value="{{item.Id}}" ng-selected="data.Symbol==item.Id">{{item.Symbol}}</option>
I want to convert this to ng-options. can someone please shed some light on this.
the value of AllData is as follows. It is an array of objects.
0:Object
Id: 1
Symbol: "GR"
1:Object
Id: 2
Symbol: "DR"
I tried something like this but was not successful.
ng-options="item as item .Symbol for item in AllData track by item.Id">
Try this
<select ng-options="option as option.Symbol for option in AllData">
</select>
when using ngOptions, you have to also bind ng-model with the initial value of select.
mention that since you used track by item.Id, the default value should at least contains property Id and meets the one of the items Id property.
refer the below sample:
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.AllData = [{
0: Object,
Id: 1,
Symbol: "GR"
}, {
1: Object,
Id: 2,
Symbol: "DR"
}];
//$scope.data = $scope.AllData[0];
$scope.data = {
0: Object,
Id: 1,
Symbol: "GR"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<select ng-model="data" ng-options="item as item.Symbol for item in AllData track by item.Id"></select> {{selectedItem}}
</div>

AngularJS How to initialize a select using ng-options with an object value

I would like to initialize a selection of a select field with ng-options.
Lets assume we've got the following items:
$scope.items = [{
id: 1,
label: 'aLabel',
subItem: { name: 'aSubItem' }
}, {
id: 2,
label: 'bLabel',
subItem: { name: 'bSubItem' }
}];
The following html:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
But now instead of selecting the option by the following command:
$scope.selected = $scope.items[0];
I do not have the object, I have only the information of the id so I like to initialize the select by something like that:
$scope.selected = $scope.otherRandomObject.id
My thought was that using track by item.id is somehow creating the relation between object and the id.
If you want to have a pre-selected value, then you can use ng-selected
<select ng-options="item as item.label for item in items" ng-selected="$first"></select>
In this case, the first item in your item array would be selected
Hope i answered your question

How to convert id as order number in ng-options group by..?

This is my code
Fiddle Link
HTML
<div ng-app ng-controller="MyCtrl">
<input type="text" ng-model = "data.name" ><br>
<input type="text" ng-model = "data.value" ><br>
<input type="text" ng-model = "data.id" ><br>
<input type="button" value="ADD" ng-click = "addIntoArr(data.name,
data.value, data.id)" ng-disabled= !data.name>
<select ng-model="selectItem" ng-options="currOption as 'order' +
(data.indexOf(currOption)+1) group by currOption.name for currOption
in data"></select>
Data : {{selectItem.name}}
</div>
Here is my Js code
function MyCtrl($scope) {
$scope.data = [{
name: "AM",
value: "11",
id: "2"
}, {
name: "PM",
value: "12",
id: "3"
}, {
name: "PM",
value: "12",
id: "23"
}, {
name: "PM",
value: "12",
id: "33"
}, {
name: "AMT",
value: "13",
id: "33"
}, {
name: "WAT",
value: "14",
id: "21"
}];
$scope.addIntoArr = function (name, value, id) {
$scope.data.push({
name: name,
value: value,
id: id
});
}
$scope.selectItem = $scope.data[0];
}
Here is my array I was using label AM, PM, AWT, WAT. and each has a order (Please check fiddle link). I want each label order show with number like order1 in AM, order1, order2, order3 in PM and so on. and if I add new entry in array then recently added entry should be shown in drop down with order number and Related label shown in Data.
You cannot use $index inside ng-options. However you can get the current index by using indexOf on the data item passing the current option.
<select
ng-model="selectItem"
ng-options="currOption as 'order' + (data.indexOf(currOption)+1) group by currOption.name for currOption in data"></select>
Demo http://jsfiddle.net/6cf3h54x/3/
I'd suggest you include some external library like lodash and format your data into more convenient structure. Then, instead of banging your head against the wall with ng-options, you could use ng-repeat.
Consider the following:
// group existing data by object's name using lodash _.groupBy
$scope.groupedData = _.groupBy($scope.data, 'name');
This gives your following data structure for groupedData, so there's key and value where key is e.g. AM and value is array of objects all having same name.
Then you could have following template for your select.
<select ng-model="selectItem">
<optgroup ng-repeat="(key, items) in groupedData" label="{{ key }}">
<option ng-repeat="item in items"
value="{{ item }}"
ng-bind="'order' + (items.indexOf(item) + 1)"></option>
</optgroup>
</select>
Which gives you what you are after, no?
You can't use $index with ng-options. Make use of indexOf instead. You can do something like this:
<select ng-model="selectItem" ng-options="currOption.id as 'order'+data.indexOf(currOption) group by currOption.name for currOption in data"></select>

How to disable dropdown list item in AngularJS?

I am a beginner to AngularJS and I am making a web app that needs to disable exiting values in a dropdown list.
I know how to do it in jQuery. It is just like this: http://jsfiddle.net/qiushibaike/FcLLn/
But I don't really know how to do it in AngularJS, Should I try to disable the item or hide it? Can I set a value
HTML
<select ng-model="numbers.value" required>
<option ng-repeat="item in items"> {{item.name}} </option>
</select><br/>
JavaScript
$scope.numbers= {};
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222'},
{ id: 3, name: '33333'}
];
If I have something like this, how can I disable or hide the option 2 and 3 by AngularJS like what I did by using jQuery?
This is also possible with ngOptions.
You just need to add "disable when" in your ng-options tag.
In your case, you can also do like this
HTML
<select ng-model="numbers.value"
ng-options="var.name as var.name disable when var.disabled for var in items" required>
<option value="">-- Select --</option></select>
Javascript
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222', disabled: true },
{ id: 3, name: '33333', disabled: true }
]
Plunkr
If you want to disable any option dynamically from your code,
here is a Plunkr : Dynamic Example.
Use Angular's ngDisabled directive.
HTML
<select ng-model="numbers.value" required>
<option ng-repeat="item in items" ng-disabled="item.disabled"> {{item.name}} </option>
</select>
Javascript
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222', disabled: true },
{ id: 3, name: '33333', disabled: true }
]

Angular JS order select using key/value

I just asked about generating a select from key/value map instead of array: AngularJS select box generated from object
That is all working fine now: http://jsfiddle.net/UPWKe/1/
<select ng-model="current.addressCode" ng-options="value.code as value.name for (key, value) in student.address | orderBy: 'code'"</select>
... and js ...
$scope.student = {
address: {
select: {
code: "0",
name: "Select proof of address"
},
letter: {
code: "1",
name: "Letter"
},
photograph: {
code: "3",
name: "Photograph"
}
},
But the only thing missing, is how to order the select items.
How can I order select items in a select box generated from key/value map in angularjs?
Solution 1: You can use another array to store the order of the fields. For this you would need to use ng-repeat in place of ng-options:
$scope.studentAddressFields = [
"select",
"letter",
"photograph"
]
HTML:
<select ng-model="current.addressCode">
<option ng-repeat="field in studentAddressFields"
value="student.address[field]['code']">
{{student.address[field]['name']}}
</option>
</select>
Solution 2: Using a filter:
HTML:
<select ng-model="current.addressCode" ng-options="code as details.name
for (code, details) in student.address | getOrdered">
</select>
Filter:
myApp.filter('getOrdered', function() {
return function(input) {
var ordered = {};
for (var key in input){
ordered[input[key]["code"]] = input[key];
}
return ordered;
};
});

Categories

Resources