Since I expanded my project I stumbled on a problem. This is my main object:
{
screens: [{
id: 0,
name: 'Screen0',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 1,
name: 'Screen1',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 2,
name: 'Screen2',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}]
};
The problem lays in the select tag which is being populated this way:
<select ng-model="ScreenService.config.screenConfig.current">
<option
value="{{screen.id}}"
ng-repeat="screen in ConfiguratorService.screens">
{{screen.name}}
</option>
</select>
In a separate container, but in the same controller, I am repeating sections within the screens. So I cannot do something like
ng-repeat = "screens in ConfiguratorService.screens"
ng-repeat = "sections in screens"
ng-repeat = "sectionItems in sections"
I need to repeat the sections based on the value of selected screen in dropdown. I would like to avoid repeating them all and hiding them since they are heavily populated, but it might be a last resort.
Edit: Sections and sectionItems will be repeated as ul-li
Since I expanded my project I stumbled on a problem. This is my main object:
{
screens: [{
id: 0,
name: 'Screen0',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 1,
name: 'Screen1',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 2,
name: 'Screen2',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}]
};
The problem lays in the select tag which is being populated this way:
<select ng-model="ScreenService.config.screenConfig.current">
<option
value="{{screen.id}}"
ng-repeat="screen in ConfiguratorService.screens">
{{screen.name}}
</option>
</select>
In a separate container, but in the same controller, I am repeating sections within the screens. So I cannot do something like
ng-repeat = "screens in ConfiguratorService.screens"
ng-repeat = "sections in screens"
ng-repeat = "sectionItems in sections"
I need to repeat the sections based on the value of selected screen in dropdown. I would like to avoid repeating them all and hiding them since they are heavily populated, but it might be a last resort.
Edit: Sections and sectionItems will be repeated as ul-li
Share Improve this question edited May 4, 2016 at 7:33 CountGradsky asked May 3, 2016 at 16:15 CountGradskyCountGradsky 2682 gold badges4 silver badges15 bronze badges 3- Don't know if this is good practice but you can try creating another controller – Cihan Köseoğlu Commented May 3, 2016 at 16:19
- It's possible to see the entire code of the controller markup? I'm not a guru but maybe i can be useful. – Nano Commented May 3, 2016 at 16:24
- It would be useful too : stackoverflow./questions/15256600/… – oguzhan00 Commented May 3, 2016 at 16:28
4 Answers
Reset to default 5Save your selected screen in a variable (by ng-model):
<select ng-model="selectedId">
<option
value="{{screen.id}}"
ng-repeat="screen in ConfiguratorService.screens">
{{screen.name}}
</option>
</select>
In that seperate container, set the vm with ConfiguratorService.screens[selectedId]
.
For the original ng-model
(ScreenService.config.screenConfig.current
), it can be set by ScreenService.config.screenConfig.current = selectedId
.
If I understood right, I think you are looking for something like this. You need to hook an ng-change
in the select tag, find the object related to the ID selected, and just than, create you second ng-repeat
.
This is an example:
https://jsfiddle/relferreira/ja776cej/
HTML:
<div data-ng-app="app">
<div data-ng-controller="MainController as mainVm">
<select data-ng-model="mainVm.selectedScreenIndex" data-ng-change="mainVm.select()">
<option
value="{{screen.id}}"
ng-repeat="screen in mainVm.screens">
{{screen.name}}
</option>
</select>
<ul>
<li data-ng-repeat="sectionItems in mainVm.selectedItem.sections">{{sectionItems}}</li>
</ul>
</div>
</div>
JS:
angular.module('app', []);
angular.module('app')
.controller('MainController', mainController);
mainController.$inject = ['$scope'];
function mainController($scope){
var vm = this;
vm.select = select;
vm.selectedScreen = null;
vm.selectedScreenIndex = null;
vm.screens = [{
id: 0,
name: 'Screen0',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 1,
name: 'Screen1',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}, {
id: 2,
name: 'Screen2',
sections: [{
id: 0,
sectionItems: []
}, {
id: 1,
sectionItems: []
}, {
id: 2,
sectionItems: []
}]
}];
function select(){
vm.screens.forEach(function(item){
if(item.id == vm.selectedScreenIndex){
vm.selectedItem = item;
}
});
}
}
Check whether if this works for you....
The Second select value will appear based on first selected Id. So the Second select dropdown value will e only after you select the first select dropdown.
<html>
<head>
<title>Angular JS Controller</title>
<script src = "http://ajax.googleapis./ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app = "mainApp" ng-controller = "studentController">
<select ng-model="current" ng-change="captureChange(current)" ng-options="option.id as option.name for option in screens">
</select>
<select ng-model="current123" ng-options="item.id as item.name for item in Collectval" ng-change="captureItemChange(current123)">
</select>
</div>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.controller('studentController', function($scope) {
$scope.screens= [{
id: 0,
name: 'Screen0',
sections: [{
id: 0,
sectionItems: [
{id:1, name:"Aarthi"},{id:2, name:"Roopa"}
]
}, {
id: 1,
sectionItems: [
{id:3, name:"Chitra"},{id:4, name:"Prakash"}
]
}, {
id: 2,
sectionItems: [
{id:5, name:"Lalitha"},{id:6, name:"Sekaran"}
]
}]
}, {
id: 1,
name: 'Screen1',
sections: [{
id: 0,
sectionItems: [
{id:7, name:"Vijay"},{id:8, name:"Sethupathi"}
]
}, {
id: 1,
sectionItems: [
{id:9, name:"Aravind"},{id:10, name:"Swamy"}
]
}, {
id: 2,
sectionItems: [
{id:11, name:"Vinay"},{id:12, name:"Raja"}
]
}]
}, {
id: 2,
name: 'Screen2',
sections: [{
id: 0,
sectionItems: [
{id:13, name:"Brian"},{id:14, name:"Laura"}
]
}, {
id: 1,
sectionItems: [
{id:15, name:"Sachin"},{id:16, name:"Tendulkar"}
]
}, {
id: 2,
sectionItems: [
{id:17, name:"Rahul"},{id:18, name:"Dravid"}
]
}]
}]
$scope.Collectval=[];
$scope.captureChange = function(val){
angular.forEach($scope.screens,function(item){
if(item.id==val){
angular.forEach(item.sections, function(data){
angular.forEach(data.sectionItems, function(vval){
$scope.Collectval.push(vval);
})
})
}
})
};
console.log($scope.Collectval);
$scope.captureItemChange = function(value){
//alert(value);
}
});
</script>
This is how you do it using three select dropdowns: https://jsfiddle/u037x1dj/1/
Definitely messy using multiple nested <optgroup>
. I would re-think what you're trying to do and re-design the UI. But this is how you do it:
<select ng-model="myModel">
<optgroup label="screen_{{screen.id}}" ng-repeat="screen in screens">
<optgroup label="section_{{section.id}}" ng-repeat="section in screen.sections">
<option ng-repeat="sectionItem in section.sectionItems" value="sectionItem.id">{{sectionItem.name}}</option>
</optgroup>
</optgroup>
</select>
EDIT: I would have three separate dropdowns, the subsequent dropdowns would filter on what is selected before it. Use ng-disabled
to disable dropdowns if there first one hasn't been selected yet.
Screen:
<select ng-model="selectedScreen" ng-options="screen as screen.name for screen in screens">
</select>
Section:
<select ng-disabled="selectedScreen === null" ng-model="selectedSection" ng-options="section as section.name for section in screens.sections | filter: selectedScreen">
</select>
Section Items:
<select ng-disabled="selectedSection === null" ng-model="selectedSectionItem" ng-options="item as item.name for item in screens.sections.sectionItems | filter: selectedSection">
</select>