I am using angular data table where i am generating table every time user selects an option.For the first input the data table render successfully but after that when user select onther option the data table disappear from the view.The problem can be solved if i place the data table options vm.dtOptions and vm.dtColumnDefs outside the function.But i need to solve the issue keeping the options inside the function as my $scope.ln is dynamically generated inside the function and i need this value to limit the loop.So how can i achieve my goal so that instead of disappearing multiple table can be showed based on user input?
var app = angular.module('myApp',['datatables']);
app.controller('MyCtrl', function($scope,DTOptionsBuilder,DTColumnBuilder,DTColumnDefBuilder) {
$scope.department = [
{value : "1", name : "sales"},
{value : "2", name : "admin"},
{value : "3", name : "other"}
];
$scope.dep=$scope.selected_dep;
$scope.depshow=function(){
$scope.dep=$scope.selected_dep;
if($scope.dep==1)
{
$scope.list = [
{"eid":"10","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"20","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"30","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"}
];
}
else if($scope.dep==2)
{
$scope.list = [
{"eid":"40","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"50","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"60","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"}
];
}
if($scope.dep==3) {
$scope.list = [
{"eid":"70","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"80","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"},
{"eid":"0","dyn1":"dval1","dyn2":"dval2","dyn3":"dval3","sales":"20"}
];
}
$scope.vm = {};
$scope.vm.dtOptions = DTOptionsBuilder.newOptions()
.withOption('order', [0, 'asc']);
$scope.ln=4;
$scope.vm.dtColumnDefs = [
];
for(var i=1;i<$scope.ln;i++){
$scope.vm.dtColumnDefs.push(DTColumnDefBuilder.newColumnDef(i).notSortable());
}
}
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://phpflow.com/demo/angular_datatable_demo/angular-datatables.min.js"></script>
<script src="https://phpflow.com/demo/angular_datatable_demo/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://phpflow.com/demo/angular_datatable_demo/datatables.bootstrap.css">
</head>
<div class="container">
<div ng-app="myApp" ng-controller="MyCtrl">
Select <select ng-model="selected_dep" ng-change="depshow()" ng-options="item.value as item.name for item in department">
<option value="">select a department</option>
</select>
{{selected_dep}}
<table class="table table-striped table-bordered" dt-options="vm.dtOptions" dt-column-defs="vm.dtColumnDefs" datatable="ng">
<thead>
<tr>
<th>Employee ID</th>
<th>dynamic clm1</th>
<th>dynamic clm2</th>
<th>dynamic clm3</th>
<th>sales</th>
</thead>
<tbody>
<tr ng-repeat="data in list">
<td> {{ data.eid }} </td>
<td> {{ data.dyn1 }} </td>
<td> {{ data.dyn2 }} </td>
<td> {{ data.dyn3 }} </td>
<td> {{ data.sales }} </td>
</tr>
</tbody>
</table>
</div>
The reason for this is that you dont have brackets on the
else if($scope.dep==2)
Related
This question is a follow-up to this question.
I've created this JSFiddle for demonstration purposes.
Note that when searching for a value in column1 the search works as expected. However when searching for a value in column2 (using the same "search field"), data_table.search does not appear to be called at all and relevant rows can not be found (press F12 to see debug info in the console).
var data_table = $("#table").DataTable();
var search_term = null;
$.fn.DataTable.ext.search.push(
function(settings, row, index) {
if (search_term) {
search_term = search_term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
search_term = search_term.toLowerCase();
}
console.log(`search_term is ${search_term}`)
var approver = $(data_table.cell(`:eq(${index})`, ':eq(0)').node()).find('.approver-select').val().toLowerCase();
console.log(`approver is ${approver}`)
var approver_match = approver.match(search_term);
console.log(`approver_match is ${approver_match}`)
var network_or_group = $(data_table.cell(`:eq(${index})`, ':eq(1)').node()).find('.network-or-group-text').val().toLowerCase();
console.log(`network_or_group is ${network_or_group}`)
var network_or_group_match = network_or_group.match(search_term);
console.log(`network_or_group_match is ${network_or_group_match}`)
console.log(`approver_match || network_or_group_match || !search_term is ${approver_match || network_or_group_match || !search_term}`)
console.log('')
console.log('')
return approver_match || network_or_group_match || !search_term;
}
);
$('#table_filter input', data_table.table().container()).on('keyup.DT cut.DT paste.DT input.DT search.DT', event => {
search_term = $(event.target).val();
data_table.draw();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<table id="table">
<thead>
<th>column1</th>
<th>column2</th>
</thead>
<tbody>
<tr>
<td>
<select class="approver-select">
<option selected>user1</option>
<option>user2</option>
</select>
</td>
<td>
<input class="network-or-group-text" type="text" value="1.1.1.1/32">
</td>
</tr>
<tr>
<td>
<select class="approver-select">
<option>user1</option>
<option selected>user2</option>
</select>
</td>
<td>
<input class="network-or-group-text" type="text" value="2.2.2.0/24">
</td>
</tr>
</tbody>
</table>
</body>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</html>
A simpler way of doing it using the html-input type is as below. You define the columns you're targeting and you're returning the value upon search. It works for both the select and the input.
You won't need to check for keyup.DT cut.DT paste.DT input.DT search.DT as datatables does that for you automatically as well.
$.fn.dataTableExt.ofnSearch['html-input'] = function(value) {
return $(value).val();
};
var data_table = $("#table").DataTable({
columnDefs: [{
"type": "html-input",
"targets": [0, 1]
}]
});
<html>
<body>
<table id="table">
<thead>
<th>column1</th>
<th>column2</th>
</thead>
<tbody>
<tr>
<td>
<select class="approver-select">
<option selected>user1</option>
<option>user2</option>
</select>
</td>
<td>
<input class="network-or-group-text" type="text" value="1.1.1.1/32">
</td>
</tr>
<tr>
<td>
<select class="approver-select">
<option>user1</option>
<option selected>user2</option>
</select>
</td>
<td>
<input class="network-or-group-text" type="text" value="2.2.2.0/24">
</td>
</tr>
</tbody>
</table>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</html>
This is cleaner and uses the basic type property of datatables rather than filtering all data upon search as you're doing right now.
I am trying to do pagination for scope object in angularjs,for that am using jquery data table plugin.
But am getting Cannot read property 'insertBefore' of null error,Table datas are also not displaying.
What is the meaning for this error?Is anything wrong in my code?
var app= angular.module('myApp',[])
app.controller('myController',function($scope){
$scope.details=[
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
},
{
'name':'aaa',
'age':'20'
}
]
$scope.init = function(){
$('#myData').dataTable();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div ng-app="myApp" ng-controller="myController" ng-init="init()">
<table id="myData">
<thead>
<td>S.no</td>
<td>Name</td>
<td>Age</td>
</thead>
<tbody>
<tr ng-repeat="data in details">
<td>{{$index+1}}</td>
<td>{{data.name}}</td>
<td>{{data.age}}</td>
</tr>
</tbody>
</table>
</div>
Can anybody let me know what am wrong?Please correct me if am wrong.Thanks!!:-)
for perform jquery object in controller you can create an directive in this way
but for pagination in table you can download angular-table and add angular-table module to your app.and then use angular table in bellow way
angular table in your view :
<table id="myData" at-config="config" at-table at-list="details">
<tbody>
<tr >
<td at-implicit at-title='S.no'>{{$index+1}}</td>
<td at-implicit at-attribute="name" at-title='Name'></td>
<td at-implicit at-attribute="age" at-title='Age'></td>
</tr>
</tbody>
</table>
<at-pagination at-config="config" at-list="details"></at-pagination>
add config in your controller:
$scope.config = {
itemsPerPage: 10,
maxPages: 5,
currentPage: 0,
orderBy: 0,
fillLastPage: false
};
you can also use pagination directive for your purpose
I am completely new to angular, I need to create a table. The data array is as-follows:-
data = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
I want to create a table with some summary rows based on this data and then when I click the expand button the sub-rows should appear beneath that summary-row indicating the actual data.
For example:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
When I toggle the expand/collapse button on the second row for example I want actual rows to appear like this beneath it:-
Expand/Collapse | No of Students | Subject
click here 1 Maths
click here 2 History
RollNo | StudentName
4 xyz
2 pqr
How Can I achieve this?
1) Grouping the data by subject
First you need to group the data by subject and then count the items in each group.
You can use the angular.filter module's groupBy filter to do this.
1a) Add a dependency on that module as follows:
var app = angular.module("yourModuleName", ["angular.filter"]);
1b) You can then use the groupBy filter in an ng-repeat directive on a <tbody> tag like this:
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
1c) You're now dealing with the data in the format below. This is an object of key/value pairs where "maths" and "history" are both keys, and the arrays are the values
{
"maths": [
{
"rollno": 1,
"name": "abc",
"subject": "maths",
}
],
"history": [
{
"rollno": 4,
"name": "xyz",
"subject": "history",
},
{
"rollno": 2,
"name": "pqr",
"subject": "history",
}
]
}
2) Displaying the grouped data and counting the items in each group
Use key and value to display the grouped data in a table as follows:
<table>
<thead>
<tr>
<th>Subject</th>
<th>Number of Students</th>
<th>Expand/Collapse</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<td>{{ key }}</td>
<td>{{ value.length }}</td>
<td>
<button>
Expand/Collapse
</button>
</td>
</tr>
<tr>
<td colspan="3">
<table>
<thead>
<tr>
<th>Roll Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in value">
<td>{{ student.rollno }}</td>
<td>{{ student.name }}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Note the extra <tr> and nested table with another ng-repeat for displaying the student data. Currently all nested student data will display, the next step is to conditionally show/hide the nested tables based on which expand/collapse button was clicked.
3) Showing/Hiding the nested student data
3a) Add an ng-click directive on the button so that it passes in the key to an onExpandClicked function on your controller:
<button ng-click="onExpandClicked(key)">
Expand/Collapse
</button>
3b) Create the onExpandClicked function in your controller:
$scope.onExpandClicked = function(name){
$scope.expanded = ($scope.expanded !== name) ? name : "";
}
This sets a value on the $scope that can be used in the view to decide whether to show/hide a section of student data. The key is passed into the function as the name parameter and $scope.expanded will either be set to name or reset to "" depending on whether the passed in name is the same as the current $scope.expanded value or not.
3c) Finally, use the $scope.expanded variable in an ng-if directive on the second <tr> tag of <tbody> to show or hide the nested student data:
<table>
<thead>
<tr>
<!-- Omitted for brevity -->
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<!-- Omitted for brevity -->
</tr>
<tr ng-if="expanded === key">
<!--
Omitted for brevity
-->
</tr>
</tbody>
</table>
Demo
CodePen: How to show/hide grouped data created by the angular.filter module's groupBy filter
Design a table with html and iterate through your data object with ng-repeat loop to display the data.
ngRepeat
W3Schools has some basic examples on how to display tables with AngularJS
Angular Tables
First you should replace the actual table by a div structure, because it is not possible to mix two kinds of table like you are planning (when I get you right).
You could toggle every row with a ng-click with the corresponding expanded content like this (pseudo code, I hope the idea gets clear):
<div class="row-header">
<span>RollNo</span>
<span>StudentName</span>
</div>
<div class="row-content" ng-if="!row_4_expanded" ng-click="row_4_expanded = !row_4_expanded">
<span>4</span>
<span>xyz</span>
</div>
<div ng-if="row_4_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
<div class="row-content" ng-if="!row_2_expanded" ng-if="row_2_expanded" ng-click="row_2_expanded = !row_2_expanded">
<span>2</span>
<span>pqr</span>
</div>
<div ng-if="row_2_expanded">
<div class="row-expanded-header">
<span>No of Students</span>
<span>Subject</span>
</div>
<div class="row-expanded-content">
<span>1</span>
<span>Math</span>
</div>
<div class="row-expanded-content">
<span>2</span>
<span>History</span>
</div>
</div>
When you now click on a row, it toggle presens with the corresponding expanded one.
Here is a working example which resolves your problem.
var indexCtrl = ['$scope', function($scope){
$scope.num = 0;
$scope.test = [{rollno: 1,name: 'abc',subject: 'maths'},
{rollno: 4,name: 'xyz',subject: 'history'},
{rollno: 2,name: 'pqr',subject: 'history'}
];
$scope.changeShow = function(index){
$scope.num = index;
};
}];
<!DOCTYPE html>
<html ng-app>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-controller='indexCtrl'>
<table>
<tr>
<td>Expand/Collapse</td>
<td>No of Students</td>
<td>Subject</td>
</tr>
<tr ng-repeat='i in test' ng-class="num == $index ? red : none">{{}}
<td ng-click='changeShow($index)'>click here</td>
<td>{{$index +1}}</td>
<td >{{i.subject}}</td>
</tr>
</table>
<table>
<tr>
<td>RollNo</td>
<td>StudentName</td>
</tr>
<tr ng-repeat='i in test'>
<td ng-show='num == $index'>{{i.rollno}}</td>
<td ng-show='num == $index'>{{i.name}}</td>
</tr>
</table>
<style>
table tr td{
border: 1px solid black
}
</style>
</body>
</html>
Hope it helps you.
I have a simple Angular.js application that grabs tabular data from a mysql database and shows it in a simple bootstrap table. I’m using this code below to show the table column names without hardcoding them individually…
HTML:
<table class="table">
<thead>
<tr style="background:lightgrey">
<th ng-repeat="column in columns"> {{ column }} </th>
</tr>
</thead>
and in the controller I create ’$scope.columns’ with something like this…
var columnNames = function(dat) {
var columns = Object.keys(dat[0]).filter(function(key) {
if (dat[0].hasOwnProperty(key) && typeof key == 'string') {
return key;
}
});
return columns;
};
DataFactory.getTables(function(data) {
$scope.columns = columnNames(data);
$scope.tables = data;
});
And this works as expected and it’s great, but what about the the rest of the data.. So for example, the body of my table currently looks like this…
HTML:
<tbody>
<tr ng-repeat="x in tables ">
<td> {{ x.id}} </td>
<td> {{ x.name }} </td>
<td> {{ x.email }} </td>
<td> {{ x.company }} </td>
</tbody>
I’ve tried using two loops like this…
HTML:
<tbody>
<tr ng-repeat="x in tables">
<td ng-repeat=“column in columns”> {{ x.column }} </td>
</tr>
</tbody>
But this code doesn’t work, So is it possible to populate a table with angular without hardcoding the column names in HTML, and if so whats the most efficient way to do so?
You might want to try this https://jsfiddle.net/8w2sbs6L/.
<div data-ng-app="APP">
<table ng-controller="myController" border=1>
<thead>
<tr>
<td ng-repeat="column in columns">{{column}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in tables">
<td ng-repeat="column in columns">{{x[column]}}</td>
</tr>
</tbody>
</table>
</div>
<script>
'use strict';
angular.module('APP', [])
.controller('myController', ['$scope', function($scope){
$scope.tables = [
{
"column1":"row1-column1",
"column2":"row1-column2",
"column3":"row1-column3",
"column4":"row1-column4"
},
{
"column1":"row2-column1",
"column2":"row2-column2",
"column3":"row2-column3",
"column4":"row2-column4"
}
];
$scope.columns = [
"column1",
"column2",
"column3",
"column4"
];
}]);
</script>
I have a dataset that is displayed in a table. Each object has a child object of Locations, that also have a child object of Region and Sites, which is an array.
I'm having trouble with 2 issues:
First, in my view to display the Sites data (which is the 'State' value), I'm getting duplicates. I'm trying to use the 'unique' filter to show only unique State values, but it's not working.
Second, I'm wanting to use the select lists with these data elements of Region, State/Country/Province and City to act as a filtering mechanism. That's not working either.
See Plunkr for working example: http://plnkr.co/edit/p0ImqB?p=preview
var app = angular.module('plunker', ['angular.filter']);
app.controller('MainCtrl', function($scope, $anchorScroll, $location, $http) {
$scope.cart = [];
$scope.addToCart = function(index) {
$scope.cart.push(index);
$scope.cartCount = $scope.cart.length;
}
$scope.activeRow = function(index) {
$scope.selectedRow = index;
$location.hash();
$anchorScroll('anchor-' + index);
}
$scope.gotoAnchor = function(x) {
var newHash = 'anchor' + x;
}
// GET data
$scope.dataObject = data.List;
$scope.locationObject = data.Locations;
});
body{background:#eee;}
div.cart{display:block;height:70px;background:silver;margin-left:20px;width:200px;padding:5px 10px;margin-bottom:20px;margin-top:20px;}
.cart h1{color:#fff;line-height:20px;}
.item-list-wrapper{height:400px;width:90%;border:1px solid #ddd;overflow-y:scroll;margin-left:20px;}
.item-list-wrapper table td{padding:10px;vertical-align:middle;margin-bottom:10px;font-size:12px;}
.item-list{height:auto;width:100%;margin-bottom:10px;box-shadow:0 2px 2px rgba(0,0,0,0.2);border:1px solid #fff;background:#efefe4;}
.col-num{width:100px;}
.col-compound{width:80px;}
.filters{width:300px;clear:both;margin-left:20px;}
.filters select{display:inline-block;}
.region{font-weight:bolder;}
.state{font-weight:normal;}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap#*" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<link data-require="bootstrap-css#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="angular-ui.min.css" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js" data-semver="1.4.7"></script>
<script data-require="angular.js#1.4.x" data-semver="1.4.7" src="https://code.angularjs.org/1.4.7/angular-messages.js"></script>
<script data-require="ui-bootstrap#*" data-semver="0.13.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.1/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.7/angular-filter.min.js"></script>
<script src="angular-ui.min.js"></script>
<script src="app.js"></script>
<script src="http://zbl.me/test/103015.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-view=""></div>
<div class="filters">
<h2>Filter results</h2>
<select name="selectRegion" class="form-control" ng-model="selectRegion" ng-change="europeSelected()" ng-options="location as location.Region for location in locationObject | orderBy: location.Region:reverse">
<option value="">Select Region</option>
</select>
<select name="selectState" class="form-control" ng-disabled="!selectRegion" ng-model="selectState" ng-options="state as state.StateName for state in selectRegion.States">
<option value="">Select State/Province/Country</option>
</select>
<select name="selectCity" class="form-control" ng-disabled="!selectState" ng-model="selectCity" ng-options="city as city.CityName for city in selectState.Cities">
<option value="">Select City</option>
</select>
</div>
<div class="cart">
<h1>Cart: {{cartCount}}</h1></div>
<div class="item-list-wrapper">
<table class="table table-condensed table-hover">
<tr ng-repeat="data in dataObject | filterBy: ['location.Region']: selectRegion | filterBy: ['state.StateName']: selectState | filterBy: ['city.CityName']: selectCity" ng-click="activeRow($index)">
<td class="column">{{data.Phase}}</td>
<td class="column col-num">{{data.Number}}</td>
<td class="column col-compound">{{data.Item}}</td>
<td>
<span ng-repeat="location in data.Locations track by $index" class="region">{{ location.Region}}:
<span ng-repeat="sites in location.Sites track by $index" class="state">
<span ng-repeat="item in sites.State track by $index | unique: 'item' ">{{item}}</span>
</span>
</span>
</td>
<td>Add</td>
</tr>
</table>
</div>
</body>
</html>
The problem is in the HTML, you were repeating in sites.State but there is not any array there, it's only a string.
Changing the item-list-wrapper to this one in the HTML will solve the problem:
<div class="item-list-wrapper">
<table class="table table-condensed table-hover">
<tr ng-repeat="data in dataObject | filterBy: ['location.Region']: selectRegion | filterBy: ['state.StateName']: selectState | filterBy: ['city.CityName']: selectCity" ng-click="activeRow($index)">
<td class="column">{{data.Phase}}</td>
<td class="column col-num">{{data.Number}}</td>
<td class="column col-compound">{{data.Compound}}</td>
<td>
<span ng-repeat="location in data.Locations track by $index" class="region">{{ location.Region}}:
<span ng-repeat="site in location.Sites | unique: 'State'" class="state">{{site.State}}
</span>
</span>
</td>
<td>Add</td>
</tr>
</table>
</div>
Here´s the plunker: http://plnkr.co/edit/VmLjZmgLtDuds5CM7lKM?p=preview
Regarding the second problem with the filters, I'd solve it with the following custom filters:
app.filter('itemFilter', function() {
return function(input,region,state) {
if (!region)
return input;
return input.filter(function (x) {
return x.Locations.some(function (y) {
if (!state)
return y.Region == region.Region;
else
return y.Sites.some(function (z) {
return z.State == state.StateName;
});
});
});
};
});
app.filter('regionFilter', function() {
return function(input,region,state) {
if (!region)
return input;
return input.filter(function(y) {
if (!state)
return y.Region == region.Region;
else
return y.Sites.some(function (z) {
return z.State == state.StateName;
});
});
};
});
You can use them in the code as shown below:
<div class="item-list-wrapper">
<table class="table table-condensed table-hover">
<tr ng-repeat="data in dataObject | itemFilter:selectRegion:selectState" ng-click="activeRow($index)">
<td class="column">{{data.Phase}}</td>
<td class="column col-num">{{data.Number}}</td>
<td class="column col-compound">{{data.Compound}}</td>
<td>
<span ng-repeat="location in data.Locations | regionFilter:selectRegion:selectState" class="region">{{ location.Region}}:
<span ng-repeat="site in location.Sites | unique: 'State' | filter: { State: selectState.StateName }" class="state">{{site.State}}
</span>
</span>
</td>
<td>Add</td>
</tr>
</table>
</div>
Here's the plunker: http://plnkr.co/edit/liWYtMIC1rDktmBYQtjo?p=preview