Looping through 2 different objects in AngularJS - javascript

I have the following controller:
app.controller('MainController', ['$scope', function($scope) {
$scope.taskCategories = {
categories: [
'work',
'chores',
'learning'
]
};
$scope.tasklist = {
tasks: [{
title: 'Email Gregory',
category: 'work'
}, {
title: 'Clean the Kitchen',
category: 'chores'
}, {
title: 'AngularJS',
category: 'learning'
}, {
title: 'Hose Car',
category: 'chores'
}, {
title: 'Email Jethro',
category: 'work'
}
]
};
}]);
And am pulling the information through so far like this:
<div>
<li data-toggle="collapse" data-target="#work" class="nav_head workcat collapsed">
Work <span class="arrow"></span>
</li>
<ul class="sub-menu collapse" id="work">
<li ng-repeat="tasks in tasklist.tasks | orderBy:'title' | filter: {category: 'work'}">
{{ tasks.title }}
</li>
<li class="addwork">
<a href="">
<span class="fa-stack"> <i class="fa fa-2x fa-stack-2x fa-circle"></i><i class="fa fa-2x fa-stack-2x fa-plus-circle"></i>
</a>
</span>
</li>
</ul>
This would work fine doing a few times, one for each category, but I am looking to be able to add categories dynamically, and so I am looking for some way to go through the following steps:
So, I’ll need to loop all in categories.
During that loop, I’ll loop through the tasks and print out any task that matches the string of categories.index(1)
Then add 1 to category index and run again, till category.length runs out
I'm unfamiliar with looping inside a loop, and more unfamiliar again with doing it in angular. Anyone have any suggestions?

You could do an outer loop (ng-repeat) on the categories:
<ul class="sub-menu collapse" id="work" ng-repeat="cat in taskCategories.categories">
<li ng-repeat="tasks in tasklist.tasks | orderBy:'title' | filter: {category: cat}">
{{ tasks.title }}
</li>
<li class="addwork">
<a href="">
<span class="fa-stack"> <i class="fa fa-2x fa-stack-2x fa-circle"></i><i class="fa fa-2x fa-stack-2x fa-plus-circle"></i></span>
</a>
</li>
</ul>
Fiddle

Please refer below code snippet
angular.module('app',[]);
angular.module('app').controller('myController',function($scope){
$scope.taskCategories = {
categories: [
'work',
'chores',
'learning'
]
};
$scope.tasklist = {
tasks: [{
title: 'Email Gregory',
category: 'work'
}, {
title: 'Clean the Kitchen',
category: 'chores'
}, {
title: 'AngularJS',
category: 'learning'
}, {
title: 'Hose Car',
category: 'chores'
}, {
title: 'Email Jethro',
category: 'work'
}
]
};
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<body ng-app="app" ng-controller="myController">
<ul>
<li data-toggle="collapse" data-target=#{{c}} class="nav_head workcat" ng-repeat="c in taskCategories.categories">
<span class="arrow"> {{c}}</span>
<ul class="sub-menu collapse" id={{c}}>
<li ng-repeat="tasks in tasklist.tasks | orderBy:'title' | filter: {category: c}">
{{ tasks.title }}
</li>
</ul>
</li>
</ul>
</body>
Hope this helps!

Related

Aurelia - A way to add a divider into a multi level drop down menu

I have a multi level dropdown menu working for Aurelia with bootstrap however whilst its three levels deep and uses as a basis THIS gist expanding on it I am having trouble adding a divider via the route settings.
Now a divider uses the class "divider" in the list tag <li></li> Ok so I thought by adding the entry divider: true in the settings for the dropdown I could check for that and instead if displaying the link etc I could instead show a divider however I dont know how to implement this into the navmenu.html file. Here is the file:
<ul class="nav navbar-nav">
<li repeat.for="route of router.navigation" class="${route.isActive ? 'active' : ''}">
<a href.bind="route.href" if.bind="!route.settings.nav"><span class="glyphicon glyphicon-${ route.settings.icon }"></span> ${route.title}</a>
<a href.bind="route.href" if.bind="route.settings.nav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ route.settings.icon }"></span> ${route.title} <span class="caret"></span> <!--First level menu heading - requires route.settings.nav to exist-->
</a>
<ul if.bind="route.settings.nav" class="dropdown-menu">
<li repeat.for="menu of route.settings.nav" class="dropdown-submenu">
<a href.bind="menu.href" if.bind="!menu.navSettings.subNav"><span class="glyphicon glyphicon-${ menu.navSettings.icon }"></span> ${menu.title}</a>
<a href.bind="menu.href" if.bind="menu.navSettings.subNav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ menu.navSettings.icon }"></span> ${menu.title} <span class="caret-right"></span>
</a>
<ul if.bind="menu.navSettings.subNav" class="dropdown-menu">
<li repeat.for="subMenu of menu.navSettings.subNav" class="dropdown-submenu">
<a href.bind="subMenu.href" if.bind="!subMenu.subNavSettings.subSubNav"><span class="glyphicon glyphicon-${ subMenu.subNavSettings.icon }"></span> ${subMenu.title}</a>
<a href.bind="subMenu.href" if.bind="subMenu.subNavSettings.subSubNav" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-${ subMenu.subNavSettings.icon }"></span> ${subMenu.title} <span class="caret-right"></span>
</a>
<ul if.bind="subMenu.subNavSettings.subSubNav" class="dropdown-menu">
<li repeat.for="lowestSubMenu of subMenu.subNavSettings.subSubNav" class="dropdown-submenu">
<a href.bind="lowestSubMenu.href"> <span class="glyphicon glyphicon-${ lowestSubMenu.subSubNavSettings.icon }"></span> ${lowestSubMenu.title}</a>
</li>
</ul>
</li>
</ul>
</li> [ALL THE ANCHORS HERE OR A DIVIDER.. HOW DO I DO A TERNARY TO CHECK ON EACH REPEAT FOR A DIVIDER VALUE IN THE SETTINGS ARRAY.
</ul>
</li>
</ul>
Here is an exert from the route map that the navmenu reads from:
{
route: "clients",
name: "clients",
moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
title: "Clients",
nav: true,
settings: {
nav: [
{
href: "#clients/clientsList",
title: "Client List",
navSettings: {
icon: "list",
roles: ["Employee", "Admin"],
}
},
{
navSettings: {
roles: ["Employee", "Admin"],
divider: true, // HERE IS MY DIVIDER
}
},
{
href: "#clients/Create",
title: "Create Client",
navSettings: {
icon: "user",
roles: ["Employee", "Admin"],
}
}
],
icon: "user",
auth: true,
roles: ["Employee", "Admin"],
pos: "left"
}
},
The problem is that the <li></li> does a repeat and I need to check in that repeat - li to see if "navSettings has an entry divider: true and if so not show the link (menu item) but instead show a line divider.
How do I discard the anchors and instead show a list line with class "divider". Whats throwing me is the fact that the li has a repeat.for and I need to either show everything between the <li></li>tags or instead show a divider.
I need to check on the line:
<li repeat.for="menu of route.settings.nav" class="dropdown-submenu">
and change the class from "dropdown-submenu" to "divider" while at the same time not show any of the anchors <a></a> by doing similar check (if.bind I am guessing) for divider..
Hope you can help..
In the <li> use class="${menu.divider ? 'divider' : 'dropdown-submenu'}".
Use if.bind on menu.divider for the elements inside the <li>.
<li repeat.for="menu of route.settings.nav" class="${menu.divider ? 'divider' : 'dropdown-submenu'}">
<a if.bind="!menu.divider" href.bind="lowestSubMenu.href"> <span class="glyphicon glyphicon-${ lowestSubMenu.subSubNavSettings.icon }"></span> ${lowestSubMenu.title}</a>
<div if.bind="menu.divider" class="divider"></div>
</li>

Delete button "delete" after clicking in ng-repeat

I'm showing data by ng-repeat. There Have button. to delete item.
After delete item, this button must dissapear only for item that I deleted.
<tr ng-repeat="paymentinfo in paymentList | filter:keyword | filter:money | filter:getdate | filter:{state: 'archived'}: archived.state ? true : false">
<td id="outmouse">
<ul style="list-style: none;" class="gt-reset">
<li class="dropdown changecoursename">
<a class="dropdown-toggle" data-toggle="dropdown">
<span class="tableOperation norlmalstate">Open Course</span>
<span class="tableOperation openedstate">more options</span>
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a class="tableOperation" ng-click="paymentRemarks()">Remarks</a></li>
<li><a class="tableOperation" ng-click="paymentReturn(paymentinfo)">Return</a></li>
<li ng-switch on="paymentinfo.state">
<div ng-switch-when="archived" class="archived__state">{{paymentinfo.state}}</div>
<a ng-switch-default class="tableOperation" ng-click="paymentDelete();">{{deletebtn}}</a>
</li>
</ul>
</li>
</ul>
</td>
</tr>
There place where I need to delete
<li ng-switch on="paymentinfo.state">
<div ng-switch-when="archived" class="archived__state">{{paymentinfo.state}}</div>
<a ng-switch-default class="tableOperation" ng-click="paymentDelete();">{{deletebtn}}</a>
</li>
My JS
$scope.datas = [{
date: '06-12-2016',
name: 'Pinao Class',
state: 'archived',
remark: 'remarled',
amount: 101,
id: 21
}, {
date: '15-04-2016',
name: 'drivers Class',
state: 'notarchived',
remark: 'remarled',
amount: 102,
id: 22
}];
$scope.paymentList = $scope.datas;
$scope.deletebtn = "delete";
$scope.paymentDelete = function() {
$scope.www = true;
$scope.deletebtn = false;
}
My code deleting for All elements need delete just for one I choose
try this
ng-click="paymentDelete(this.paymentinfo);">// pass current object to delete function
$scope.paymentDelete = function (paymentinfo ) {
$scope.www = true;
var index = $scope.paymentList.indexOf(paymentinfo );
if (index > -1) {
$scope.paymentList.splice(index, 1);
}
}

Filter an ng-repeat based on parent ng-repeat

Scratching my head now for 2 hours. Maybe I'm tired or maybe I don't understand what I'm doing. Anyway, I've got an array of blogposts. Which looks like this:
[
{
'title': 'first post',
'tags': [
{ 'name': 'Tag 1', 'slug': 'tag-1' }
]
},
{
'title': 'second post',
'tags': [
{ 'name': 'Tag 1', 'slug': 'tag-1' },
{ 'name': 'Tag 3', 'slug': 'tag-3' }
]
},
{
'title': 'third post',
'tags': [
{ 'name': 'Tag 2', 'slug': 'tag-2' }
]
}
]
And also an array containing my tags like this.
[
{'title': 'Tag 1', 'slug':'tag-1'},
{'title': 'Tag 2', 'slug':'tag-2'},
{'title': 'Tag 3', 'slug':'tag-3'},
{'title': 'Tag 4', 'slug':'tag-4'}
]
And I am doing an regular angular ng-repeat like this to show all my blogpost tags:
<ul>
<li ng-repeat="tag in blog.tags">
<h3>{{ tag.title }}</h3>
</li>
</ul>
Now, I would like to add a nested repeater which only shows blogposts from the variable blog.posts that contains the current tag.
Something like this:
<ul ng-controller="BlogComponent as blog">
<li ng-repeat="tag in blog.tags">
<h3>{{ tag.title }}</h3>
<ul>
<li ng-repeat="post in blog.posts | filter: tag.slug IN post.tags">
<span>{{ post.title }}</span>
</li>
</ul>
</li>
</ul>
But I cannot seem to get it working. I think it SHOULD be easy. Because in my mind it is a quite simple task. to filter out unwanted results based on a string and an array.
Wanted/Exptected output:
<ul>
<li>
<h3>Tag 1</h3>
<ul>
<li>first post</li>
<li>second post</li>
</ul>
</li>
<li>
<h3>Tag 2</h3>
<ul>
<li>third post</li>
</ul>
</li>
<li>
<h3>Tag 3</h3>
<ul>
<li>second post</li>
</ul>
</li>
</ul>
You could make a custom filter instead of using "filter: expression".
What you can do create a filter that takes the tags and posts as arguments and returns the array with filtered items.
myApp.filter('myFilter', function () {
return function (posts, tag) {
var newPosts = [];
for (var i = 0; i < posts.length; i++)
for (var j = 0; j < post.tags.length; j++)
if (posts[i].tags[j].slug === tag.slug)
newPosts.push(posts[i]);
return newPosts;
}
});
And then
<li ng-repeat="post in blog.posts | myFilter: tag">
<span>{{ post.title }}</span>
</li>
Using the built-in functionality, you can do it like this:
<ul ng-controller="BlogComponent as blog">
<li ng-repeat="tag in blog.tags">
<h3>{{ tag.title }}</h3>
<ul>
<li ng-repeat="post in blog.posts | filter: {tags: {slug: tag.slug}}">
<span>{{ post.title }}</span>
</li>
</ul>
</li>
</ul>
See it working here: https://plnkr.co/edit/pQZse1hUnnzyfneIlpMu?p=preview
Documentation for the filter is here: https://docs.angularjs.org/api/ng/filter/filter
Or, if you want Tag 4 to be hidden because it has no matching posts, you could do something like this:
<div ng-controller="BlogComponent as blog">
<div ng-repeat="tag in blog.tags">
<div ng-repeat="post in blog.posts | filter: {tags: {slug: tag.slug}}">
<h3 ng-if="$first">{{ tag.title }}</h3>
<li>{{ post.title }}</li>
</div>
</div>
</div>

How do I use a router and inbuilt/custom attributes to create dropdown menu in aurelia?

Twitter bootstrap has a dropdown menu option; where a menu has have multiple layers. See: http://getbootstrap.com/javascript/#dropdowns
How can I use Aurelia.js's routers to recreate this? Routers normally provide 1 level. I need 2 levels.
Credit for this goes to: https://github.com/adarshpastakia.
I "borrowed" most of this person's code to answer this question. You can find it at: https://gist.github.com/adarshpastakia/5d8462b5bc8d958d5cb3
Here are steps to answer the question above:
(1) In the router, add a "settings" property. It can be whatever you want. Here is an example:
settings:{
subMenu:[
{href:'#/sub1', title:'Submenu 1'},
{href:'zoldello.wordpress.com', title:'Submenu 2'},
{href:'#/sub3', title:'Submenu 3'}
]
}
Note: (a)It must be called "settings" (b) Aurelia currently ignores custom code you write outside "settings" (c)In "settings", you can place any property in it you like
(2) (a) From (1) above, if you need the submenu to route to a part of the page, in href (or whatever you call it) use "#sub1"; where "sub1" refers to a different route where nav is set to false.
(b) If you want a hyperlink independent of routing, set href (or whatever you call it) to the url you desire (I used "zoldello.wordpress.com" in my example). No need to add a additional route
(3) Follow the basic aurelia rules of building DOM (repeat, template etc)
Here is an example:
HTML file
<li repeat.for="route of router.navigation">
<!-- if route has no submenu -->
<a href.bind="route.href" if.bind="!route.settings.subMenu">${route.title}</a>
<!-- if route has submenu -->
<a href.bind="javascript:;" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="false" if.bind="route.settings.subMenu">
${route.title} <span class="caret"></span></a>
<ul if.bind="route.settings.subMenu">
<li repeat.for="menu of route.settings.subMenu">
<a href.bind="menu.href">${menu.title}</a>
</li>
</ul>
</li>
Javascript file
configureRouter(config) {
config.map([{
route:'home',
title:'Home',
nav:true,
module:'home'
},{
route:'top-menu',
title:'Top Menu',
nav:true,
settings:{
subMenu:[
{href:'#/sub1', title:'Submenu 1'},
{href:'zoldello.wordpress.com', title:'Submenu 2'},
{href:'#/sub3', title:'Submenu 3'}
]
}
}, {
route:'sub1',
title:'Submenu 1',
nav:false,
moduleId:'module'
}, {
route:'sub2',
title:'Submenu 2',
nav:false,
moduleId:'module'
}, {
route:'sub3',
title:'Submenu 3',
nav:false,
moduleId:'module'
}])
}
small fix for Phil's answer
html:
<li class=" ${route.settings.subMenu ? '' : 'dropdown'} " repeat.for="route of router.navigation">
<!-- if route has no submenu -->
<a href.bind="route.href" if.bind="!route.settings.subMenu">${route.title}</a>
<!-- if route has submenu -->
<a href="#" class="dropdown-toggle" data-toggle="dropdown" if.bind="route.settings.subMenu">
${route.title} <span class="caret"></span>
</a>
<ul class="dropdown-menu" if.bind="route.settings.subMenu">
<li repeat.for="menu of route.settings.subMenu">
<a href.bind="menu.href">${menu.title}</a>
</li>
</ul>
</li>
js
configureRouter(config) { config.map([{
route:'home',
title:'Home',
nav:true,
moduleid:'home' },{
route:'top-menu',
title:'Top Menu',
nav:true,
moduleid:'module'
settings:{
subMenu:[
{href:'#/sub1', title:'Submenu 1'},
{href:'zoldello.wordpress.com', title:'Submenu 2'},
{href:'#/sub3', title:'Submenu 3'}
]
} }, {
route:'sub1',
title:'Submenu 1',
nav:false,
moduleId:'module' }, {
route:'sub2',
title:'Submenu 2',
nav:false,
moduleId:'module' }, {
route:'sub3',
title:'Submenu 3',
nav:false,
moduleId:'module' }])}
I was looking for the same thing when I landed here. The above answers where helpful but didn't take me as far as I needed to go. I learned of Bootstrap 3 dropdown sub menu missing and the work-arounds offered there but again needed something more.
Then I found http://www.smartmenus.org/ which provides the responsiveness and functionality I need in a drop-down menu for Aurelia for our production app. I worked with their team to get a version of the skeleton app that works well.
You can download it at http://www.smartmenus.org/files/demos/aurelia/SmartMenusDemo.zip.
The app.ts file is similar to the example above but adds support for font-awesome icons:
import {RouterConfiguration, Router} from 'aurelia-router';
import 'jquery';
import 'bootstrap';
import 'smartmenus';
import 'smartmenus-bootstrap';
export class App {
router: Router;
configureRouter(config: RouterConfiguration, router: Router) {
config.title = 'Aurelia';
config.map([
{ route: ['', 'welcome'], name: 'welcome', moduleId: './welcome', nav: true, title: 'Welcome' },
{
route: 'users', name: 'users', moduleId: './users', nav: true, title: 'Show Users',
settings: {
subMenu: [{ href: '#/users', title: 'Users', iconClass: 'fa fa-slideshare' },
{ href: '#/usersTest', title: 'Test Users', iconClass: 'fa fa-street-view' },
{
href: '#', title: 'Sub Sub', iconClass: 'fa fa-medium', settings: {
subMenu: [{ href: '#/child-router', title: 'Child Router', iconClass: 'fa fa-registered' },
{ href: '#/usersTest', title: 'Test Users', iconClass: 'fa fa-street-view' }]
}
},
{ href: '#/child-router', title: 'Child Router', iconClass: 'fa fa-registered' }]
}
},
{ route: 'usersTest', name: 'usersTest', moduleId: './usersTest', nav: false, title: 'Test Users' },
{ route: 'child-router', name: 'childRouter', moduleId: 'child-router', nav: false, title: 'Child Router' },
{ route: 'users', name: 'users', moduleId: './users', nav: true, title: 'Github Users' }
]);
this.router = router;
}
attached(): void {
$.SmartMenus.Bootstrap.init();
}
}
I implemented support for 4 levels of sub-menus in nav-bar.html:
<template bindable="router">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#top-level-nav">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<i class="fa fa-home"></i>
<span>${router.title}</span>
</a>
</div>
<div class="collapse navbar-collapse" id="top-level-nav">
<ul id="main-menu" class="nav navbar-nav ">
<li repeat.for="route of router.navigation" class="${row.isActive ? 'active' : ''} ${route.settings.subMenu ? 'dropdown' : ''}">
<!-- if route has no submenu -->
<a href.bind="route.href" if.bind="!route.settings.subMenu">${route.title}</a>
<!-- if route has submenu -->
<a if.bind="route.settings.subMenu" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="true">
${route.title} <span class="caret"></span>
</a>
<ul if.bind="route.settings.subMenu" class="dropdown-menu">
<li repeat.for="l2SubMenu of route.settings.subMenu">
<a href.bind="l2SubMenu.href" if.bind="!l2SubMenu.settings.subMenu"><span class.bind="l2SubMenu.iconClass"> </span>&nbsp&nbsp${l2SubMenu.title}</a>
<a href.bind="l2SubMenu.href" if.bind="l2SubMenu.settings.subMenu" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="true">
<span class.bind="l2SubMenu.iconClass"> </span>&nbsp&nbsp${l2SubMenu.title} <span class="caret"></span>
</a>
<ul if.bind="l2SubMenu.settings.subMenu" class="dropdown-menu">
<li repeat.for="l3SubMenu of l2SubMenu.settings.subMenu">
<a href.bind="l3SubMenu.href" if.bind="!l3SubMenu.settings.subMenu"><span class.bind="l3SubMenu.iconClass"> </span>&nbsp&nbsp${l3SubMenu.title}</a>
<a href.bind="l3SubMenu.href" if.bind="l3SubMenu.settings.subMenu" class="dropdown-toggle" data-toggle="dropdown"
role="button" aria-haspopup="true" aria-expanded="true">
<span class.bind="l3SubMenu.iconClass"> </span>
&nbsp&nbsp${l3SubMenu.title} <span class="caret"></span>
</a>
<ul if.bind="l3SubMenu.settings.subMenu" class="dropdown-menu">
<li repeat.for="l4SubMenu of l3SubMenu.settings.subMenu">
<a href.bind="l4SubMenu.href"><span class.bind="l4SubMenu.iconClass"> </span>&nbsp&nbsp${l4SubMenu.title}</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="loader" if.bind="router.isNavigating">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</li>
</ul>
</div>
</nav>
</template>
As you can see, SmartMenus didn't require much change to the app but provides us with great responsive multi-level drop down menus in Aurelia with the power of Bootstrap regardless of Bootstrap depreciating support for that.
Hope this helps someone !

Toggle active class on item with angular.js

How can I toggle active class on element if I have the following code?
<div class="searchandfilter">
<span ng-repeat="taxonomy in taxonomies" class="tab-controller" ng-class="{'active': $index == 0}">
<ul>
<li class="tab" ng-click="onClickTab(taxonomy)">{{taxonomy.name}}</li>
</ul>
<span class="tab-content">
<span ng-repeat="child in taxonomy.children">
<input type="checkbox" checked="child.value" />{{child.name}}
</span>
</span>
</span>
On load I need to set the first tab-conroller span to active, which is now correct but I can't toggle the active class onclick. The number of tabs is dynamic, so it can be 1 or 10. Currently it generates the tabs like this:
<span class="tab-controller ng-scope active" ng-class="{'active': $index == 0}" ng-repeat="taxonomy in taxonomies">
<ul>
<li class="tab ng-binding" ng-click="onClickTab(taxonomy)">Tab 1</li>
</ul>
</span>
<span class="tab-controller ng-scope" ng-class="{'active': $index == 0}" ng-repeat="taxonomy in taxonomies">
<ul>
<li class="tab ng-binding" ng-click="onClickTab(taxonomy)">Tab2</li>
</ul>
</span>
You can do this by passing the index and setting a scope variable.
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.taxonomies = [
{name: 'a', children: [{name: 'a', value: false}]},
{name: 'b', children: [{name: 'a', value: true},
{name: 'b', value: false}]}
];
$scope.onClickTab = function(idx) {
$scope.selectedIndex = idx;
};
$scope.selectedIndex = 0;
});
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app='app' ng-controller='myController'>
<div class="searchandfilter">
<span ng-repeat="taxonomy in taxonomies" class="tab-controller" ng-class="{'active': $index == selectedIndex}">
<ul>
<li class="tab" ng-click="onClickTab($index)">{{taxonomy.name}}</li>
</ul>
<span class="tab-content">
<span ng-repeat="child in taxonomy.children">
<input type="checkbox" ng-model="child.value">{{child.name}}
</span>
</span>
</span>
</div>
</div>
The problem with that approach is if the taxonomies change, the selectedIndex may no longer match up with selected tab so instead of tracking index, you can just track the entire object:
var app = angular.module('app', []);
app.controller('myController', function($scope) {
$scope.taxonomies = [
{name: 'a', children: [{name: 'a', value: false}]},
{name: 'b', children: [{name: 'a', value: true},
{name: 'b', value: false}]}
];
$scope.onClickTab = function(selected) {
$scope.selected = selected;
};
$scope.selected = $scope.taxonomies[0];
});
.active {
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app='app' ng-controller='myController'>
<div class="searchandfilter">
<span ng-repeat="taxonomy in taxonomies" class="tab-controller" ng-class="{'active': taxonomy === selected}">
<ul>
<li class="tab" ng-click="onClickTab(taxonomy)">{{taxonomy.name}}</li>
</ul>
<span class="tab-content">
<span ng-repeat="child in taxonomy.children">
<input type="checkbox" ng-model="child.value">{{child.name}}
</span>
</span>
</span>
</div>
</div>
You need to have some property in your tabs to be able to compare against the $index in the ng-repeat.
For example:
<div class="tab-controller" ng-class="{'active': $index == currentTab}" ng-repeat="taxonomy in taxonomies">
<ul>
<li class="tab" ng-click="onClickTab(taxonomy.tab)">{{ taxonomy.name }}</li>
</ul>
</div>
And taxonomies should be an array of objects, something like:
var taxonomies = [
{ id: 0, name: 'Tab 1', tab: 'whatever you need here'},
{ id: 1, name: 'Tab 2', tab: 'whatever you need here'},
{ id: 2, name: 'Tab 3', tab: 'whatever you need here'}
];
And when you call your function onClickTab it should set the variable scope.currentTab to the id of the clicked tab.
Hope it helps.
sorry if am wrong,try this
http://plnkr.co/edit/FdueM4rAvd4k6hClK1HR?p=preview
your html will be
<html>
<head>
<script data-require="angular.js#*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app">
<div class="searchandfilter" ng-controller="tab-controller">
<span ng-repeat="taxonomy in taxonomies">
<ul ng-class="{'active': $index == selectedIndex}">
<li class="tab" ng-click="onClickTab(taxonomy.id)">{{taxonomy.name}}
<br/>
<span class="tab-content">
<span ng-repeat="child in taxonomy.children">
<input type="checkbox" ng-model="child.value" />{{child.name}}
</span>
</span>
</li>
</ul>
</span>
</div>
</body>
</html>
angular js code will be
var app = angular.module("app",[]);
app.controller('tab-controller',['$scope',function($scope){
$scope.taxonomies = [
{ id: 0, name: 'hello' , children:[{name:"test1",value:true},{name:"test2",value:false}]},
{ id: 1, name: 'how' , children:[{name:"test5", value: false}]},
{ id: 2, name: 'are you',children:[{name:"test4",value: true}]}
];
$scope.onClickTab= function(x){
$scope.selectedIndex= x;
};
}]);
css code will be
.active{
background-color:green;
}
body {
background-color: yellow;
}

Categories