How to dynamically re-draw data in table. Angular ngTable - angularjs

I have controller with just 1 function getList(). When I call it first time - everything is just fine and my table show proper data. But when I call this function again (with new params in order to get different data in response), I still have data in table from the first call. How to reload/redraw/refresh data?
module.controller("IPsCtrl", function($scope, $filter, IPService, ngTableParams) {
$scope.data_out = {
'ip_pattern' : '%',
};
$scope.getList = function() {
$scope.data=IPService.getList($scope.data_out,
function(response) {
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
id: '' // initial filter
},
sorting: {
id: 'asc' // initial sorting
}
}, {
total: response.list.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')(response.list, params.filter()) :
response.list;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) :
response.list;
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
};
});
Here is html view
<table ng-table="tableParams" show-filter="true" class="table">
<tr ng-repeat="user in $data">
<td data-title="'Name'" sortable="'id'" filter="{ 'id': 'text' }">
{{user.id}}
</td>
<td data-title="'Age'" sortable="'value'" filter="{ 'value': 'text' }">
{{user.value}}
</td>
</tr>
</table>

There is a provided method to do just that:
$scope.tableParams.reload();
Just call it after you update the data the table is displaying.
Edit:
First off, I think your current use of ngTable is incorrect. Instead of tying the table directly to the response data, I think the best thing to do would be to store your response data in a $scope variable, and then attach it to your ngTable. That way you only have to manipulate the $scope data and call reload.
From there it is simply a matter of updating the stored data then calling reload:
// Store your data in a dedicated variable
$scope.myData = response.list;
// Update ngTable to reflect the new data
if ($scope.tableParams) {
$scope.tableParams.reload();
} else {
// create your table as before,
// but tying it to $scope.myData
// instead of response.list
}

Related

ng-table data not showing on page load

I have integrated ngTable into my mean.io stack and I'm having trouble with populating the table on page load. If I select one of the column headers, the data shows up and the table works as advertised.
Here is my html
<table ng-table="tableParams" class="table">
<tbody ng-repeat="p in $data">
<tr id="tr{{p._id}}" ng-class-odd="'odd'" ng-class-even="'even'">
<td class="rowTd" data-title="'Task Code'" sortable="'task_code'">{{p.task_code}}</td>
<td class="rowTd" data-title="'Task Name'" sortable="'task_name'">{{p.task_name}}</td>
<td class="rowTd" ><input type=button id="editRowBtn{{p._id}}" value="edit"
ng-click="setEditId(p._id)"></td>
</tr>
<tr ng-show="editId===p._id" ng-if="editId===p._id">
<td colspan="7" ng-include src="'editRow.html'"></td>
</tr>
</tbody>
</table>
Here is my controller code.
var data = GeneralTasks.query();
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
},{
total: data.length,
getData: function($defer, params) {
params.total(data.length);
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
$scope.editId = -1;
$scope.setEditId = function(pid) {
$scope.editId = pid;
};
I am new to using this table so i'm sure there is something i'm overlooking.
Wanted to provide the answer to my question so it may help others. Anytime an item in the table is added or removed, the table must be reloaded. Since $save and $remove invoke a callback function, just inserted the following for updating the table.
$scope.add = function() {
if (!$scope.tasks) $scope.tasks = [];
var task = new GeneralTasks({
task_code: $scope.task_code,
trade: $scope.trade,
task: $scope.task,
task_name: $scope.task_name
});
task.$save(function(response) {
$scope.tasks.push(response);
var data = $scope.tasks;
$scope.tableParams.total(data.length);
$scope.tableParams.reload();
});
this.task_code = this.trade = this.task = this.task_name = '';
};
First i update the $scope list with the response and then update the tables data and length. Then just call reload.
As I've stated earlier, i do this for $save and $remove. Here is the $remove code.
$scope.remove = function(task) {
for (var i in $scope.tasks) {
if ($scope.tasks[i] === task) {
$scope.tasks.splice(i, 1);
}
}
task.$remove();
var data = $scope.tasks;
$scope.tableParams.total(data.length);
$scope.tableParams.reload();
};
I have noticed that when I edit a name in the list and then cancel, the name does not reset. I suppose I should add similar code for the cancel action but I'm lazy and that's the least of my worries for now. :)
Hope this helps someone else.

How to filter and sort array elements in ngtable?

I have an array which I am using in ngtable, but need help in filtering data I am not able to do sort when I click on the header. Please help
HTML
<table class="table" ng-table="namingConventionParams" show-filter="true">
<tr ng-repeat="item in $data | orderBy:'toString()'">
<td style="word-break:break-all" data-title="items.tableHeader" align="left" filter="{ '0': 'text' }" sortable="'valueOf()[0]'">{{item}}</td>
</tr>
</table>
Controller
$scope.namingConventionParams = new ngTableParams({
page: 1, // show first page
count: 10
}, {
defaultSort: "asc",
total: $scope.items.instanceData.length, // length of data
counts: [],
getData: function($defer, params) {
var data = $scope.items.instanceData;
var orderedData = params.filter() ? $filter('filter')(data, params.filter()) : data;
orderedData = params.sorting() ? $filter('orderBy')(orderedData, params.orderBy()) : orderedData;
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
Plunker link
The problem with your code is that your array of data only contains strings instead of objects, so it's filtering based only on the first character when you have sortable="valueOf()[0]"
The solution is to use objects instead. Here is the relevant code that needs to be updated:
HTML
<td ... filter="{'name':'text'}" sortable="name">{{item.name}}</td>
JS
var data = $scope.items.instanceData.map(function(text) {
return {name: text};
});
Plunker Demo

angularJS with ng-table is not loading data on returning to listing from detail page

I am using angular JS with ng-tables with rails as an API.
i successfully integrated ng-tables with server side pagination. The issue i am facing is whenever i go back list page from detail page. table data is not visible. i checked in logs and using breakpoints . i can see data but not lucky.
my controller is sampleController.js
function sampleController($scope, $http, ngTableParams, $state, Auth) {
$data = [];
$scope.tableParams = new ngTableParams({
page: 1,
count: 10
}, {
getData: function($defer, params) {
$http.get('sample.json', {
params: {
page: params.page()
}
})
.success(function(response, status) {
$data = response.data;
params.total(response.count);
$defer.resolve($data);
});
}
});
and my html template is as follows
<table ng-table="tableParams" class="table ng-table-responsive">
<tr ng-repeat="data in $data.tasks">
<td data-title="'Title'">
{{data.title}}
</td>
</tr>
</table>
also i referred issue . but i couldn't able to fix it.
I appreciate your time and input. Hoping for solution from you guys.

How to filter and refresh ngtable pagination on a custom fiter

I want to filter ngtable based on value taken from dropdown box.
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 5, // count per page
sorting: {
name: 'asc' // initial sorting
},
}, {
total: tabledata.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
filteredData = params.filter() ?
$filter('filter')(tabledata, params.filter()) :
tabledata;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) : filteredData;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
I have posted my full code on plunker: http://plnkr.co/edit/YbCe5Y6qIxN18yHCrzwW?p=preview.
Problem that occurs is that number of pages remains the same, but if some of my results were on page 5 they will remain there. Basically I have empty pages and among them will be pages with filtering result (there is no page downsizing).
I tried to incorporate my custom filter - viewFilter but I was unsuccessful in making it work. This is another plunker example where filtering is basic (based on column name) and works: http://plnkr.co/edit/CbmbXTXukNxC1ZzkJNKO?p=preview
Does anyone knows ad could help me with integration of this custom filter? Thanks
you are not invoking the filter of the table, you are just filtering the page you are on. In order to solve you issue, you should invoke the filter function of ng-table from you viewFilter function. I did few changes to your code and works as expected. In the controller I've change the values of the viewOptions, I've included a filter in the table and I've invoked the filter function from your viewFilter. Now it looks like:
$scope.viewOptions = [
{
name: 'All',
value: ''
},
{
name: 'Approved',
value: 'Y'
},
{
name: 'Declined',
value: 'N'
}
];
$scope.view = { type: '' };
$scope.viewFilter = function (data) {
var filter = $scope.view.type;
$scope.tableParams.filter(filter, data);
};
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
name: 'asc' // initial sorting
},
filter:{
flag_approved:''
}
}, {
total: tabledata.length, // length of data
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ? $filter('filter')(tabledata, params.filter()) : tabledata;
var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : filteredData;
params.total(filteredData.length);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
}); `
Blockquote
In the html i'm calling the viewFilter function every time that the dropdown in changed and I've removed the filter from the table. Now it looks like: `
Page: {{tableParams.page()}}
Count per page: {{tableParams.count()}}
Sorting: {{tableParams.sorting()|json}}
Filter: {{tableParams.filter()|json}}
Data: {{tableParams.ordered()|json}}
<div class="row">
<div class="col-xs-6 text-left">
<form class="filter-form form-inline" role="form">
<div class="form-group">
<label for="drop-actions">View:</label>
<select id="drop-actions" class="form-control" ng-model="view.type" ng-options="opt.value as opt.name for opt in viewOptions" ng-change="viewFilter()">
</select>
</div>
</form>
</div>
</div>
<table class="table table-bordered" ng-table="tableParams">
<tr ng-repeat="g in $data">
<td data-title="'Name'" sortable="'name'">
{{ g.name }}
</td>
<td data-title="'Head2'">
{{ g.flag_approved }}
</td>
</tr>
</table>
To fix the issue change $scope.view.type = ''; and instead put $scope.view = { type: '' };

ng-table grouping - initialize with rows minimised

I am using the grouping example of ng-table from http://plnkr.co/edit/CBcbkc
Right now the table is initialised with rows expanded, but I would like them to be minimised as I have over 100 records. How can I do this?
You can set group.$hideRows to true using ngInit:
<tbody ng-repeat="group in $groups" ng-init="group.$hideRows = true">
Update
I wanted to find a better solution, because the angular docs discourage using ngInit to access scope variables.
You can create a controller for each group created in the ng-repeat:
<tbody ng-repeat="group in $groups" ng-controller="groupCtrl">
Then, you can access the group object directly. One advantage of this would be the ability to conditionally expand a group:
.controller('groupCtrl', function($scope) {
if ($scope.group.value != 'Administrator')
$scope.group.$hideRows = true;
});
http://plnkr.co/gXfsBq
FYI
I wondered why I couldn't find any references to $hideRows in the source. It turns out that the group object doesn't have a $hideRows property until after it is clicked. To prove this, I replaced $hideRows with a made up name and it worked just the same.
<tbody ng-repeat="group in $groups">
<tr class="ng-table-group">
<td colspan="{{$columns.length}}">
<a href="" ng-click="group.invokeInvisbility = !group.invokeInvisbility">
<span class="glyphicon" ng-class="{ 'glyphicon-chevron-right': group.invokeInvisbility, 'glyphicon-chevron-down': !group.invokeInvisbility }"></span>
<strong>{{ group.value }}</strong>
</a>
</td>
</tr>
<tr ng-hide="group.invokeInvisbility" ng-repeat="user in group.data">
No wonder you couldn't find a way to initialize it.
You can tell ngTable to not expand it via the property 'groupOptions' see below:
var table = new NgTableParams({ group: 'name' }, { dataset: users, groupOptions: { isExpanded: false } });
Just add groupOptions: {isExpanded:false} in the params section.
Below is a copy of your code with the proper add-on.
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
groupOptions: {isExpanded:false}
}, {
groupBy: 'role',
total: data.length,
getData: function($defer, params) {
var orderedData = params.sorting() ?
$filter('orderBy')(data, $scope.tableParams.orderBy()) :
data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});

Resources