I am using Angular routing in my application as well as ngTable. One of my pages contains a ngTable, and a search form, where data is coming from database using GET method (MongoDB) every time I search, so every time I search the ngTable (table) should be updated, and my problem is that the Table is updated only one time, after loading the page for the first time.
The contoller used for the partial page :
app.controller('SearchController',function($scope,ngTableParams,$http,$filter, $sce){
$scope.searching=function(){
var str = $scope.search.tags;
var TagsArry = str.split(",");
$http.get('/api/GetDoc',{params:{title:$scope.search.title,tags:$scope.search.tags}})
.success(function(data)
{
if(data.notExist!=-1){
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
}
})
.error(function(err){
});
}
});
I was having the same issue. You need to reload $scope.tableParams every time a new search occurs, so every time the search button is clicked. A simple way to do this is to wrap $scope.tableParams.reload() in a function, and then call that function when your search button is clicked.
controller code:
$scope.doSearch = function () {
$scope.tableParams.reload();
}
html code:
<button ng-click="doSearch()">Search</button>
I was also having the similar issue. It is a problem with the ngTable directive. It updates only when data.length changes. I had finally solved this issue, simply add this line before your $http request:
$scope['tableParams'] = {reload:function(){},settings:function(){return {}}};
$http.get('/api/GetDoc',{params:{title:$scope.search.title,tags:$scope.search.tags}})
.success(function(data){
/***** Your Code *********/
});
What it does is, it resets the ng-table settings then it initilize like it does for the first time.
Related
My project outputs results to a DataTable from an AngularJS controller function, but I'm running into some strangeness when I try to modify my search params. The first rendering of the table works as expected. But when I select different options and run the search again, extra rows appear in the table, but the info section shows the previous search's row count, and changing the number of rows shown via the length menu causes the new rows to disappear. Here's my table declaration, using attributes to wire up DataTables:
<table ui-jq="dataTable" ui-options="dataTableOptions" id="search-results" class="display nowrap datatable cell-borders" style="width: 100%;">
And this is my AngularJS controller code:
$scope.dataTableOptions = {
dom: "lfBrtip",
lengthMenu: [[25, 50, -1], [25, 50, "All"]],
language: {
emptyTable: 'No items matched your search criteria'
},
buttons: [
{
text: 'Export',
className: 'button button:hover',
extend: 'csv'
}
]
};
$scope.getItemInfo = function (model) {
$http({
method: 'POST',
url: $scope.getUrl('/My/ServerSide/Url'),
data: { model: $scope.model }
}).then(function successCallBack(response) {
$scope.model.SearchResults = response.data;
}, function errorCallback(response) {
alert("There was an error gathering the entity information. Please try again");
});
};
I'm not sure why submitting new queries with different params doesn't simply update the data in the DataTables table. Any suggestions?
I ended up using a bit of an ugly hack to get this to work. Even DataTables author wasn't sure how to get around the issue of using AngularJS with DataTables, so I had to force a reinitialization every time the form posted. I persisted the search params to localStorage, and called location.reload(). Then when the page loads and the AngularJS init() function runs, I pick up the search params and call the search function from inside an Angular document ready function, like this:
$scope.init = function () {
$scope.ValidationErrors = [];
$scope.model = {};
$scope.model.SearchResults = [];
$scope.model.ItemNumber = localStorage.getItem("itemNumber");
$scope.model.StartDate = localStorage.getItem("startDate");
$scope.model.EndDate = localStorage.getItem("endDate");
angular.element(document).ready(function () {
if ($scope.model.ItemNumber) {
$scope.getItemRecords();
}
});
localStorage.clear();
};
And then of course I clear the localStorage after the query. Not terribly elegant, but it'll have to do for now.
I am trying to implement this server side pagination example of ng-grid mentioned here http://angular-ui.github.io/ng-grid/ . Unfortunately, I do not quite understand the code.
Here is my situation:
1. Say I have a page which has 2 text boxes and a button. I would like to post the values of these two text boxes to a web service on ng-click of the button. Returned json should be displayed as grid. But the code in the plunker http://plnkr.co/edit/50vJrs?p=preview
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('largeLoad.json').success(function (largeLoad) {
data = largeLoad.filter(function(item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data,page,pageSize);
});
} else {
$http.get('largeLoad.json').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
will render the grid on page load (which I do not want). What I dont understand is how to associate the $scope.getPagedDataAsync function with a ng-click?
The html code doesnt have any textbox for searching through the grid even though in the controller they have $scope.filterOptions. How is the search happening the in plunker code?
Wish there was more documentation on the site.
Thank you
In the plunker, the function quoted in your question is immediately invoked:
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
Does commenting out that line have the desired effect?
As for the filter, it's probably there as a convenience so you can add a filter text field yourself. It is defined in an object so you can use a custom directive or ng-include block.
Im AngularJs newbie:).
But I have 3 components: controller C1 (for entering search input and clicking submit button),controller C2 (for div which will receive results from SearchService and display it) and service searchService for sending some hardocoded results.
THe idea is that after submitting search text, I have to submit it twice. With one submit click, view of ui-router is updated to partial page without results loaded. After second click the results are displayed.
Then next searches are done on search view page, all is ok, one click gives needed data.
How to fix it: I want to change ui-router view and get results from service with one click?
C1 method code (started after submiting searchText)
$scope.searchText = function searchText(text) {
$log.log("Method searchText with text: " + text);
//var parametersObject = {searchText: text, results: assetResults}
$state.go('search');
$log.log("SearchInputBoxController: rootScope Broadcasting message: " + text);
$rootScope.$broadcast('DoSearch', text);
$log.log("SearchInputBoxController finished");
};
C2 method: event handler for event 'DoSearch'
$scope.$on('DoSearch', function (event, data) {
$scope.asset = searchService.search(data);
$scope.searchText = data;
});
searchService code:
Application.Services.factory('SearchService', ['SearchServiceResource', '$q',
function (SearchServiceResource, $q) {
return {
search : function (searchText)
{
var result = [
{id: 'aaaaa', sn:"1234-1234-1234-1235", name:"DCU_name1", type: "DCU", tags: ["tag1", "tag2"]},
{id: 'aaaaa', sn:"1234-1234-1234-1235", name:"DCU_name2", type: "DCU", tags: ["tag1", "tag2"]},
{id: 'aaaaa', sn:"1234-1234-1234-1235", name:"NODE_name1", type: "DCU_Node", tags: ["tag1", "tag2"]}
];
return result;
}
};
}]);
I believe the clicking twice is because the first click is triggering the state change, then the broadcast occurs, and then the state change occurs. The second click, the state doesn't need to change, and the current now unchanged controller gets the broadcast. There are a couple different approaches I can think of (and I would def shy away from rootscope broadcasting):
in your shared service, maintain a search string variable and on your
controller, put watch on that service's variable.
change your route/state settings to include a parameter like /search/:searchTerm and in the controller, look for the state established searchTerm variable and on the controller load see if searchTerm is provided and fire the search. Some more info here
Let me now if you need any help or more specifics on the ideas listed.
I want to show table parameters (page, count, filter, etc.) in the url. so I use the following code in my controller :
$scope.tableParams = new ngTableParams(
angular.extend({
page : 1,
count: 10
},
$location.search()), {
getData: function ($defer, params) {
$location.search(params.url()); // put params in url
var query = getQuery();
query.limit = params.count();
query.offset = (params.page() - 1) * params.count();
getTotalCount().success(function () {
Content.prototype.find(query)
.success(function (response) {
$scope.tableParams.total($scope.totalCount);
var data = $filter('populateObjects')(response.data, query.fields);
$defer.resolve(data);
});
});
}
});
I do pagination and filtering on server side.
without applying filters on the table everything goes ok and the pagination works correctly. but every time I apply a filter on the table url change twice. the first time it is ok. something like this :
http://faraketabadmin/src/#/content/list?page=7&count=10&filter%5Bname%5D=g&filter%5Btype_id%5D=4
but after a moment it will again reset to page 1 like this :
http://faraketabadmin/src/#/content/list?page=1&count=10&filter%5Bname%5D=g&filter%5Btype_id%5D=4
I'm using the ngTable directive and the problem is that the data doesn't refresh in the table.
When loading the page, the gemId is undefined and no data shows which is ok.
Then you select a value from a dropdown and when pressing a button the loadItems function is called. Data is retrieved from the server but does not show in the table.
When I filter a column, the data is shown (= 2nd request ).
$scope.tblProject = new ngTableParams(tableParameters, {
counts: [], // hide page counts control
total: $scope.items.length, // value less than count hide pagination
//defaultSort: ['asc','desc'];
getData: function ($defer, params) {
//opgelet: request is geldig ondanks de onbestaand igeID;
var gemId = modelFactory.getGemeente().id;
var igeId = 22222;
if(!angular.isUndefined(gemId)){
Project.query({gemId: gemId, igeId: igeId}, function (projecten) {
var orderedData = params.sorting() ? $filter('orderBy')(projecten, params.orderBy()) : projecten;
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
});
}
},
$scope: { $data: {} } //see example 14
});
$scope.$on('loadItems',function() {
$scope.tblProject.reload();
});
Tried all the possible work-arounds for refreshing the table so far, but have had no luck.
edit: I think it is a scope problem when executing the 'loadItems'
The problem was that I was sending an event from the parentController to the childController using $emit instead of $broadcast which executes 'loadItems'