What would be angular ng-option equivalent of this select? - angularjs

I am struggling to get this into an ng-option. Is it even possible?
<select ng-model="detail_type_id">
<optgroup ng-repeat="type in data.detailTypes" label="{{type.name}}">
<option ng-repeat="t in type.children" value="{{t.id}}">{{t.name}}</option>
</optgroup>
</select>
DetailTypes looks like this:
[
{"id":7,
"parent_id":null,
"name":"Contact",
"children":[
{"id":8,
"parent_id":7,
"name":"Address",
"children":[]
},
{"id":12,
"parent_id":7,
"name":"Something else",
"children":[]
}
]},
{"id":16,
"parent_id":null,
"name":"Other",
"children":[
{"id":10,
"parent_id":16,
"name":"Remarks",
"children":[]}
]
}
]
Child id needs to be selected. Nesting cannot be deeper.

The ngOptions directive does not work with multidimensional objects. So you need to flatten your array to use it.
I wrote a filter for that:
app.filter('flatten' , function(){
return function(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
})
And the HTML part would be like this:
<select ng-model="detail_type_id"
ng-options="item.id as item.name
group by item.groupName for item
in data.detailTypes | flatten track by item.id">
</select>
Plunker (version #1 with filter):
https://plnkr.co/edit/dxi7j8oxInv2VRJ1aL7F
I also modified your object to be like this:
[{
"id": 7,
"parent_id": null,
"name": "Contact",
"children": [{
"id": 8,
"parent_id": 7,
"name": "Address",
"children": []
}, {
"id": 12,
"parent_id": 7,
"name": "Something else",
"children": []
}]
}, {
"id": 16,
"parent_id": null,
"name": "Other",
"children": [{
"id": 10,
"parent_id": 16,
"name": "Remarks",
"children": []
}]
}]
EDIT:
After suggestion I wrote another version without the filter, but flattening the array inside the controller.
Additional Controller JS:
$scope.flattenDetailTypes = flattenDetailTypes($scope.data.detailTypes);
function flattenDetailTypes(array){
return array.reduce(function(flatten, group){
group.children.forEach(function(child){
child.groupName = group.name;
flatten.push(child)
})
return flatten;
},[]);
}
Markup:
<select ng-model="detail_type_id"
ng-options="item.id as item.name group by item.groupName for item in flattenDetailTypes track by item.id"></select>
Plunker (version #2 without filter):
https://plnkr.co/edit/D4APZ6

Related

Using ng-repeat and $index how to set default selected in select

Using ng-repeat and $index how to show default selected value using angularjs
my code :
I have SelectValues :
"Jewelery_And_Diamond_Type": [
{
"id": 33,
"value": "Earrings"
},
{
"id": 35,
"value": "Gemstones"
},
{
"id": 34,
"value": "Loose Diamonds"
},
{
"id": 32,
"value": "Necklaces"
},
{
"id": 31,
"value": "Pendants"
},
{
"id": 30,
"value": "Rings"
} ]
selected Value is "Earings"
In my HTML
<select ng-model="categoryval.Jewelery_And_Diamond_Type[$index]" ng-init="categoryval.Jewelery_And_Diamond_Type[$index] = SelectValues.Jewelery_And_Diamond_Type.indexOf(0)" ng-options="option.value for option in SelectValues.Jewelery_And_Diamond_Type track by option.id">
If I wrote like this means no value as selected by default. I need exact selected Values based on the $index.
Use ng-options
<select ng-model="value" ng-init="value='Earrings'" ng-options="mode.value as mode.value for mode in storageResult.Jewelery_And_Diamond_Type">
</select>
DEMO
In a select, ng-model will determine which option is selected.
So if you strictly want to select an item by its index in the array you need to create the object model like so:
$scope.selected = $scope.values[0];
values being your json array.
The select will then look like:
<select
ng-model="selected"
ng-options="option.value for option in values track by option.id">
</select>
Don't use ng-init in the html, it's bad practice.
function MyController() {
this.values = [
{
"id": 33,
"value": "Earrings"
},
{
"id": 35,
"value": "Gemstones"
},
{
"id": 34,
"value": "Loose Diamonds"
},
{
"id": 32,
"value": "Necklaces"
},
{
"id": 31,
"value": "Pendants"
},
{
"id": 30,
"value": "Rings"
} ];
this.selected = this.values[0];
};
angular.module('app', []);
angular.module('app')
.controller('MyController', MyController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController as ctrl">
<select
ng-model="ctrl.selected"
ng-options="option.value for option in ctrl.values track by option.id">
</select>
<br>
{{ctrl.selected | json}}
</div>
</div>
If you know the id where default selected value is available you can include it in a scope variable and inject the variable in
<option value="">{{selectedType}}</option>
$scope.selectedType= categoryval.Jewelery_And_Diamond_Type[defaultIndex].valu‌​e
value ="" helps you to fill the empty first option
Remove ng-init and set default value in controller so that you can unit test whether default option is always what you want it to be.
In controller:
$scope.defaultValue = $scope.SelectValues.Jewelery_And_Diamond_Type[0];
then change HTML
<select ng-model="defaultValue" ng-options="option.value for option in SelectValues.Jewelery_And_Diamond_Type track by option.id">
Plunker

Ng-option directive cant get access to nested array value

Help
I'm trying to output different class options(economy/business) with ng-options.
Here is the syntax and json information .
Cant get it working
<select ng-model="mySelect" ng-options="item for item in items ">
</select>
$scope.items = [
{
"id": 2,
"codeName": "class",
"friendlyName": "Class",
"options":
[
{
"id": 15,
"displayOrderNo": 0,
"optionName": "Economy"
},
{
"id": 16,
"displayOrderNo": 1,
"optionName": "Business"
},
{
"id": 36,
"displayOrderNo": 2,
"optionName": "First Class "
}
]
}
];

object nested into a nested array, how to implement a custom filter for it?

I have an application that I am constructing with a friend and we have a very big problem: I have a very big json with some nested arrays an objects, I am using a filter with an ng-model="search" the filter (search) works great with the top level array which is named sports, but once I try to search through the leagues array, the filter returns nothing. I saw in another question that I can search(filter) based on nested properties which is exactly what I want. I tried to follow the example answer on that question but I am having a problem trying to solve this. Someone else says: that is not possible with this kind of matching that you are trying because you want to filter through a matching sport.name and all of his matching and not non matching leagues or a non matching sport.name and only his matching leagues.
json
[
{
"name": "Cricket",
"leagues": []
},
{
"name": "NBA Games",
"leagues": [
{
"name": "NBA",
"sport": {
"id": 8,
"name": "NBA Earliest"
},
"lineType": "G",
"priority": [
1,
3
],
"part": "0"
}
]
},
{
"name": "COLLEGE Basketball",
"leagues": [
{
"name": "College - NCAA BASKETBALL",
"sport": {
"id": 24,
"name": "College Basketball"
},
"lineType": "G",
"priority": [
0,
4
],
"part": "0"
},
{
"name": "NCAA BASKETBALL ADDED GAMES",
"sport": {
"id": 24,
"name": "College Basketball"
},
"lineType": "G",
"priority": [
1,
4
],
"part": "0"
},
...
my html
<input type="search" ng-model="search">
<div ng-repeat="sport in sports | filter: query">
<!-- searching (filtering) great -->
<div>{{sport.name}}</div>
</div>
<div ng-repeat="league in sport.leagues | filter: query">
<!-- here is not filtering at all -->
{{league.name}}
</div>
</div>
can I do it this way I am trying or how do I implement a custom filter for this ?

Angular JS orderBy not working using dropdown

i am trying to do orderBy using dropdown value, but its not working :(
CODE:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.datas = [{
"id": "1",
"name": "name area 1"
}, {
"id": "2",
"name": "name area 2"
}, {
"id": "3",
"name": "name area 3"
}, {
"id": "4",
"name": "name area 4"
}];
$scope.dropdown = [{
"title": "Newest first",
"value": "true"
}, {
"title": "Oldest first",
"value": "reverse"
}];
});
HTML:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<ul ng-repeat="rows in datas | orderBy: 'id':orderByData">
<li>{{rows.id}} : {{rows.name}}</li>
</ul>
<select ng-model="orderByData" ng-options="x.value as x.title for x in dropdown"></select>
</div>
</div>
DEOM JS BIN
Why you use reverse?
Please use false instead reverse and it should work fine.
$scope.dropdown = [{
"title": "Newest first",
"value": "true"
}, {
"title": "Oldest first",
"value": "false"
}];
You don't need reverse parameter here. Instead you can do something like this:
<ul ng-repeat="rows in datas | orderBy: getSort()">
<li>{{rows.id}} : {{rows.name}}</li>
</ul>
Where getSort is defined as:
$scope.getSort = function() {
return $scope.orderByData ? 'id' : '-id';
};
Basically you want sort part to look like orderBy: 'id' or orderBy: '-id'.
Demo: http://jsbin.com/pepureta/1/edit?html,js,output

How to select specific option using ng-options

I am starting with an array of sources
$scope.sources = [
{
"type": "register",
"name": "Register 1",
"balance": 100
},
{
"type": "register",
"name": "Register 2",
"balance": 100
},
{
"type": "register",
"name": "Register 3",
"balance": 200
},
{
"type": "office",
"name": "Change Drawer",
"balance": 200
},
{
"type": "office",
"name": "Safe",
"balance": 500
}
];
I'm successfully loading the options
<div class="form-group">
<label>Transfer <strong>{{amount(count, start, selectedItem.balance) | currency}}</strong> To:</label>
<select id="transferTo" class="form-control" ng-model="form.to" ng-options="item.name for item in sources | filter:{type:'office'}">
<option value="">-- Select a Source --</option>
</select>
</div>
I've tried using a $timeout function to select it after it works, but it doesn't pass back the correct value to my function
$timeout(function () {
$('#transferTo').val('1');
}, 200);
How would I set the "Safe" as the default option selected when the form loads?
You will need to set a value on your scope that you're setting ng-model equal to:
$scope.form.to = $scope.sources[4];
If your list (sources) is dynamic you can filter the array like this, which will return an array (but leave your array untouched).
filterFilter($scope.sources, {name: 'Safe'})
fiddle

Resources