Angular ngGrid pagination forward buttons won't disable - angularjs

I've a json with some data stored on $scope.data.
JS
$scope.pagingOptions = {
pageSize: 5,
currentPage: 1
};
$scope.setPagingData = function (data, page, pageSize) {
var pagedData = data.slice((page - 1) * pageSize, page * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.pagingOptions.totalServerItems = data.length;
};
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.setPagingData($scope.data, $scope.pagingOptions.currentPage, $scope.pagingOptions.pageSize);
}
}, true);
$scope.gridOptions = {
data: 'myData',
enableRowSelection: false,
enablePaging: true,
showFooter: true,
pagingOptions: $scope.pagingOptions
};
HTML
<div class="gridStyle" ng-grid="gridOptions"></div>
Problem
"myData" has 8 results. First page shows 5, second page shows 3, BUT forward button doesnt disable when there are no more results in array "myData".
Otherwise, back button works properly.

It was missing totalServerItems: 'totalServerItems'
$scope.gridOptions = {
data: 'myData',
enableRowSelection: false,
enablePaging: true,
totalServerItems: 'totalServerItems',
showFooter: true,
pagingOptions: $scope.pagingOptions
};

Related

How can I display a grid repeater using ui-grid?

I have data of messages including {id,message,date}.
I would like to display a grid for each Date with data{message} in AngularJs using ui-grid
I was thinking of something like this:
<div ng-repeat="(item in data | groupBy: 'Date'">
<div>{{ item.Date }}</div>
<div id="grid1" ui-grid="gridOptions(item.Date) " class="grid"></div>
</div>
but it's not working!
$scope.gridOptions = function (date) {
return {
enableSorting: true,
enableFiltering: true,
data: 'data',
columnDefs: $scope.filterGrid(date),
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
};
};
$scope.filterGrid= function (date){
return [
{ field: 'id', enableFiltering: False},
{
field: 'Date', enableFiltering: false, filter: {
noTerm: true,
condition: function (searchTerm, cellValue) {
return cellValue.match(date);
}
}
},
{ field: 'Message' , enableFiltering: false },
]
}
First of all - ui-grid has a grouping feature, but this is still in beta.
You can try to use this example to group the data and build grids accordingly.
var dataSource = {};
$scope.gridOptions = {};
var generalGridOptions = {
enableSorting: true,
columnDefs: [
{ name: 'prop1' },
{ name: 'prop2' },
],
data: null
};
// group the data
for(var i = 0; i < data.length; i++){
if(!dataSource[data[i].month]){
dataSource[data[i].month] = [];
}
var obj = {};
for(var prop in data[i]){
if(prop!='month'){
obj[prop] = data[i][prop];
}
}
dataSource[data[i].month].push(obj);
}
// build the grid options
for (var item in dataSource) {
$scope.gridOptions[item] = angular.copy(generalGridOptions);
$scope.gridOptions[item].data = dataSource[item];
}
ui-grid attribute recieves a gridOptions object containing several parameters. Two of them are:
columnDefs - defining the columns and their data-binding.
data - the message objects in your case.
Look at the the documentation for further study: http://ui-grid.info/docs/#/tutorial
Code Example
template:
<div ng-repeat='item in items track by item.id' ui-grid='getItemGridOptions($index)'></div>
Passing the item index to the controller allows you to process your data. Then you can return an object containing the data and columnDefs properties. Like this:
private getItemGridOptions(index): IGridOptions {
//get the data you need for your items array using the index...
// then return the gridOptions object (I put random values)
return {
columnDefs: this.columns,
rowHeight: 24,
rowTemplate: rowtpl,
enableHorizontalScrollbar: this.uiGridConstants.scrollbars.NEVER,
enableColumnMenus: false,
enableRowSelection: true,
enableRowHeaderSelection: false,
enableFiltering: true,
modifierKeysToMultiSelect: true,
multiSelect: true,
data: null,
};
}

Uib-tab containing UI-GRID

I have a uib-tabset with four tabs:
<uib-tabset active="activeForm">
<uib-tab index="0" heading="One"><ng-include src="'one.html'"></ng-include></uib-tab>
<uib-tab index="1" heading="Two"><ng-include src="'two.html'"></ng-include></uib-tab>
<uib-tab index="2" heading="Three"><ng-include src="'three.html'"></ng-include></uib-tab>
<uib-tab index="3" heading="Four"><ng-include src="'four.html'"></ng-include></uib-tab>
</uib-tabset>
it has this controller:
$scope.tabs = [
{ title: 'One', route: 'one' },
{ title: 'Two', route: 'two' },
{ title: 'Three', route: 'three' },
{ title: 'Four', route: 'four' }
];
$scope.go = function(route) {
$state.go(route);
};
Each tab has the same structure. They all contain a UI-GRID, and differ only in the data they contain:
$scope.dataList = [];
$scope.selectedFile = null;
$scope.gridOpts = {
enableFiltering: true,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
noUnselect: false,
columnDefs: [..my fields..],
onRegisterApi: function(gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope,function(row){
$scope.selectedFile = row.entity;
// Switcher selezione/deselezione
if ($scope.atLeastOneIsSelected === false){
$scope.atLeastOneIsSelected = true;
} else {
$scope.atLeastOneIsSelected = false;
}
});
gridApi.selection.on.rowSelectionChangedBatch($scope,function(rows){
$scope.atLeastOneIsSelected = false;
});
$scope.getFirstData();
}
};
$scope.addGridData = function(datalist) {
$scope.dataList = $scope.dataList.concat(datalist);
$scope.gridOpts.data = $scope.dataList;
};
$scope.getMoreDataAsync = function(firstData) {
if ($scope.cancelPromise) {
$scope.cancelPromise.resolve();
}
$scope.cancelPromise = $q.defer();
TypeOneFileSrv.fileList.get(
{
userId: $scope.$stateParams.userId
}, function(data) {
if (data) {
$scope.addGridData(data);
blockUI.stop();
}
}, function(error) {
if (error) {
toaster.pop('error', 'Error', error);
}
}
);
};
$scope.getFirstData = function() {
blockUI.start('Loading 'ONE' tab...');
$scope.selectedFile = null;
$scope.dataList.length = 0;
$scope.getMoreDataAsync(true);
};
At least, here is the Service which calls the server. As for the Controller, even the Services of the four tab are the same and differ only in the url:
angular.module('app').factory('TypeOneFileSrv', ['$resource', function($resource) {
var typeOne = {
fileList: $resource('url_for_the_first_tab/:userId/?', {
userId: '#userId'
}, {
get: {
method: 'GET',
isArray: true
}
})
};
return typeOne;
}]);
My problem is that, even if I added the blockUI in each tab, when I open the page containing the uib-tabset it seems sometimes it does not load all the data. Because for example I see the first two tabs that have the table populated, but the other two are not populated. Or the first two and the last, and so on.
Please try as shown below.
app.js
Inject ui.grid.autoResize module as shown below.
var appModule = angular.module("app", [
'ui.grid.autoResize'
]);
Html
Use ui-grid-auto-resize directive as shown below.
<div class="grid" ui-grid="vm.yourGridOptions" ui-grid-auto-resize></div>
css
Give a width for your grid as shown below.
.grid {
width: 980px !important;
}

Angular ui-grid: how to refresh 2nd grid based on row selected value of 1st grid

There are 2 grids grid1 grid2.
My requirement is: When I select a row in grid1, grid2 should get refreshed. I am able to fetch the modified data based on the row selection from my service, but I am not able to get it to display on my grid2.
I tried
$scope.grid2 = function () { $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL);
$scope.gridApi.core.refresh();}
Both the above are in the RowSelectionChanged event inside the grid1 onRegisterAPI
$scope.gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
$timeout(function () {
$scope.gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.value = row.entity.MVE_VEID;
console.log($scope.value);
$scope.contractvalues = contracts.query({ id: $scope.value });
console.log($scope.contractvalues);
$scope.gridoptions2 = function () { $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL); $scope.gridApi.core.refresh(); }
$scope.refresh = true;
});
How can I refresh the data in grid2?
Current Code:
contrcontroller.js
<pre>
angular
.module('VendorApp')
.controller('ang_contcontroller', ang_contcontroller);
ang_contcontroller.$inject = ['$scope','contracts'];
function ang_contcontroller($scope, contracts) {
$scope.contractvalues = contracts.query({ id: $scope.value });
$scope.gridoptions2 = {
enableRowHeaderSelection: false,
multiSelect: false,
enableRowSelection: true,
enableSelectAll: true,
enableSorting: true,
enableFiltering: true,
enablePagination: true,
enablePaginationControls: true,
paginationCurrentPage: 1,
paginationPageSize: 100,
maxVisibleColumnCount: 200,
columnDefs: [
{ name: 'CONTRACTID', field: 'MCO_COID' },
{ name: 'NAME', field: 'CO_DESC' },
{ name: 'VENDORID', field: 'MCO_VEID' }
],
data: $scope.contractvalues
};
$scope.gridoptions2.onRegisterApi = function (gridApi) {
$scope.gridApi2 = gridApi;
}
}
vencontroller.js
$scope.gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
$timeout(function () {
$scope.gridApi.selection.on.rowSelectionChanged($scope, function (row) {
$scope.value = row.entity.MVE_VEID;
console.log($scope.value);
$scope.contractvalues = contracts.query({ id: $scope.value });
console.log($scope.contractvalues);
$scope.gridoptions2 = {};
$scope.gridoptions2.data = $scope.contractvalues;
//$scope.gridApi2.refresh();
$scope.grid2 = function () {
$scope.gridApi2.core.notifyDataChange(uiGridConstants.dataChange.ALL);
$scope.gridApi2.core.refresh();
};
//$scope.grid2 = function () {
// $scope.gridoptions2 = angular.copy($scope.gridoptions2);
// $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL= function () { $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL); },$scope.gridApi.core.refresh(); );
// }
//$scope.refresh();
//$scope.gridoptions2 = function () { $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ALL); }
});
});
<code>
If I understand correctly you need to update data for grid2
you wrote that you able to get modified base data say "newData".
Assign this new data to "$scope.gridoptions2.data"
$scope.gridoptions2.data = newData;

I want to read a array value inside factory in angularjs

I am trying to read value in array in factory but I am unable to do so. I am using ng-grid and when I click on one row I get selecteditems list which I pass in another controller where I call a factory service in which I pass that as a parameter but that parameter in the factory stays as array and when I read it using index it shows blank.
My code is as below -
myNgApp.controller('MyGrid', ['$scope', function ($scope) {
$scope.mySelections = [];
$scope.mySelItems = [];
$scope.myData = [{ Reference: 12, Customer: "fff", Title: "sd", Task: "Enter Details", Received: "Today", Due: "01/09/2014" },
{ Reference: 7899, Customer: "eee", Title: "dsd", Task: "Enter Details", Received: "Yesterday", Due: "05/09/2014" }];
$scope.gridOptions = {
data: 'myData',
checkboxHeaderTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
selectWithCheckboxOnly: true,
showSelectionCheckbox: true,
selectedItems: $scope.mySelections,
multiSelect: true,
columnDefs: [{ field: 'Reference', displayName: 'Reference', width: '*' }, { field: 'Customer', displayName: 'Customer', width: '**' }, { field: 'Title', displayName: 'Title', width: '***' }, { field: 'Task', displayName: 'Task', width: '***' }, { field: 'Received', displayName: 'Received', width: '**' }, { field: 'Due', displayName: 'Due', width: '**' }],
showGroupPanel: true,
enableCellSelection: false,
enableRowSelection: true,
enableCellEditOnFocus: false,
enablePinning: true,
showColumnMenu: true,
showFilter: true,
enableColumnResize: true,
enableColumnReordering: true,
maintainColumnRatios: true,
afterSelectionChange: function () {
angular.forEach($scope.mySelections, function (item) {
if ($scope.mySelItems.length == 0) {
$scope.mySelItems.push(item.Title)
}
else {
$scope.mySelItems[0] = item.Title
}
});
}
};
}]);
myNgApp.factory('myPreviewDataService', function () {
return function (x) {
var arr = [x, "Apple", "Banana", "Orange"];
return arr
};
});
myNgApp.factory('myPreviewTplService', function () {
return function () {
return '<div><div class="ngPreviewItems" ng-repeat="item in items">{{item}}</div></div>';
};
});
myNgApp.directive('showPreview', function ($compile) {
return {
scope: true,
link: function (scope, element, attrs) {
var el;
attrs.$observe('template', function (tpl) {
if (angular.isDefined(tpl)) {
// compile the provided template against the current scope
el = $compile(tpl)(scope);
// stupid way of emptying the element
element.html("");
// add the template content
element.append(el);
}
});
}
};
});
myNgApp.controller('myPreviewController', function ($scope, myPreviewDataService, myPreviewTplService) {
//$scope.showContent = function () {
$scope.items = myPreviewDataService($scope.mySelItems);
$scope.template = myPreviewTplService();
//};
});
here $scope.mySelItems is from ng grid controller that gets updated when we select a checkbox.
What I get is an array but I am unable to read its content, when I display the array as it is it gets displayed like ["test"] but when I try to read it x[0] in myPreviewDataService factory or by $scope.mySelItems[0] in myPreviewController then I get blank. I am not able to figure out why this is happening
I was able to solve it. In myPreviewDataService factory I changed the array elements from string to array
var arr = [x, "Apple", "Banana", "Orange"];
changed to
var arr = [x, ["Apple"], ["Banana"], ["Orange"]];
and in myPreviewTplService factory I changed {{item}} to {{item[0]}}
it worked.
P.S I think we can also use ng switch based on condition in myPreviewTplService factory based on the type of item, I tried to do it but I was not able to do so and worked with my earlier solution.

How to do client-side pagination with ngGrid?

If you set the enablePaging options of an ng-grid to true, you enable server-side pagination.
What about client-side one? I could not find any hint on this in the documentation, but I can not imagine that ng-grid does not support client-side paging as well.
Any hint?
I think the example given on the angular page (http://angular-ui.github.io/ng-grid/) actually shows an example of client-side paging. If you look at the data load that is being called by the sample script (http://angular-ui.github.io/ng-grid/jsonFiles/largeLoad.json), you'll see that its not actually doing any server-side paging... it's coming down as one big file.
It might help you!!
The AngularJs code-sample
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: ""
};
$scope.pagingOptions = {
pageSizes: [25, 50, 100],
pageSize: 25,
totalServerItems: 0,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize) {
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.pagingOptions.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function(pageSize, page) {
setTimeout(function() {
$http.get('json').success(function(largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
}, 100);
};
$scope.$watch('pagingOptions', function() {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}, true);
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
pagingOptions: $scope.pagingOptions,
showFooter: true
};
$scope.gridOptions.columnDefs = 'gridColumnDefs';
// city loc pop state
$scope.gridColumnDefs = [{
field: "city"
},
{
field: "state"
}, {
field: "pop"
}, {
field: "loc"
}
];
});
The HTML code-sample
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</div>

Resources