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);
Related
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; });
};
I am trying to integrate highcharts sparkline with angular ui-grid directive but unable to plot the sparkline. When we try to dynamically plot the sparklines using ui-grid nothing gets plotted. I have made necessary changes to the sparkline code as well yet unable to find what is the issue. We need age column to have highcharts sparkline. Any pointer will be of great help.
$scope.gridOptions = {
enableFiltering: false,
enableSorting: true,
}
$scope.gridOptions.columnDefs = [{
name: 'id'
}, {
name: 'name'
}, {
name: 'age',
cellTemplate: '<div id="table-sparkline" data-sparkline="71, 78, 39, 66"></div>'
}, {
name: 'address.city'
}];
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.success(function(data) {
$scope.gridOptions.data = data;
console.log(JSON.stringify(data));
/**
* Create a constructor for sparklines that takes some sensible defaults and merges in the individual
* chart options. This function is also available from the jQuery plugin as $(element).highcharts('SparkLine').
*/
Highcharts.SparkLine = function(a, b, c) {
var hasRenderToArg = typeof a === 'string' || a.nodeName,
options = arguments[hasRenderToArg ? 1 : 0],
defaultOptions = {
chart: {
renderTo: (options.chart && options.chart.renderTo) || this,
backgroundColor: null,
borderWidth: 0,
type: 'area',
margin: [2, 0, 2, 0],
width: 120,
height: 20,
style: {
overflow: 'visible'
},
// small optimalization, saves 1-2 ms each sparkline
skipClone: true
},
title: {
text: ''
},
credits: {
enabled: false
},
xAxis: {
labels: {
enabled: false
},
title: {
text: null
},
startOnTick: false,
endOnTick: false,
tickPositions: []
},
yAxis: {
endOnTick: false,
startOnTick: false,
labels: {
enabled: false
},
title: {
text: null
},
tickPositions: [0]
},
legend: {
enabled: false
},
tooltip: {
backgroundColor: null,
borderWidth: 0,
shadow: false,
useHTML: true,
hideDelay: 0,
shared: true,
padding: 0,
positioner: function(w, h, point) {
return {
x: point.plotX - w / 2,
y: point.plotY - h
};
}
},
plotOptions: {
series: {
animation: false,
lineWidth: 1,
shadow: false,
states: {
hover: {
lineWidth: 1
}
},
marker: {
radius: 1,
states: {
hover: {
radius: 2
}
}
},
fillOpacity: 0.25
},
column: {
negativeColor: '#910000',
borderColor: 'silver'
}
}
};
options = Highcharts.merge(defaultOptions, options);
return hasRenderToArg ?
new Highcharts.Chart(a, options, c) :
new Highcharts.Chart(options, b);
};
var start = +new Date(),
$tds = $('div[data-sparkline]'),
fullLen = $tds.length,
n = 0;
// Creating 153 sparkline charts is quite fast in modern browsers, but IE8 and mobile
// can take some seconds, so we split the input into chunks and apply them in timeouts
// in order avoid locking up the browser process and allow interaction.
function doChunk() {
var time = +new Date(),
i,
len = $tds.length,
$td,
stringdata,
arr,
data,
chart;
for (i = 0; i < len; i += 1) {
$td = $($tds[i]);
stringdata = $td.data('sparkline');
arr = stringdata.split('; ');
data = $.map(arr[0].split(', '), parseFloat);
chart = {};
if (arr[1]) {
chart.type = arr[1];
}
$td.highcharts('SparkLine', {
series: [{
data: data,
pointStart: 1
}],
tooltip: {
headerFormat: '<span style="font-size: 10px">' + $td.parent().find('div').html() + ', Q{point.x}:</span><br/>',
pointFormat: '<b>{point.y}.000</b> USD'
},
chart: chart
});
n += 1;
// If the process takes too much time, run a timeout to allow interaction with the browser
if (new Date() - time > 500) {
$tds.splice(0, i + 1);
setTimeout(doChunk, 0);
break;
}
}
}
doChunk();
Plunker
I am following this tutorial: http://ui-grid.info/docs/#/tutorial/206_exporting_data
I am using angularjs ui grid. But when I export grid to pdf, UI is not look good.
Problem: Page number and Pdf title is too left, but grid is too right
I tried to search the solution online, but no luck. This is my grid options setting:
gridOptions = {
showGridFooter: true,
showFooter: false,
enableSorting: true,
multiSelect: false,
enableFiltering: true,
enableRowSelection: true,
enableSelectAll: false,
enableRowHeaderSelection: false,
enableGridMenu: true,
noUnselect: true,
onRegisterApi: function (_gridApi) {
this.gridApi = _gridApi;
},
data: [],
exporterCsvFilename: 'Report.csv',
exporterPdfDefaultStyle: {fontSize: 9},
exporterPdfTableStyle: {margin: [30, 30, 30, 30]},
exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'},
exporterPdfHeader: { text: "Foo", 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;
},
exporterPdfOrientation: 'portrait',
exporterPdfPageSize: 'LETTER',
exporterPdfMaxGridWidth: 500,
exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
};
You need to add a margin to the header and footer styles, in your gridOptions, try with something like this:
$scope.gridOptions = {
...
exporterPdfTableStyle: {margin: [20, 20, 20, 20]},
...
exporterPdfCustomFormatter: function ( docDefinition ) {
docDefinition.styles.headerStyle = { margin: [30, 30, 30, 30],fontSize: 22, bold: true };
docDefinition.styles.footerStyle = { margin: [30, 30, 30, 30],fontSize: 10, bold: true };
return docDefinition;
},
...
I wonder how I should go about having better animations when adding points to a area plot. In regular highcharts this is done pretty smooth but using highcharts-ng it rerenders a huge chunk of the chart.
I have two fiddels that shows the issue. Maby there is a simple way to solve this ?
Highcharts-ng
http://jsfiddle.net/Cp73s/3399/
var myapp = angular.module('myapp', ["highcharts-ng"]);
myapp.controller('myctrl', function ($scope) {
$scope.addPoints = function () {
var seriesArray = $scope.highchartsNG.series
var rndIdx = Math.floor(Math.random() *10+7);
$scope.highchartsNG.series[0].data.push(rndIdx);
};
$scope.highchartsNG = {
options: {
chart: {
type: 'area'
},
plotOptions: {
area: {
fillOpacity: 0.15,
dataLabels: {
allowOverlap: true,
enabled: true,
padding: 0,
style: {
fontSize: '25px'
}
},
enableMouseTracking: true
}
},
},
series: [{
data: [10, 15, 12, 8, 7]
}]
}
});
Regular-highcharts
http://jsfiddle.net/m8Lavyrc/3/
$(function () {
$('#container').highcharts({
chart: {
type: 'area'
},
plotOptions: {
area: {
fillOpacity: 0.15,
dataLabels: {
allowOverlap: true,
enabled: true,
padding: 0,
style: {
fontSize: '25px'
}
},
enableMouseTracking: true
}
},
series: [{
data: [10, 15, 12, 8, 7]
}]
});
// the button action
var i = 0;
$('#button').click(function () {
var chart = $('#container').highcharts();
chart.series[0].addPoint(Math.floor(Math.random() *10+7));
});
});
Tnx
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();
});
}
});