How to add Search using ngTable - angularjs

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);
});
});

Related

AngularJS Firebase database ng-repeat filtered data into ngtable with ngTableParams

I filter one Firebase database based on another and concatenate the result into one $scope and ng-repeat the $scope array projectslist in a ngtable with ng-repeat="obj in projectslist", which works fine!
however, when I want to add ngTableParams to my table, it breaks and shows only the first object in the array. This time I ng-repeat like this: ng-repeat="obj in $data".
here is the console log of the concatenated array:
here is the controller:
app.controller('ProjectCtrl', ["$scope", "$filter", "ngTableParams", "firebase", "Auth", "DatabaseRef", "$firebaseArray", "$firebaseObject",
function ($scope, $filter, ngTableParams, firebase, Auth, DatabaseRef, $firebaseArray, $firebaseObject) {
var userId = firebase.auth().currentUser.uid;
$scope.projectslist = [];
var projectsRef = DatabaseRef.ref('/users/' + userId).orderByKey().once("value")
.then(function onSuccess(snapshot) {
snapshot.child("projects").forEach(function (childSnapshot) {
var userprojects = childSnapshot.val();
var projectquery = DatabaseRef.ref("projects").orderByKey().equalTo(userprojects);
var list = $firebaseArray(projectquery);
$scope.list = $firebaseArray(projectquery);
list.$loaded(function(){
$scope.projectslist = $scope.projectslist.concat(list);
});
var data = $scope.list;
data.$loaded().then(function(data) {
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 7, // count per page
}, {
dataset: data,
filterSwitch: true,
getData: function ($defer, params) {
var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data;
var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : data;
params.total(data.length);
// set total for recalc pagination
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
});
});
}]);
The question is:
how to ng-repeat the data in a table with ngTableParams working as well, filtering, sorting, pagination?
You need to first sort your data, then go for filtering and then you can apply pagination on the data.
$scope.tableParams = new NgTableParams(
{
page : 1, // show first page
count : 5, // count per page
},
{
getData : function($defer, params) {
{
if (!$scope.projectslist|| !$scope.projectslist.length) { return; }
$scope.data = params.sorting() ? $filter('orderBy')($scope.projectslist, params.orderBy()) : $scope.projectslist;
$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);
}
}
});
Then you can use it in html like below defined
<table ng-table="tableParams" class="table table-striped responsive" show-filter="true" border="1" cellspacing="1" style="padding-left: 100px;padding-right: 100px;">
<tbody ng-repeat="obj in $data">
<tr ng-form="rowForm">
<td data-title="'Project Name'" filter="{'project_name':'text'}" sortable="'project_name'"
style="overflow: auto; -webkit-overflow: auto;"
><label>{{obj.project_name}}</label>
</td>
<!--<td>
More rows </td>-->
</table>

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 configure Ajax Call with ngTable

I am trying to get the code correct, I used ngTable a long time ago and I forgot how I got it to work. The Json is returning fine. But Nothing is going through ngTable.
var data = CustomerGet.query().then(function (data) {
$scope.customerArray = data;
}, function (reason) {
errorMngrSvc.handleError(reason);
});
//Customer Employee Table
$scope.tableParams = new ngTableParams({
count: data.length // hides pager
}, {
counts: [], // hides page sizes
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()));
}
});
View
<table ng-table="tableParams" class="table">
<tbody ng-repeat="group in $groups">
<tr class="ng-table-group">
<td colspan="{{$columns.length}}">
<a href="" ng-click="group.$hideRows = !group.$hideRows">
<span class="glyphicon" ng-class="{ 'glyphicon-chevron-right': group.$hideRows, 'glyphicon-chevron-down': !group.$hideRows }"></span>
<strong>{{ group.value }}</strong>
</a>
</td>
</tr>
<tr ng-hide="group.$hideRows" ng-repeat="user in group.data">
<td sortable="name" data-title="'Name'">
{{user.CustomerEmployees.CustomerEmployeeFirstName}}
</tr>
</tbody>
</table>
UPDATE
CustomerEmployeeGet.query()
.success(function (data, status) {
$scope.customerArray = data;
$scope.tableParams = new ngTableParams({
count: customerArray.length // hides pager
}, {
counts: [], // hides page sizes
groupBy: 'Role',
total: customerArray.length,
getData: function ($defer, params) {
var orderedData = params.sorting() ?
$filter('orderBy')(customerArray, $scope.tableParams.orderBy()) :
customerArray;;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
I am making some progress.
Error
TypeError: undefined is not a function
and that is at the .success line
I skipped my http factory and did everything from the controller
//Get CustomerEmployees
$http.get('/api/apiCustomerEmployee')
.success(function (data, status) {
$scope.tableParams = new ngTableParams({
count: data.length // hides pager
}, {
counts: [], // hides page sizes
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()));
}
});
});

AngularJS reloading ngTable from ng-change event

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();
};

Resources