AngularJS reloading ngTable from ng-change event - angularjs

I am populating ngTable using the following which works fine:
$scope.data = ClientService.query(
{
state: $scope.currentStateId,
parentId: $scope.parentId
});
$scope.data.$promise.then(function (data) {
$scope.tableParams = new ngTableParams(
{
page: 1, // show first page
count: $scope.pageCount, // count per page
sorting: { Name: 'asc' },
filter: { Name: ''}
},
{
total: data.length,
getData: function ($defer, params) {
var orderedData = params.filter() ? $filter('filter')(data, params.filter()) : data;
orderedData = params.sorting() ? $filter('orderBy')(orderedData, params.orderBy()) : orderedData;
params.total(orderedData.length); // set total for recalc pagination
$scope.accounts = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.accounts);
}
});
});
I now wish to update the ngTable from an ng-change event which sets a new $scope.currentStateId as follows:
$scope.stateChange = function () {
//$state.go('root.account.clients.list', { state: $scope.currentStateId, parentId : $scope.parentId }, { reload : true })
//var sel = $scope.currentStateId;
$scope.data = ClientService.query(
{
state: $scope.currentStateId,
parentId: $scope.parentId
});
$scope.tableParams.reload();
};
The ClientService.query hits the server with the correct parameters and returns the correct data but the ngTable is not updated.
Can someone please help.

Update (correct answer)
Promises, by design, can be resolved only once. As a result, nesting new ngTableParams inside of $scope.data.$promise.then(function (data) { limits your ability to update the data at a later point.
Instead, put the callback inside of the getData function so that you can reset $scope.data with a new promise before calling $scope.tableParams.reload():
$scope.data = ClientService.query({
...
});
$scope.tableParams = new ngTableParams({
...
getData: function ($defer, params) {
$scope.data.$promise.then(function (data) {
var orderedData = params.filter() ? $filter('filter')(data, params.filter()) : data;
...
$defer.resolve($scope.accounts);
});
}
});
$scope.stateChange = function () {
$scope.data = ClientService.query({
...
});
$scope.tableParams.reload();
};
Previous Answer (incorrect)
You have a synchronous function call (your ngTable update) following an asynchronous call (the ClientService query). So, the table update executes before the data comes back.
Wrap the table update call in callback that fires once the promise is resolved:
$scope.data = ClientService.query(
{
state: $scope.currentStateId,
parentId: $scope.parentId
});
$scope.data.$promise.then(function (data) {
$scope.tableParams.reload();
};

Related

Iterate through all the records in all the pages in a Angular.js Datatable ng-table

I have a ng-table (angular.js datable) implementation with 25 records per page, on the page i have a submit button on clicking which i need to iterate through all records in all the pages to find which records have been modified in this table.
below is my code with which i can only iterate through the records in the current selected page, not the rest of the pages.
$scope.tableParams = new NgTableParams(
{
page: 1,
count: 25,
},
{
total: records.length,
getData: function ($defer, params) {
$scope.data = params.sorting() ? $filter('orderBy')(records, params.orderBy()) : result;
$scope.data = params.filter() ? $filter('filter')($scope.data, params.filter()) : $scope.data;
$scope.data = $scope.data.slice((params.page() - 1) * params.count(), params.page() * params.count());
$defer.resolve($scope.data);
}
});
var skus = [];
angular.forEach($scope.tableParams.data, function (product) {
if (product.quantity > 0) {
var sku =
{
AddToCart: true,
CategoryId: product.categoryId,
PriceCharged: product.displayPrice,
Quantity: product.quantity,
SkuCode: product.skuCode
}
skus.push(sku);
}
});
Probably you could use event ngTableEventsChannel.onDatasetChanged to catch modified row and copy it to a new object.
You might also try to use ng-change on edited cell.
And remember that you have all your records in records object.

ngTable.reload() unable to refresh ng-table does not show new data second time

ngTable.reload() unable to refresh ng-table does not show new data second time
code for index.js where i'm binding ng-table data.
First time databinding working properly. second time data is not binding properly. it shows previous data.
so basiccally it is unable to bind data and unable to refresh
$http.get("GetValidationsDataForTable", { params: { "entity": entity } })
.success(function (response) {
$scope.tableValue = response;
$scope.tableParams = [];
$scope.tableParams = new ngTableParams(
{
page: 1, // show first page
count: 5 // count per page
},
{
groupBy: 'Entity',
total: $scope.tableValue.length,
getData: function ($defer, params) {
var orderedData = params.filter() ?
$filter('filter')($scope.tableValue, params.filter()) :
$scope.tableValue;
var orderedData = params.sorting() ?
$filter('orderBy')($scope.tableValue, $scope.tableParams.orderBy()) : scope.tableValue;
orderedData = params.filter ?
$filter('filter')(orderedData, params.filter()) :
orderedData;
params.total(orderedData.length);
$defer.resolve($scope.tableValue.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
$scope.tableParams.reload();
})
code for index.cshtml
<table id="tblValue" ng-table="tableParams" class="customTable" style="table-layout:fixed;max-width:100%">
<tbody ng-repeat="group in $groups">
<tr ng-hide="group.$hideRows" ng-repeat="validation in group.data" style="table-layout:fixed;">
<td data-title="'Property'" style="width:10%;text-align:left !important;overflow:hidden;">
<label id="lblProperty" ng-model="validation.Property" for="Property" ng-hide="editmode" style="width:97%;word-wrap:break-word; overflow-wrap:break-word;">{{validation.Property}}</label>
<select class="form-control" data-ng-model="validation.PropertyChoice" data-ng-options="choice.Name for choice in CurrentEntityProperties" ng-change="ChangeValidationRules(validation)" ng-show="editmode" style="width:100%; ">
<option value="" style="margin-left:25px">-Select Property-</option>
</select>
</td>
</tr>
</tbody>
</table>
why ngtable.reload() does not work and also not showing new data second time?
Solution is :
$scope.tableParams = {};
$http.get("GetValidationsDataForTable", { params: { "entity": entity } })
.success(function (response) {
$scope.tableValue = response;
$scope.tableParams = [];
$scope.tableParams = new ngTableParams(
{
page: 1, // show first page
count: 5 // count per page
},
{
groupBy: 'Entity',
total: $scope.tableValue.length,
getData: function ($defer, params) {
var orderedData = params.filter() ?
$filter('filter')($scope.tableValue, params.filter()) :
$scope.tableValue;
var orderedData = params.sorting() ?
$filter('orderBy')($scope.tableValue, $scope.tableParams.orderBy()) : scope.tableValue;
orderedData = params.filter ?
$filter('filter')(orderedData, params.filter()) :
orderedData;
params.total(orderedData.length);
$defer.resolve($scope.tableValue.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
$scope.tableParams.reload();
})
i.e before every request make table parameters blank.
Solution for this problem is make table parameters blanks before any request to the data.
$scope.GetValidationsDataForTable = function(entity) {
// $("div").removeClass("container body-content");
$scope.tab1eParams = {};
SpinStart();
$http.get("GetValidationsDataForTable", {
params: {
"entity": entity
}
}).success(function(response) {
var resultArray = response;
SpinStop();
if (!$.isArray(resu1tArray) || !resultArray.1ength) {
$scope.HideFormVa1ue();
alert("Ho record found for this selection.");
}
else {
$scope.ShowFormVa1ue();
$scope.rows = response;
$scope.groupby = 'Entity',
$scope.tab1eParams = new ngTableParams({
page: 1,
count: 50,
filter: {},
sorting: {}
},
{
groupBy: $scope.groupby,
counts: [],
total: function() {
return $scope.rows.1ength;
},
getData: function($defer, params) {
$defer.resolve($scope.rows.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
You must clone params.filter() before using your service and use params.filter().yourFilter in HTML data binding.
Like that you do not need to use reload(), the ngTable will reload automatically.
Regards.

How to use ngResource with ngtable select box filtering

I am using ngtable with the custom filtering. I am bringing in my data with resource. I am trying to get it to work with one ajax call. I did get it working when I made a call for the table and for each select box. this however is not efficient. I have switched the var data to $scope.data as suggested by other solutions. It is not working.
var data = {};
$scope.data = DocumentUser.query();
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
counts: [], // hide page counts control
total: $scope.data.length, // length of data
getData: function ($defer, params) {
// DocumentUser.query(function (data) {
// use build-in angular filter
var orderedData = params.sorting ?
$filter('orderBy')($scope.data, params.orderBy()) :
$scope.data;
orderedData = params.filter ?
$filter('filter')(orderedData, params.filter()) :
orderedData;
$scope.data = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve($scope.data);
// });
}
});
var inArray = Array.prototype.indexOf ?
function (val, arr) {
return arr.indexOf(val)
} :
function (val, arr) {
var i = arr.length;
while (i--) {
if (arr[i] === val) return i;
}
return -1;
}
$scope.DocumentTypes = function (column) {
var def = $q.defer(),
arr = [],
DocumentTypes = [];
// DocumentUser.query(function (data) {
angular.forEach($scope.data, function (item) {
if (inArray(item.DocumentType, arr) === -1) {
arr.push(item.DocumentType);
DocumentTypes.push({
'id': item.DocumentType,
'title': item.DocumentType
});
}
// });
});
def.resolve(DocumentTypes);
return def;
};//
$scope.DocumentLocations = function (column) {
var def = $q.defer(),
arr = [],
DocumentLocations = [];
// DocumentUser.query(function (data) {
angular.forEach($scope.data, function (item) {
if (inArray(item.DocumentLocation, arr) === -1) {
arr.push(item.DocumentLocation);
DocumentLocations.push({
'id': item.DocumentLocation,
'title': item.DocumentLocation
});
}
//});
});
def.resolve(DocumentLocations);
return def;
};//
$scope.DocumentPlants = function (column) {
var def = $q.defer(),
arr = [],
DocumentPlants = [];
// DocumentUser.query(function (data) {
angular.forEach($scope.data, function (item) {
if (inArray(item.DocumentPlant, arr) === -1) {
arr.push(item.DocumentPlant);
DocumentPlants.push({
'id': item.DocumentPlant,
'title': item.DocumentPlant
});
}
//});
});
def.resolve(DocumentPlants);
return def;
};
Update
$scope.data = {};
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
counts: [], // hide page counts control
total: $scope.data.length, // length of data
getData: function ($defer, params) {
// DocumentUser.query(function (data) {
// use build-in angular filter
var orderedData = params.sorting ?
$filter('orderBy')($scope.data, params.orderBy()) :
$scope.data;
orderedData = params.filter ?
$filter('filter')(orderedData, params.filter()) :
orderedData;
$scope.data = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve($scope.data);
}
});
$scope.data = DocumentUser.query({}, function () {
$scope.tableParams.reload();
});
ngResource immediately returns an object. For query it is actually an empty array with a promise attached ($promise). Your getData function is building the table with an empty array. There are many ways to solve this, but one simple thing is just to call reload on the table params (which will cause another call to getData()). You can just do that when the promise finishes.
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
counts: [], // hide page counts control
total: $scope.data.length, // length of data
getData: function ($defer, params) {
// DocumentUser.query(function (data) {
// use build-in angular filter
var orderedData = params.sorting ?
$filter('orderBy')($scope.data, params.orderBy()) :
$scope.data;
orderedData = params.filter ?
$filter('filter')(orderedData, params.filter()) :
orderedData;
orderedData = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve(orderedData);
});
}
$scope.data = DocumentUser.query({}, function(){
$scope.tableParams.reload();
});
});

How to add Search using ngTable

My current code is pulling data using JSON. I can see my data load correctly on ngTable.
How can I add a search box that upon clicking the button, initiates a search and reloads data on my ngTable? I have tried using tableParams.reload() within an ngClick but that doesn't reload my data.
Controller
app.controller('ModelPagingCtrl', function ($scope, ngTableParams, $filter,
$http, DataService) {
$scope.doSearch = function () {
DataService.getModels($scope.SearchText).then(function (data) {
console.log("GetModels Worked");
$scope.data = data.d;
$scope.tableParams = new ngTableParams({
page: 1,
count: 10,
filter: {
ModelNum: ''
},
sorting:
{
ModelNum: 'asc'
}
}, {
total: $scope.data.length,
getData: function ($defer, params) {
// use built-in angular filter
var filteredData = params.filter() ?
$filter('filter')($scope.data, params.filter())
: $scope.data;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy())
: $scope.data;
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1)
* params.count(), params.page() * params.count()));
}
}, function (error) {
console.log('errror', error);
});
});
Factory/DataService
app.factory('DataService', function ($http, $q) {
return {
getModels: function (Search) {
return $http.post('AngularWithWebServices.aspx/FetchModels',
{ "search": Search }).then(function (response) {
if (typeof response.data === 'object') {
console.log('object found');
return response.data;
} else {
// invalid response
console.log("Invalid Response");
return $q.reject(response.data);
}
}, function (response) {
// something went wrong
console.log("Error Response!");
return $q.reject(response.data);
});
}
};
});
HTML
Search: <input ng-model="SearchText"/>
<button ng-click="doSearch()">Search</button>**<----What goes here?**
<table class="table" ng-table="tableParams" show-filter="true" >
<tr ng-repeat="item in $data" >
<td data-title="'ModelNum'" sortable="'ModelNum'"
filter="{ 'ModelNum': 'text' }">
{{item.ModelNum}}
</td>
<td>
<strong>Year:</strong><p>{{item.Year}}</p>
<strong>Price:</strong><p>{{item.Price}}</p>
<p>{{item.Features}}</p>
</td>
</tr>
</table>
I didn't test this code but it should work for you.
app.controller('ModelPagingCtrl', function ($scope, ngTableParams, $filter, $http, DataService) {
$scope.doSearch = function() {
$scope.tableParams.reload();
}
function search(params)
{
return DataService.getModels($scope.SearchText);
}
$scope.tableParams = new ngTableParams({
page: 1,
count: 10,
filter: {
ModelNum: ''
},
sorting:
{
ModelNum: 'asc'
}
}, {
getData: function ($defer, params) {
//pass params.url() to your search function http://whatever.dev?count=10&page=1&sorting%5Bid%5D=desc
search(params.url()).then(function(data)
{
//you have 2 ways from here
// 1. if you use server side sorting, filtering
params.total(data.length);
$defer.resolve(data);
// 2. if you use client side sorting/filtering
var filteredData = params.filter() ?
$filter('filter')(data, params.filter())
: data;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy())
: filteredData;
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1)
* params.count(), params.page() * params.count()));
}
}
}, function (error) {
console.log('errror', error);
});
});

How to insert a row via ajax with NgTable?

Ok, i´m trying to do something very simple, here is my code:
<tr data-ng-repeat="data in $data | filter:searchText">
and i´ve this function, it´s called when i want to generate my table...
$scope.init = function (obj) {
if (isValid(obj)) {
generateService.sendUrlViaPost(obj.url, obj.params).then(function (response) {
$scope.$data = response;
$scope.tableParams = new ngTableParams({
page: obj.page,
count: obj.count,
}, {
total: $scope.grid.data.length,
getData: function ($defer, params) { //$data
orderedData = params.sorting() ? $filter('orderBy')($scope.$data, params.orderBy()) : $scope.$data;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
Calling it at my html(it´s working fine)
data-ng-init="init({url: '/Professional/GetAll', params: false, page: 1, count: 10})"
The problem is when i call it when i submit my form and i want to reload via ajax and insert one row at my ngTable...
gridService.init({ url: '/Professional/GetAll', params: false, page: 1, count: 10});
Why my ngTable isn´t reloading? I think that the problem is with my ng-repeat because it isn´t reloading my table...

Resources