Angular ng-repeat nested array - angularjs

I've got this array
{
"menus": [
{
"id": "4",
"name": "Administrator",
"icon": "symbol-male",
"is_show": "1",
"sub_menus": [
{
"id": "6",
"admin_menu_id": "4",
"name": "Manage Admin Role",
"link": "admin-roles",
"is_show": "1"
},
{
"id": "5",
"admin_menu_id": "4",
"name": "Manage Administrator",
"link": "admins",
"is_show": "1"
}
]
}
]
}
How can I ng-repeat with the sub_menus properly with the menus?
I've tried
<ul>
<li ng-repeat="menu in menus">{{ menu.name }}
<ul>
<li ng-repeat="sub_menu in menu.sub_menus">{{ sub_menu.name}} </li>
</ul>
</li>
</ul>
But the sub_menus.name not shown when I repeat it.

Your html need to be something like below.
<ul>
<li ng-repeat="menu in menuItems.menus">{{ menu.name }}
<ul>
<li ng-repeat="sub_menu in menu.sub_menus">{{ sub_menu.name}} </li>
</ul>
</li>
</ul>
Have alook at this JSFiddle

Related

Update list of child items in data set using ng-repeat and index value passed from navigation

I have displayed a list of items in my data set using the ng-repeat as below.
<li ng-repeat="item in adults[1].children">
{{item.childName}}
</li>
What I would like to do is HOW TO dynamically update the list using navigation such as this to show the other child items -
<li ng-click="updateList(1)">First kids</li>
<li ng-click="updateList(2)">Second group of kids</li>
<li ng-click="updateList(3)">Third group of kids</li>
dataset
$http.get('data/parents-data.json')
.then(function(res) {
$scope.adults= res.data;
});
[
{
"parentName": "Jim",
"age": "32",
"sex": "M",
"children": [
{"childName": "Jennifer"},
{"childName": "Timmy"}
]
},
{
"parentName": "Barbara",
"age": "29",
"sex": "F",
"children": [
{"childName": "Oliver"},
{"childName": "Henry"},
{"childName": "Jane"}
]
},
{
"parentName": "Sue",
"age": "40",
"sex": "F",
"children": [
{"childName": "William"},
{"childName": "Robyn"},
{"childName": "Sarah"}
]
}
]
I'm really stumped as to how to get the updateList function to return the index back to the the ng-repeat
I tried
$scope.updateList = function(val) {
return adults[x].children;
}
With
<li ng-repeat="item in updateList()>
{{item.childName}}
</li>
But this obviously didn't work. I just can't get this clear in my head. Maybe I'm doing this wrong. Any help at all greatly appreciated : )
You just have to create a new $scope variable and update it on ng-click to change the list of childrens.
//Default set of children
$scope.childrens=$scope.adults[0].children;
//Update childrens variable on click
$scope.updateList = function(x) {
$scope.childrens=$scope.adults[x].children;
}
var app=angular.module("App",[]);
app.controller("AppCtrl",function($scope){
$scope.adults = [
{
"parentName": "Jim",
"age": "32",
"sex": "M",
"children": [
{"childName": "Jennifer"},
{"childName": "Timmy"}
]
},
{
"parentName": "Barbara",
"age": "29",
"sex": "F",
"children": [
{"childName": "Oliver"},
{"childName": "Henry"},
{"childName": "Jane"}
]
},
{
"parentName": "Sue",
"age": "40",
"sex": "F",
"children": [
{"childName": "William"},
{"childName": "Robyn"},
{"childName": "Sarah"}
]
}
];
$scope.childrens=$scope.adults[0].children;
$scope.updateList = function(x) {
$scope.childrens=$scope.adults[x].children;
}
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<!DOCTYPE html>
<html ng-app="App">
<head>
<meta charset="utf-8" />
<script data-require="angular.js#1.4.9" data-semver="1.4.9" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</head>
<body>
<div ng-controller="AppCtrl">
<ul>
<li><a ng-click="updateList(0)">First kids</a>
</li>
<li ng-click="updateList(1)"><a ng-click="updateList(1)">Second group of kids</a>
</li>
<li ng-click="updateList(2)"><a ng-click="updateList(2)">Third group of kids</a>
</li>
</ul>
<ul>
<li ng-repeat="children in childrens">
{{children.childName}}
</li>
</ul>
</div>
</body>
</html>
You can create a new variable on your $scope to keep track of which children to display. Then we could create a function to update this group. See below
In your controller
$scope.children = $scope.adults[0]; // Default to the first group
$scope.updateGroup = function(newGroupNumber) {
$scope.children = $scope.adults[newGroupNumber];
};
Then in your template:
<li ng-repeat="child in children>
{{child.childName}}
</li>
...
<li ng-click="updateGroup(1)">First kids</li>
<li ng-click="updateGroup(2)">Second group of kids</li>
<li ng-click="updateGroup(3)">Third group of kids</li>

Dynamic MainMenu with unique subMenu's using ng-repeat with data from JSON

I'm trying to ng-repeat and load the main menu from a JSON.
Here's the scenario.
Please check the layout screenshot or you might not be able to understand
MainMenu - Groceries,Listing,Product,Blog,Gallery,Pages,Woman,Electronics,Contact
Submenu - Corporate,Electronics,Kids,Background Isotope,Login,Sign Up
Website Layout Screenshot
JSON//
[{"title":"Corporative","link":"index_corporate.html"},
{"title":"Electronics","link":"index_corporate.html"},
{"title":"Kids","link":"index_corporate.html"},
{"title":"Background Isotope","link":"index_corporate.html"},
{"title":"Login","link":"#/login"},
{"title":"Sign Up","link":"#/register"}
]
Controller//
$http.get('data.json').success(function(dataForSubmenu){
$scope.menu = dataForSubmenu;
});
HTML//
<dt class="item">
<ul class="sf-menu">
<li><a href="index.html”>Groceries</a>//Titles to be repeated from JSON
<ul>
//Dropdown Menu Under Main Menu
<li ng-repeat="menuData in menu">{{menuData.title}}</li>
</ul>
</li>
</ul>
</dt>
<dd></dd>
<dt class="item">
<ul class="sf-menu">
<li><a href="page2.html”>Listing</a>//Titles to be repeated from JSON
<ul>
//Dropdown Menu Under Main Menu
<li ng-repeat="menuData in menu">{{menuData.title}}</li>
</ul>
</li>
</ul>
</dt>
<dd></dd>
<dt class="item">
<ul class="sf-menu">
<li><a href="page3.html”>Product</a>//Titles to be repeated from JSON
<ul>
//Dropdown Menu Under Main Menu
<li ng-repeat="menuData in menu">{{menuData.title}}</li>
</ul>
</li>
</ul>
</dt>
What I want to do is
Load the MainMenuItems using ng-repeat using data from JSON
Load DIFFERENT Sub Menus under multiple main menus using ng-repeat with data from JSON
Repeat should work with the HTML structure I have got going (Using a template for the website so can't change much in that)
your json should be something like this:
[{
"menu":[{
"mainMenuName": "Groceries",
"mainMenuLink": "link"
"subMenu": [{
"title": "Corporative",
"link": "index_corporate.html"
}, {
"title": "Electronics",
"link": "index_corporate.html"
}, {
"title": "Kids",
"link": "index_corporate.html"
}, {
"title": "Background Isotope",
"link": "index_corporate.html"
}, {
"title": "Login",
"link": "#/login"
}, {
"title": "Sign Up",
"link": "#/register"
}]
}, {
"mainMenuName": "Listing",
"mainMenuLink": "link",
"subMenu": [{
"title": "Corporative",
"link": "index_corporate.html"
}, {
"title": "Electronics",
"link": "index_corporate.html"
}, {
"title": "Kids",
"link": "index_corporate.html"
}, {
"title": "Background Isotope",
"link": "index_corporate.html"
}, {
"title": "Login",
"link": "#/login"
}, {
"title": "Sign Up",
"link": "#/register"
}]
}, {
"mainMenuName": "Product",
"mainMenuLink": "link",
"subMenu": [{
"title": "Corporative",
"link": "index_corporate.html"
}, {
"title": "Electronics",
"link": "index_corporate.html"
}, {
"title": "Kids",
"link": "index_corporate.html"
}, {
"title": "Background Isotope",
"link": "index_corporate.html"
}, {
"title": "Login",
"link": "#/login"
}, {
"title": "Sign Up",
"link": "#/register"
}]
}]
}]
once you have that json in $scope.menu then your html should look like
<dt ng-repeat="menuData in menu" class="item">
<ul class="sf-menu">
<li><a href="menuData.mainMenuLink”>{{menuData.mainMenuName}}</a>
<ul>
//Dropdown Menu Under Main Menu
<li ng-repeat="subMenuData in menuData.subMenu">{{subMenuData.title}}</li>
</ul>
</li>
</ul>
</dt>
I have not tested this out yet but it should be something similar to this. if you send me the project I can take a look.
check this answer out its similar solution to what you want: https://stackoverflow.com/a/19840244/2502933

AngularJS ng-repeat for a JSON contains String or an array of a same property

I'm having a JSON data namely $scope.family, it contains the family.name and optionally family.child
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
});
Cases:
If family.child has one child then the name is directly assign as a string
If family.child has more than one child then the name is assign as a array of string with the property family.child.name
If family.child doesn't in the collection just show the family.name
My Expected Output UI is
Siva
Suriya
Karthick
Kumar
Rajini
Kamal
Ajith
Samer
Ranjan
Mahesh
Babu
Joseph
My HTML Source Code (I Can't able to get the expected output from this code)
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child>
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
Kindly assist me...
Please refer the fiddle here. You need some changes in the model and loop with the new modified model - newFamily instead of family.
HTML:
<div ng-app="app" ng-controller="test">
<ul>
<li ng-repeat="member in newFamily">
{{ member.name }}
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child track by $index">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function ($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
$scope.newFamily = [];
angular.forEach($scope.family, function (v, k) {
var existingChildArray = v.child;
var newChildArray = [];
if (!angular.isArray(v.child) && v.child) {
newChildArray.push({ 'name': v.child });
}
var addChild = newChildArray.length > 0 ? newChildArray : existingChildArray;
$scope.newFamily.push({ 'name': v.name, 'child': addChild });
});
});
Try this for your actual output.
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
$scope.family = [
{
"name": "Siva",
"child":
[
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": [{name:"Ranjan"}]
},
{
"name": "Mahesh",
"child": [{name:"Babu"}]
},
{
"name": "Joseph",
"child": []
}
];
You can add the following method to your controller
$scope.isArray = function(obj) {
return angular.isArray(obj);
}
and update the markup as
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling">
<ul ng-if="isArray(member.child)">
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
<ul ng-if="member.child && !isArray(member.child)">
<li>
{{ member.child }}
</li>
</ul>
</div>
</li>
This should do, I think.
Even though #MarcNuri provided a good answer. But if you are not changing the data pattern you can use this also.
HTML
<ul>
<li ng-repeat="member in family">
{{ member.name }}
<div class="liststyling" ng-if="isArray(member.child) && member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
<div class="liststyling" ng-if="!isArray(member.child) && member.child.length > 0">
<ul>
<li>
{{ member.child}}
</li>
</ul>
</div>
</li>
</ul>
JS
app.controller('test', function ($scope) {
$scope.isArray = angular.isArray;
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": "Ranjan"
},
{
"name": "Mahesh",
"child": "Babu"
},
{
"name": "Joseph"
}
];
});
just notice $scope.isArray = angular.isArray; in js.Find plank HERE
Here is a simple running version of your code JSFiddle (not the best coding practices)
Keep in mind that you should use at least AngularJS 1.1.15 version at least to use ng-if.
You should simply tidy up your script a little and it'll work:
HTML:
<body ng-app="myApp">
<div ng-controller="ctrl">
<ul>
<li ng-repeat="member in family">
<h2>
{{ member.name }}
</h2>
<div class="liststyling" ng-if="member.child.length > 0">
<ul>
<li ng-repeat="chdMember in member.child">
{{ chdMember.name }}
</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
Javascript:
var app = angular.module('myApp',[]);
app.controller('ctrl', MyCtrl);
function MyCtrl($scope) {
$scope.family = [
{
"name": "Siva",
"child": [
{
"name": "Suriya"
},
{
"name": "Karthick"
}
]
},
{
"name": "Kumar",
"child": [
{
"name": "Rajini"
},
{
"name": "Kamal"
},
{
"name": "Ajith"
}
]
},
{
"name": "Samer",
"child": [{name:"Ranjan"}]
},
{
"name": "Mahesh",
"child": []
},
{
"name": "Joseph"
}
];
}

AngularJS Scope don't call elements

Hi guys this exercise with scopes don't run,
View:
<body ng-controller="marcasController">
<ul>
<li ng-repeat="todo in marcas">
{{todo.nombre}}
<ul>
<li ng-repeat="tipo in todo.modelo">{{tipo.nombre}}</li>
</ul>
</li>
</ul>
</body>
Controller:
app.controller('marcasController', ['$scope', function($scope) {
$scope.marcas =
[{
"marcas": [
{
"marca": "Chevrolet",
"modelo": [
{
"nombre": "Aveo",
"image": "images/aveo.jpg",
"modelo": "2000-2014",
"tab": "aveo"
},
{
"nombre": "Captiva",
"image": "images/captiva.jpg",
"modelo": "2000-2014",
"tab": "captiva"
}
]
}
]
}];
}])
Example
please how use scopes to call objects
Given that data structure you should be doing it like this:
<ul>
<li ng-repeat="todo in marcas[0].marcas">
{{todo.marca}}
<ul>
<li ng-repeat="tipo in todo.modelo">{{tipo.nombre}}</li>
</ul>
</li>
</ul>
Example
Notice that $scope.marcas is an Array of objects that contains just one element, that element has only one attribute: marcas which is another Array...
Maybe you wanted that data structure to be like this instead:
$scope.marcas =[
{
"marca": "Chevrolet",
"modelo": [
{
"nombre": "Aveo",
"image": "images/aveo.jpg",
"modelo": "2000-2014",
"tab": "aveo"
},
{
"nombre": "Captiva",
"image": "images/captiva.jpg",
"modelo": "2000-2014",
"tab": "captiva"
}
]
}
];
In that case, the correct syntax for your view would be:
<ul>
<li ng-repeat="todo in marcas">
{{todo.marca}}
<ul>
<li ng-repeat="tipo in todo.modelo">{{tipo.nombre}}</li>
</ul>
</li>
</ul>
Example

Could the below method of creating a dropdown menu using AngularJS be done a different way?

I'm trying to integrate AngularJS into a website I'm experimenting with. In the original code, I had a few elements that were duplicated so I am using AngularJS to remedy this. The code is as follows:
<nav id=global>
<ul>
<li>Home</li>
<li><a href=#>Blog</a></li>
<li id=projects>
Projects
<ul id=dropdown-toggle>
<li><a href=html/omnicode.html>Project1</a></li>
<li><a href=#>Project2</a></li>
<li><a href=#>Project3</a></li>
<li><a href=#>Project4</a></li>
<li><a href=#>Project5</a></li>
<li><a href=#>Project6</a></li>
<li><a href=#>Project7</a></li>
</ul>
</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
I used the following code to remove the duplication:
<nav id=global ng-controller="NavListCtrl">
<ul>
<li ng-repeat="nav in navheaders" ng-switch on="isProjects(nav)">
<a href={{nav.link}}>{{nav.name}}</a>
<ul id=dropdown-toggle ng-switch-when="true">
<script>var el = this.parent(); el.id = "projects"</script>
<li ng-repeat="proj in projects">
<a href={{proj.link}}>{{proj.name}}</a>
</li>
</ul>
</li>
</ul>
</nav>
Just in case, here is the contents of my controller.js file:
'use strict';
/* Controllers */
function NavListCtrl($scope) {
$scope.navheaders = [
{"name": "Home",
"link": "index.html"},
{"name": "Blog",
"link": "#"},
{"name": "Projects",
"link": "#"},
{"name": "About",
"link": "#"},
{"name": "Contact",
"link": "#"}
];
$scope.isProjects = function (nav) {
return nav.name == "Projects";
}
$scope.projects = [
{"name": "Project1",
"link": "html/omnicode.html"},
{"name": "Project2",
"link": "#"},
{"name": "Project3",
"link": "#"},
{"name": "Project4",
"link": "#"},
{"name": "Project5",
"link": "#"},
{"name": "Project6",
"link": "#"},
{"name": "Project7",
"link": "#"}
];
}
Is there a better way to carry out this operation? Also, I am not sure how to insert "id=projects" into the li element that contains "Projects". My code:
<script>var el = this.parent(); el.id = "projects"</script>
was a feeble attempt at doing such. Any help would be appreciated.
You could extend your model with an id property:
$scope.navheaders = [
{"name": "Home",
"link": "index.html"},
{"name": "Blog",
"link": "#"},
{"name": "Projects",
"link": "#",
"id": "projects" },
{"name": "About",
"link": "#"},
{"name": "Contact",
"link": "#"}
];
<li ng-repeat="nav in navheaders" ng-switch on="isProjects(nav)" id="{{nav.id}}"> ...</li>

Resources