ngTable: customizing number of rows buttons - angularjs

In this plunk I have a simple ngTable. I need to customize the buttons that allow the user to select the number of rows shown in the table. For example, if you click on "10" there's an inner shadow, I need to get rid of it. I see that it's a Bootstrap button but can't figure out how to change it. Any ideas?
HTML
<div ng-controller="myCtl" ng-app="app">
<table ng-table="tableParams" class="table table-bordered">
<tbody>
<tr ng-repeat="u in $data">
<td title="'User ID'">{{ u.uid }}</td>
<td title="'Name'">{{ u.nm }}</td>
<td title="'Group'">{{ u.ugr }}</td>
</tr>
</tbody>
</table>
</div>
Javascript
var app = angular.module('app', ['ngTable']);
app.controller('myCtl', function($scope, NgTableParams) {
$scope.data = [{
uid: 'User 1',
nm: 'Name 1',
ugr: 'Group 1'
}, {
uid: 'User 2',
nm: 'Name 2',
ugr: 'Group 2'
}];
$scope.tableParams = new NgTableParams({
count: 5
}, {
data: $scope.data
});
});

Add this css
.btn-default:active, .btn-default.active {
background : white !important;
}

Related

AngularJS recursive templates using tables

I am trying to work out how to do recursion using table tags with angularjs. I have the following data structure
$scope.report = [{
'Name': 'Moo',
'Value': 'MooV',
'Children': [{
'Name': 'Moo2',
'Value': 'Moo2V',
'Children': [{
'Name': 'Moo3',
'Value': 'Moo3V'
}]
}]
}];
The recursion can have no limit. I am looking to put in a simple table with the format
<table>
<tr>
<td>Moo</td>
<td>MooV</td>
</tr>
<tr>
<td>Moo2</td>
<td>Moo2V</td>
</tr>
<tr>
<td>Moo3</td>
<td>Moo3v</td>
</tr>
<table>
but I am unable to get it working just right. This will allow me to do certain things to the sections while looking flat to the user. Currently I have the code
<div ng-app="app" ng-controller='AppCtrl'>
<script type="text/ng-template" id="rloop">
<td>{{data.Name}}</td>
<td>{{data.Value}}</td>
<tr ng-repeat="data in data.Children" ng-include src="'rloop'"></tr>
</script>
<table class="table table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="data in report" ng-include="'rloop'"></tr>
<tr ng-repeat-end></tr>
</tbody>
</table>
</div>
but this is not going to work due to in repeating it creates a tr tag within a tr tag. I have tried various different methods of moving the repeat to tbody etc etc but I can't seems to get it working due to the restrictions of tables in HTML. Example, is not allowed within tr.
JSFiddle showing issue here: JSfiddle
As you say, this is not going to work within the table. Maybe it would be better to recursively convert the data to an array of Name/Value pairs, then use those in the normal way?
var app = angular.module('app', []);
function includeChildren([first, ...rest]) {
if (!first) return [];
const {Name, Value, Children = []} = first;
return [{Name, Value}, ...includeChildren(Children), ...includeChildren(rest)];
}
app.controller('AppCtrl', function ($scope) {
$scope.report = [{
'Name': 'Moo',
'Value': 'MooV',
'Children': [{
'Name': 'Moo2',
'Value': 'Moo2V',
'Children': [{
'Name': 'Moo3',
'Value': 'Moo3V'
}]
}]
}];
$scope.reportTable = includeChildren($scope.report);
// $scope.reportTable now contains:
// [{Name: 'Moo', Value: 'MooV'}, {Name: 'Moo2', Value: 'Moo2V'}, {Name: 'Moo3', Value: 'Moo3V'}]
});
Now you can use a more unsurprising template:
<div ng-app="app" ng-controller='AppCtrl'>
<table class="table table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in reportTable">
<td>{{data.Name}}</td>
<td>{{data.Value}}</td>
</tr>
</tbody>
</table>
</div>
See it working here: https://jsfiddle.net/k6rf9g1p/1/

Incorrect number of rows per page in ngTable

In this plunk I have an ngTable generated with dynamic columns. The number of rows per page is 5, but as you can see the number of rows is 8 without pagination. Is this a defect or I'm doing something wrong?
HTML
<div ng-controller="myCtl" ng-app="app">
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<tr ng-repeat="row in data">
<td title="'Name'" ng-repeat="col in cols">{{row[col.nm]}}</td>
</tr>
</table>
</div>
Javascript:
var app = angular.module('app', ['ngTable']);
app.controller('myCtl', function($scope,NgTableParams) {
$scope.cols = [ {nm:'uid', title:'User ID'}, {nm:'ugr', title: 'Group ID'} ];
$scope.data = [
{ uid: 'User 1',ugr: 'Group 1'},
{ uid: 'User 2', ugr: 'Group 2'},
{ uid: 'User 3', ugr: 'Group 3'},
{ uid: 'User 4', ugr: 'Group 4'},
{ uid: 'User 5', ugr: 'Group 5'},
{ uid: 'User 6', ugr: 'Group 6'},
{ uid: 'User 7', ugr: 'Group 7'},
{ uid: 'User 8', ugr: 'Group 8'}
];
$scope.tableParams = new NgTableParams({count:5},{dataset: $scope.data});
});
Two issues:
$scope.tableParams = new NgTableParams({count:5},{dataset: $scope.data});
should be
$scope.tableParams = new NgTableParams({count:5},{data: $scope.data,counts: [5, 10]});
Note how I used data instead of dataset (I think dataset is for tables without dynamic columns).
In your html, you should get the data from $data, and your columns from $columns. Those dollar sign variables refer to the variables provided to you by ng-table.
Your data was getting loaded directly from $scope.data, instead of using the data passed to NgTableParams.
<table ng-table-dynamic="tableParams with cols" class="table table-bordered table-hover">
<tr ng-repeat="row in $data">
<td ng-repeat="col in $columns">{{row[col.nm]}}</td>
</tr>
</table>
Also, you do not need to set td title, since you are already passing your cols to it.
http://plnkr.co/edit/U8eMbtzAlxIf6ftRtxZA?p=preview
I think the problem is with your HTML code that does not make sense as the tr/td are not correctly created, I fix the issue in the following plunk
Basically, I change the ng-repeat to generate the rows correctly
<table ng-table="tableParams" class="table" show-filter="true">
<tr ng-repeat="user in $data">
<td title="'Name'" filter="{ name: 'text'}" sortable="'name'">
{{user.uid}}</td>
<td title="'Age'" filter="{ age: 'number'}" sortable="'age'">
{{user.ugr}}</td>
</tr>
</table>

AngularJS access another array with $index under ng-repeat

I new to AngularJS and wish to access two arrays under ng-repeat. This is my code:
<tr ng-repreat="find in findOptions">
<td>find.first</td>
<td>find.second</td>
<td>{{ search[{{$index}}].third }}</td>
</tr>
search is another array that I want to access here
You can't have iterpolation inside a intepolation again, basically you could access scope variable directly inside it.
You could simply directly use $index to access array.
search[$index].third
Created JSFiddle Demonstration - https://jsfiddle.net/qtksp1kj/
Hope this will help!
<body ng-app="SampleApp">
<table ng-controller="fcController" border="1px">
<thead>
<tr>
<td>Name</td>
<td>Address</td>
<td>LandMark</td>
</tr>
</thead>
<tbody ng-repeat="element in myArray">
<tr>
<td>{{element.name}}</td>
<td>{{element.address}}</td>
<td>{{myArray1[$index].landMark}}</td>
</tr>
</tbody>
</table>
</body>
var sampleApp = angular.module("SampleApp", []);
sampleApp.controller('fcController', function($scope) {
$scope.myArray = [{
'name': 'Name1',
'address': 'H-1 China Town'
}, {
'name': 'Name2',
'address': 'H-2 China Town'
}];
$scope.myArray1 = [{
'landMark': 'Near Dominos'
}, {
'landMark': 'Near Airport'
}];
});

Sorting only certain arrays in nested ngRepeat

I currently have a nested ngRepeat, where the inner loop iterates over a collection of items from its parent. An excerpt:
<div ng-repeat="person in persons">
(Irrelevant code here.)
<table>
<tr>
<th ng-click="setItemOrder('name')">Item name</th>
<th ng-click="setItemOrder('number')">Item number</th>
</tr>
<tr ng-repeat="item in person.items | orderBy:itemOrder">
<td>{{item.name}}
<td>{{item.number}}
</tr>
</table>
</div>
By clicking the table headers, I set the itemOrder-property in my controller to the name of the property I want orderBy to use:
$scope.setItemOrder = function(order){
$scope.itemOrder = order;
}
This all works fine, except that if I click the headers in one person-div, the item-tables in all person-divs get sorted on that property.
Is there a way to make ngRepeat only apply orderBy to entries that match a certain criteria - for instance a certain index? Or should I use a different approach?
Try setting the property to respective person instance as follows:
angular.module('test', []).controller('testController', function($scope) {
$scope.persons = [{
items: [{
name: 'test',
number: 2
}, {
name: 'test1',
number: 1
}]
}, {
items: [{
name: 'test3',
number: 5
}, {
name: 'test4',
number: 4
}]
}];
$scope.setItemOrder = function(person, order) {
person.itemOrder = order;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
<div ng-repeat="person in persons">
<table>
<tr>
<th ng-click="setItemOrder(person,'name')">Item name</th>
<th ng-click="setItemOrder(person,'number')">Item number</th>
</tr>
<tr ng-repeat="item in person.items | orderBy:person.itemOrder">
<td>{{item.name}}
<td>{{item.number}}
</tr>
</table>
</div>
You could add a ordering variable for each person and extend setItemOrder with the person object. Then you can call:
setItemOrder(person, 'name');
and then use it in the ngRepeat:
orderBy:person.itemOrder
angular.module('test', []).controller('testController', function($scope) {
$scope.ordersort=true;
$scope.orderfield='number';
$scope.persons = {
"items": [{
"name": 'test',
"number": 2
}, {
"name": 'test1',
"number": 1
}],
"item1": [{
"name": 'test3',
"number": 5
}, {
"name": 'test4',
"number": 4
}]
};
$scope.setItemOrder = function(person, order) {
$scope.orderfield=order;
person.itemOrder = order;
$scope.ordersort= !$scope.ordersort;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
<div ng-repeat="person in persons">
<table>
<tr>
<th ng-click="setItemOrder(person,'name')">Item name</th>
<th ng-click="setItemOrder(person,'number')">Item number</th>
</tr>
<tr ng-repeat="item in person | orderBy:orderfield:ordersort">
<td>{{item.name}}
<td>{{item.number}}
</tr>
</table>
</div>
I have modified your example. In this example table sorting is working perfectly. But It is not sorted the particular table when I click on that table header. Anyway to sort columns by specific table?
angular.module('test', []).controller('testController', function($scope) {
$scope.persons = [{
items: [{
name: 'test',
number: 2
}, {
name: 'test1',
number: 1
}]
}, {
items: [{
name: 'test3',
number: 5
}, {
name: 'test4',
number: 4
}]
}];
$scope.setItemOrder = function(person, order) {
person.itemOrder = order;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="test" ng-controller="testController">
<div ng-repeat="person in persons">
<table>
<tr>
<th ng-click="setItemOrder(person,'name')">Item name</th>
<th ng-click="setItemOrder(person,'number')">Item number</th>
</tr>
<tr ng-repeat="item in person.items | orderBy:person.itemOrder">
<td>{{item.name}}
<td>{{item.number}}
</tr>
</table>
</div>

ng-repeat does not work with the list defined in a service

I am new to angular and I am trying to learn, I have a table which I try to fill it with an array that I have:
<table ng-controller="repeatTest">
<tr>
<td>name</td>
<td>family name</td>
<td>score</td>
</tr>
<tr ng-repeat="item in list">
<td>{{ item.name }}</td>
<td>{{ item.familyName }}</td>
<td>{{ item.score }}</td>
</tr>
</table>
and my javascript code is as follow:
app.controller('repeatTest', function($scope, sharedService) {
$scope.list = [ {
name : 'hamed',
familyName : 'Minaee',
score : '100'
}, {
name : 'hamed',
familyName : 'Minaee',
score : '100'
} ];
});
which works perfectly fine but when I use service to hold he array that I have the table does not render, here is the javascript that I use which does not work:
app.service('sharedService', function() {
this.list = [ ];
});
app.controller('repeatTest', function($scope, sharedService) {
sharedService.list = [ {
name : 'ddd',
familyName : 'sss',
score : '100'
}, {
name : 'www',
familyName : 'aaa',
score : '100'
} ];
});
Can anyone help me? How can I make my code work with the second approach?
In angular, any values you wish to access in the view layer need to be attached to either the controller as "this" or to "$scope".
You set "sharedService.list" equal to a value, but that's not available to the view, so "list" will be undefined in your ng-repeat.
What you'd want to do in your controller is:
$scope.list = sharedService.list
and then define your list as:
this.list = [...some list here...]; in your service.
You have to add it to $scope. Often times the service is doing an AJAX call. See this Plunker for a working example: http://plnkr.co/edit/Yx6GYqnSLTzGD2TfB2p8?p=info
var app = angular.module("app", []);
app.service('sharedService', function() {
this.list = [{
name: 'ddd',
familyName: 'sss',
score: '100'
}, {
name: 'www',
familyName: 'aaa',
score: '100'
}];
});
app.controller('repeatTest', function($scope, sharedService) {
$scope.list = sharedService.list ;
});
And the HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js" data-require="angular.js#1.5.0" data-semver="1.5.0"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>
<body ng-app="app">
<table ng-controller="repeatTest">
<tr>
<td>name</td>
<td>family name</td>
<td>score</td>
</tr>
<tr ng-repeat="item in list">
<td>{{item.name}}</td>
<td>{{item.familyName}}</td>
<td>{{item.score}}</td>
</tr>
</table>
</body>
</html>
app.service('sharedService', function(){
this.list = [ {
name : 'ddd',
familyName : 'sss',
score : '100'
}, {
name : 'www',
familyName : 'aaa',
score : '100'
} ];
});
app.controller('repeatTest', function($scope, sharedService){
$scope.list = sharedService.list;
});
The simple approach is define data in service and use that service in controller and bind data using $scope.
<table ng-controller="repeatTest">
<tr>
<td>name</td>
<td>family name</td>
<td>score</td>
</tr>
<tr ng-repeat="item in list">
<td>{{ item.name }}</td>
<td>{{ item.familyName }}</td>
<td>{{ item.score }}</td>
</tr>
</table>

Resources