angularjs UI grid - display columns dynamically - angularjs

I have a stored procedure that returns the first 4 columns(LineNumber, AttributeName, Source, MIC) along with the other columns that are dynamic. Dynamic meaning it can range from 150 to 1. Here in the screenshot example I have columns 40 to 29.
I was able to bring the data from back end to the controller and I was also able to display the the first 4 columns fine. But I need help to loop through the rest of the columns (For example in the screenshot the columns from 40 to 29. These columns are dynamic). THanks in advance.
$scope.gridOptionsVatMakeRpt = {
enableFullRowSelection: true,
enableRowHeaderSelection: false,
paginationPageSizes: [20, 40, 60],
paginationPageSize: 40,
rowHeight: 53,
enableFiltering: true,
enableCellEdit: false,
enableGridMenu: false,
rowTemplate:
'<div ng-class="{ \'grey\':grid.appScope.rowFormatter( row ) }">' +
' <div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader }" ui-grid-cell></div>' +
'</div>',
columnDefs: [
{
field: 'LineNumber', grouping: {
groupPriority: 0
},
width: '10%', visible: true
}
, {
field: 'AttributeName', grouping: {
groupPriority: 1
},
width: '10%', visible: true
}
, { field: 'Source', width: '10%', visible: true }
, { field: 'MIC', width: '10%', visible: true }
}
$scope.loadgridVatMakeRpt = function () {
$scope.loading = true;
console.log('loading grid');
LRWService.getVatMakeRpt('1', '1221209', '100000028', '2020-05-08', '2020-05-08').success(function (data) {
if (data === null || data.VatMakeRptList === null || data.VatMakeRptList.length === 0) {
$scope.error = true;
$scope.errorDescription = "No data found for selected criteria.";
} else {
$scope.gridOptionsVatMakeRpt.paginationPageSizes.push(
data.VatMakeRptList.length
);
var VatMakeRptList = data.VatMakeRptList;
$scope.gridOptionsVatMakeRpt.data = VatMakeRptList;
$scope.renderfields();
console.log(VatMakeRptList);
$scope.error = false;
}
}).finally(function () { $scope.loading = false; });
};

You can create columns dynamically inside the function loadgridVatMakeRpt eg. you as per your information you can iterate through the number of columns, post fixed set of columns and add one dynamic column for each iteration till the last entry.
Also find below documentation link for further dynamic behaviour if needed
Just note that, column should have field to which it should map to.
$scope.gridOptionsVatMakeRpt = {
enableFullRowSelection: true,
enableRowHeaderSelection: false,
paginationPageSizes: [20, 40, 60],
paginationPageSize: 40,
rowHeight: 53,
enableFiltering: true,
enableCellEdit: false,
enableGridMenu: false,
rowTemplate:
'<div ng-class="{ \'grey\':grid.appScope.rowFormatter( row ) }">' +
' <div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader }" ui-grid-cell></div>' +
'</div>',
columnDefs: [
{
field: 'LineNumber', grouping: {
groupPriority: 0
},
width: '10%', visible: true
}
, {
field: 'AttributeName', grouping: {
groupPriority: 1
},
width: '10%', visible: true
}
, { field: 'Source', width: '10%', visible: true }
, { field: 'MIC', width: '10%', visible: true }
}
$scope.loadgridVatMakeRpt = function () {
$scope.loading = true;
console.log('loading grid');
LRWService.getVatMakeRpt('1', '1221209', '100000028', '2020-05-08', '2020-05-08').success(function (data) {
if (data === null || data.VatMakeRptList === null || data.VatMakeRptList.length === 0) {
$scope.error = true;
$scope.errorDescription = "No data found for selected criteria.";
} else {
$scope.gridOptionsVatMakeRpt.paginationPageSizes.push(
data.VatMakeRptList.length
);
var VatMakeRptList = data.VatMakeRptList;
var keysArray = [];
keysArray = Object.keys(VatMakeRptList[0]);
for (var i = 4;i<keysArray.length;i++) {
$scope.gridOptionsVatMakeRpt.columnDefs.push({ name: keysArray[i], field: keysArray[i],width: <dynamic/fixed width>, visible: true});
}
$scope.gridOptionsVatMakeRpt.data = VatMakeRptList;
$scope.renderfields();
console.log(VatMakeRptList);
$scope.error = false;
}
}).finally(function () { $scope.loading = false; });
};

Related

Angularjs Dynamic Angular UI Grid Columns

Angularjs ui-grid how to column define dynamically. In my code, I defined columnDefs is null and set columns after button click and set data to grid. But columns not rendering on browser. how to render or reload grid with this situation. Any solution will be helpful to my problem.
I hope this makes sense. any suggestions are welcome.
// I defined grid first
$scope.gridOptions = {
enableColumnResizing: true,
enableSorting: true,
enableFiltering: true,
showGridFooter: true,
paginationPageSize: 50,
paginationPageSizes: [50, 100, 150, 200, 250],
enableHorizontalScrollbar: 1,
columnDefs: [],
exporterPdfDefaultStyle: { fontSize: 9 },
exporterPdfTableStyle: { margin: [30, 30, 30, 30] },
exporterPdfTableHeaderStyle: { fontSize: 10, bold: true, italics: true, color: 'red' },
exporterPdfHeader: { text: "Tüm Liste", style: 'headerStyle' },
exporterPdfFooter: function (currentPage, pageCount) {
return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
},
exporterPdfCustomFormatter: function (docDefinition) {
docDefinition.styles.headerStyle = { fontSize: 22, bold: true };
docDefinition.styles.footerStyle = { fontSize: 10, bold: true };
return docDefinition;
},
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
}
//and ng-click set column grid and set data to grid
//but grid is not rendering
$scope.getTable = function () {
$scope.columns = {'name','surname','id'};
$scope.gridOptions.columnDefs = new Array();
$scope.columns.forEach(function (item) {
$scope.gridOptions.columnDefs.push({
name: item,
field: item,
headerCellClass: 'tablesorter-header-inner'
})
});
$http({
method: 'POST',
url: '/report/getData',
data: {
vars: $scope.vars
}
}).success(function (data, status) {
switch (status) {
case 200:
$scope.gridOptions.data = $.parseJSON(data);
break;
case 204:
location.replace('/Error/Error?errorMessage=Error!&errorCode=' + status);
break;
default:
console.log("default");
// location.replace('/Error/Error?errorMessage=Message!&errorCode=' + status);
break;
}
}).error(function (data, status) {
location.replace('/Error/Error?errorMessage=problem!&errorCode=' + status);
}); }
This is about ng-show ui-grid not rendering after ng-show true beacuse of
First set ng-show visible
And set data
Last step run below code:
$scope.gridApi.core.handleWindowResize();
$scope.gridApi.core.refresh();
$scope.gridApi.core.refreshRows();
$scope.gridApi.grid.refresh();
$scope.gridApi.grid.refreshRows();
$scope.gridApi.grid.updateCanvasHeight();
$scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
$scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);

Need to get the grouping values in ui-grid

I'm using ui-grid and I'm grouping the data, I will need to get the group headers and the counters. How can I get those values?
This is an example of the grid
$scope.gridOptions = {
enableFiltering: false,
enableColumnResize: true,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
columnDefs: [
{ field: 'month',enableHiding: false, grouping: { groupPriority: 0 }, sort: { priority: 0, direction: 'desc' }},
{ field: 'facility',enableHiding: false,grouping: { groupPriority: 1 }, sort: { priority: 1, direction: 'asc' }},
...
{ field: 'categorymanager',enableHiding: false, displayName:'CM', grouping:{ groupPriority: 2 }, sort: { priority: 2, direction: 'asc' }},
]
};
You can get the values by writing a custom cellTemplate for the colDef. For example if you can define your template as:
let monthTemplate = '<div><div ng-if="!col.grouping || col.grouping.groupPriority === undefined || col.grouping.groupPriority === null || ' +
'( row.groupHeader && col.grouping.groupPriority === row.treeLevel )" class="ui-grid-cell-contents" ' +
'title="TOOLTIP">{{grid.appScope.getValue(COL_FIELD, row.treeNode.children )}}</div></div>';
Then define your method as:
$scope.getValue = function(item, treeRowEntity){
//item will hold month value
//iterate over treerowentity array and get values
//for example, if column required was facility
treeRowEntity[0].row.entity.facility
};

ui.grid data displayed is the same on each row

I am using a cell template for each row in my data grid. If I qualify the json object with an index then the value appears correctly but of course it is the same for each row. If I remove the index, then all rows are displayed with the same value but the value is an array.
---the js file
(function() {
angular.module('xxxSurvey').controller('EditxxxSurveyController', EditxxxSurveyController);
EditxxxSurveyController.$inject = ['$scope', 'UserFacilityListService', 'xxxSurveyService'];
function EditxxxSurveyController($scope, UserFacilityListService, xxxSurveyService) {
$scope.dataLoaded = false;
$scope.currentPage = 1;
$scope.pageSize = 10;
// test ui-grid setup
$scope.dataLoaded = true;
$scope.editWorksheetOptions = {
enableSorting: true,
columnDefs: [
{
name: 'all', field: 'MasterPatientId', width: 40,
enableSorting: false, enableColumnMenu: false, pinnedLeft: true,
//cellTemplate: '<input type="checkbox" id="i{{COL_FIELD}}">'
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.worksheetInfo.MasterProviderId}}</div>'
},
{name: 'residentName', field: 'residentName', minWidth: 90, pinnedLeft: true,
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.editWorksheetOptions.data[0].ResidentNameLast}}</div>'
},
{name: 'residentRoom', field: 'residentRoom', width: 90, pinnedLeft: true},
{name: 'status', field: 'status', width: 90},
],
data: []
};
$scope.$on('FacilitySelected', function() {
if (UserFacilityListService.getSelectedFacility()) {
$scope.selectedFacility = UserFacilityListService.getSelectedFacility();
}
var promise = xxxSurveyService.getCurrentWorksheet($scope.selectedFacility.MasterProviderId);
promise.then(
function(payload) {
if (payload !== null) {
$scope.worksheetInfo = payload.worksheetInfo;
$scope.editWorksheetOptions.data = payload.residentData;
}
}
);
});
}
})();
--the json data
[{"AssessmentId":1,"WorksheetId":4,"MasterPatientId":1,"ResidentNameFirst":"xx","ResidentNameMiddle":"^","ResidentNameLast":"zzz","ResidentNameSuffix":"^"},
{"AssessmentId":2,"WorksheetId":2,"MasterPatientId":2,"ResidentNameFirst":null,"ResidentNameMiddle":null,"ResidentNameLast":null,"ResidentNameSuffix":null}]
--the html div id="editWorksheetGrid" ui-grid="editWorksheetOptions" class="grid" ui-grid-pinning>
i had same issue. For me it was rowIdentity problem.
Define following in your controller.
$scope.gridOptions.rowIdentity = function (row) {
return row.ID; //make sure ID is unique.
};
This fixed my problem.
Thanks

ui-grid columns collapsing when width:"**" is specified

I am working on a project where I have used UI-Grid to show list of users. I have specified width:"**" for each column in column definition. In output, all the columns are collapsed in left side. When I resizes browser window or inspects element, then width is auto adjusted quickly. But for first time, all columns are displayed collapsed. Here is my code:
$scope.columns = [
{ field: 'name', name:'Name', width: "**", cellTooltip : false,enablePinning:true,
cellTemplate:'<div class="ui-grid-cell-contents">'+
'<a ng-href="#/account/profile?id={$ grid.appScope.getUserID(grid, row) $}"> {$ grid.appScope.getUserRow(grid, row,"uname") $} </a>'+
'</div>'
},
{ field: 'email', name:'Email', width: "**", cellTooltip : false,enablePinning:true },
{ field: 'role', name:'Role', width: "**", enableSorting: true,
cellTemplate:'<div class="ui-grid-cell-contents"> '+
'{$ grid.appScope.getUserRow(grid, row,"role") $}'+
'<a ng-click="grid.appScope.assignRole({$ grid.appScope.getUserID(grid, row) $})"> add </a>'+
'</div>'
},
{ field: 'isInvited', name:'Invitation status', width: "**", cellTooltip : false,enablePinning:true },
];
$scope.gridOptions = {
showGridFooter: true,
enableSorting: true,
enableGridMenu: true,
enableSelectAll: true,
enableFiltering: true,
enableHorizontalScrollbar : 1,
paginationPageSizes: [10,25, 50, 100],
useExternalPagination: true,
columnDefs: $scope.columns,
enableGridMenu: true,
enableSelectAll: true,
exporterCsvFilename: 'myFile.csv',
exporterPdfDefaultStyle: {fontSize: 9},
exporterPdfTableStyle: {margin: [10, 10, 10, 10]},
exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'},
exporterPdfHeader: { text: "My Header", style: 'headerStyle' },
exporterPdfFooter: function ( currentPage, pageCount ) {
return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
},
exporterPdfCustomFormatter: function ( docDefinition ) {
docDefinition.styles.headerStyle = { fontSize: 22, bold: true };
docDefinition.styles.footerStyle = { fontSize: 10, bold: true };
return docDefinition;
},
exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
$scope.gridApi.core.on.sortChanged( $scope, function( grid, sort ) {
$scope.gridApi.core.notifyDataChange( uiGridConstants.dataChange.COLUMN );
});
$scope.gridApi.pagination.on.paginationChanged( $scope, function( currentPage, pageSize){
$scope.getAppDetails(currentPage, pageSize);
});
}
};
I just noticed if you resize the window it renders the grid properly. So a quick and dirty work around and not really intended as a solution, is watching for when the grid becomes visible and calling grid.handleWindowResize() on the gridApi.
Also a $timeout to ensure the rendering is performed after the tab has fully displayed. Here's how I watch:
$scope.test = {isActive: false};
$scope.$watch('test.isActive', function (active, oldActive) {
if(active) {
$timeout(function () {
$scope.gridApi.grid.handleWindowResize();
});
}
});

Angularjs ui grid with grouping column sequence is getting jumbled up

I am using AngularJs ui grid with grouping. The table is displaying fine but the problem I am facing is that the months sequence in the table is getting jumbled up. Please find my Plunker. In the table the Months are appearing in the jumbled up sequence 11-14, 05-15, 04-15, ... 02-15. But I need it in the sequence of 11-14, 12-14, 01-15, 02-15, 03-15, 04-15, 05-15. Can any one help me to fix it?
I am using the following for to get colDefs:
$scope.getColumnDefsForUiGrid = function(columns) {
var colDef = [];
colDef.push({
name: 'mode',
grouping: {
groupPriority: 0
},
displayName: 'Type',
enableCellEdit: false,
width: '5%'
});
colDef.push({
name: 'service',
displayName: 'Catg',
enableCellEdit: false,
width: '5%'
});
angular.forEach(columns, function(value, key) {
colDef.push({
name: key,
displayName: value,
enableCellEdit: true,
aggregationType: uiGridConstants.aggregationTypes.sum,
width: '5%'
})
});
return colDef;
};
Here is a workaround for your problem
you can see it working on this plunker
$scope.getColumnDefsForUiGrid = function( columns ){
var colDef = [];
colDef.push({name: 'mode', grouping: { groupPriority: 0 }, displayName: 'Type', enableCellEdit: false, width: '5%'});
colDef.push({name: 'service', displayName: 'Catg', enableCellEdit: false, width: '5%'});
//I split the monthColumns into an other array
var monthCol = [];
angular.forEach(columns, function( value, key ) {
monthCol.push({name: key, displayName: value, enableCellEdit: true, aggregationType : uiGridConstants.aggregationTypes.sum, width: '5%' })
});
//I sort this array using a custom function
monthCol.sort(function(a,b){
a = a.displayName.split("-");
b = b.displayName.split("-");
if(a[1] < b[1]){
return -1;
}else if (a[1] > b[1]){
return 1;
}else {
if(a[0] < b[0]){
return -1;
}else{
return 1;
}
}
});
//I concat the two array
return colDef.concat(monthCol);
};

Resources