I use refreshCells to update a specific cell style after clicking on it. However, this does not work, and when I set refreshCells({ force: true }), the whole column updates new style that I don't want. Any suggestions please?
vm.gridOptions = {
columnDefs: vm.columnDefs,
rowData: vm.rows,
angularCompileRows: true,
defaultColDef: {
sortable: true,
resizable: true,
},
onCellClicked: onCellClicked,
onGridReady: function (params) {
}
}
function onCellClicked(params) {
const focusedCell = params.api.getFocusedCell();
focusedCell.column.colDef.cellStyle = { 'background-color': '#b7e4ff' };
params.api.refreshCells({
force: true // this updates the whole column, not only the clicked cell
});
}
I solved this by setting the specific rowNodes and columns.
function onCellClicked(params) {
const focusedCell = params.api.getFocusedCell();
const rowNode = params.api.getRowNode(focusedCell.rowIndex);
const column = focusedCell.column.colDef.field;
focusedCell.column.colDef.cellStyle = { 'background-color': '#b7e4ff' };
params.api.refreshCells({
force: true,
columns: [column],
rowNodes: [rowNode]
});
}
Related
Background
Had upgraded the typescript to 2.6.2 from 2.3.4. Ag grid have compile issue so its upgraded to 15.0.0. After upgrade existing pagination code for ag-grid is not working.
Previous Configuration - ag-grid and pagination works fine
on click search button from form searchCategory() method will be called and load the grid
package.json
"ag-grid": "^8.1.0",
"ag-grid-angular": "^8.1.0",
.....
"typescript": "^2.3.4"
temp.ts
gridOptions = <GridOptions>{
context: {},
paginationPageSize: AppUtils.IR_PAGINATION_SIZE,
/* rowModelType: 'pagination',*/
rowModelType: 'infinite',
pagination: true,
enableServerSideSorting: true,
suppressDragLeaveHidesColumns: true,
onGridSizeChanged: () => {
this.gridOptions.api.sizeColumnsToFit();
},
getRowHeight: () => {
return 32;
},
components: {
getTypeDesc : function(params: any) {
var eDiv = document.createElement('div');
let desc = params.context.typeMaster.filter(function (item: any) {
if (params.data.typeCode === item.typeCode) {
return item.typeDescription;
}
});
eDiv.innerHTML = '<span>' + desc[0].typeDescription + '</span>';
return eDiv;
},
};
typeMaster: TypeMasterModel[];
categoryMaster: CategoryModel[];
category: CategoryModel = new CategoryModel();
severityMaster: SeverityMasterModel[];
selectedRowsValue: number[];
columnDefs: any[] = [
{ headerName: '', field: 'catCode', hide: true },
{ headerName: 'Category', field: 'catDesc', width: 550 },
{ headerName: 'Type', field: 'typeCode', cellRenderer:'getTypeDesc' }
{ headerName: 'PatientID', field: 'patIdMandYn' },
{ headerName: 'EquipmentID', field: 'equipIdMandYn' },
{ headerName: 'WorkorderId', field: 'workOrderMandYn' }
];
action: string = '';
searchCategory() {
let self = this;
let dataSource = {
rowCount: null, //
getRows: (params: any) => {
this.http.get(//server call ).subscribe(res => {
let result = res['result'];
if (result != null && result.paginatedList != null) {
this.totalRecords = result.paginatedList.length;
if (this.totalRecords <= 0) {
this.gridStatusMessageDisplay("");
}
params.successCallback(result.paginatedList, result.totalRecords);
} else {
this.gridStatusMessageDisplay("");
}
});
}
}
this.gridOptions.api.setDatasource(dataSource);
}
temp.html
New Configuration Details
package.json
ag-grid": "^15.0.0",
"ag-grid-angular": "^15.0.0",
"typescript": "^2.6.2"
test.ts pagination replaced with infinite.
/* rowModelType: 'pagination',*/
rowModelType: 'infinite',
pagination: true,
Current Behavior
On call to searchCategory(), server call is made and data loaded into grid with pagination bar.
On clicking next in the pagination bar, its not calling the registered data source and halt there.
Expected Behaviour
pagination should work properly. Datasource should be called on next & prev and update the grid
use other pagination libraries to solve this issue, Here primeng pagination,
https://www.primefaces.org/primeng/#/paginator
//html
<div *ngIf="totalRecords > catPaginationSize">
<p-paginator rows="10" totalRecords="{{totalRecords}}" (onPageChange)="paginate($event)" ></p-paginator>
</div>
//ts
import { PaginatorModule } from 'primeng/primeng';
paginate(event: any) {
this.startIndex = event.first;
this.rowsPerPage = event.rows;
this.paginatedList();
}
I have several unique cases inside ui-grid where the cells of certain table contents need additional class, or even style rules assigned, so the appearance for these cells stands out compared to others. Looking through the official ui-grid documentation I found that it could be done with cellTemplate, but I couldn't get any consistent results. What is the best approach here?
Below are the code changes I have attempted before, with the intent being to change the class name based on the returned value from a filter call made
//Define Grid Headings
$scope.scheduledPatientAppointments = [
{
field: 'appointment_date',
displayName: 'Appointment Date'
},
{
field: 'doctor_name',
displayName: 'Doctor Name'
},
{
field: 'procedure_type_eng',
displayName: 'Medical Procedure Type'
},
{
field: 'appointment_status_eng',
displayName: 'Appointment Status'
},
{
field: 'docs_received',
displayName: 'Related Documents',
cellTemplate: '<div class="ui-grid-cell-contents" ng-click="grid.appScope.loadDocumentsModal(\'{{row.entity.id}}\')">{{grid.getCellValue(row, col) | hasDocuments}}</div>',
cellFilter: 'hasDocuments',
cellClass: function(grid, row, col, rowRenderIndex, colRenderIndex) {
if (grid.getCellValue(row, col).toLowerCase() === 'missing') {
return 'missing';
} else if (grid.getCellValue(row, col).toLowerCase() === 'received') {
return 'received';
} else {
return 'undefined';
}
}
}
];
// Define Grid Options
$scope.PatientAppointmentsGrid = {
selectionRowHeaderWidth: 25,
enableHorizontalScrollbar: false,
rowHeight: 35,
enableSorting: true,
columnDefs: $scope.columnsPatient,
data: [],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
//Behavior for patient page load
$scope.appointmentsProvider = patientsService.patientFactory.getAppointmentsForPatient($stateParams.id).then(
function successCallback(response) {
var preFetchData = response.data.data;
angular.forEach(preFetchData, function (value, key) {documentsService.documentsFactory.getDocumentsByAppointmentId(value.id).then(
function successCallback(response2) {
if (response2.data.length >= 1) {
//Append value state to the preFetchData object (count size)
var totalFiles = response2.data.length;
preFetchData[key].docs_received = totalFiles;
} else {
preFetchData[key].docs_received = 0;
}
}, function errorCallback(response2) {
console.debug("Error", response2);
});
});
$scope.PatientAppointmentsGrid.data = preFetchData;
},
function errorCallback(response) {
console.debug("Error", response);
});
The contents from the "Related Documents" are initally set to Missing (the original rest call returns nothing, and the filter call sets it to that. However, a later call actually loads associated documents per row, and I believe the inactivity of the grid on this particular call is what is causing no class to get set here.
Thoughts on the best approach here?
adding custom class with cellTemplate:
columnDefs: [
{
name:'firstName',
field: 'first-name',
// adding custom class
cellTemplate: "<div class=\"ui-grid-cell-contents custom-class\" title=\"TOOLTIP\">{{COL_FIELD CUSTOM_FILTERS}}</div>"
},
{ name:'1stFriend', field: 'friends[0]' },
{ name:'city', field: 'address.city'},
{ name:'getZip', field: 'getZip()', enableCellEdit:false}
],
.......
there are plenty of predefined customizable templates defined with $templateCache at the bottom of https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.2.9/ui-grid.js
adding custom style:
.......
onRegisterApi: function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
// adding custom style
gridApi.grid.registerStyleComputation({
func: function () {
return [
'.custom-class { ',
' color: red; ',
' font-weight: bold; ',
'} ',
'.ui-grid-row:nth-child(1) .custom-class { ',
' color: blue; ',
'} '
].join('\n');
}
});
}
plunker: http://plnkr.co/edit/YbnYoWLlEYzwmjuKOFa0?p=preview
I am using ui grid to show a list of data and I am trying to initially expand all rows.
I am trying to do this in the onRegisterApi event:
scope.GridOptions =
{
data: properties,
columnDefs:
[
{ name: "Full Address", field: "FullAddress" },
{ name: "Suburb", field: "Suburb" },
{ name: "Property Type", field: "PropertyType" },
{ name: "Price", field: "Price", cellFilter: 'currency'},
{ name: "Status", field: "Status" },
{ name: "Sale Type", field: "SaleType" },
{ name: "Date Created", field: "CreateDate", cellFilter: "date:'dd/MM/yyyy HH:mma'"}
],
expandableRowTemplate: 'template.html',
expandableRowHeight: 200,
onRegisterApi: (gridApi) =>
{
scope.gridApi = gridApi;
gridApi.expandable.on.rowExpandedStateChanged(scope,(row) =>
{
if (row.isExpanded) {
this.scope.GridOptions.expandableRowScope = row.entity;
}
});
gridApi.expandable.expandAllRows();
}
};
But the code above does not work. It looks like when I call expandAllRows() the rows are not rendered yet.
In my case, the following worked:
$scope.gridOptions = {
...
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.gridApi.grid.registerDataChangeCallback(function() {
$scope.gridApi.treeBase.expandAllRows();
});
}
};
I find I can expand all rows by using rowsRendered event:
gridApi.core.on.rowsRendered(scope,() => {
if (!gridApi.grid.expandable.expandedAll && !initialized)
{
gridApi.expandable.expandAllRows();
initialized = true;
}
});
I have used a variable initialized to identify if this is the first time rows are rendered as I only want to expand all rows initially.
None of the above worked for me for all of my grid use cases.
$scope.gridApi.grid.registerDataChangeCallback(function() {
if($scope.gridApi.grid.treeBase.tree instanceof Array){
$scope.gridApi.treeBase.expandAllRows();
}
});
The following works in every case I have tested. DataChangeCallback is called twice (for some unknown reason) on initial page load. The first time, gridApi.grid.treeBase.tree is an object which causes the issue with gridApi.grid.treeBase.tree.forEach above:
None of these answers worked for me, the following did:
scope.gridApi.core.on.rowsRendered(null, () => {
scope.gridApi.treeBase.expandAllRows();
});
The following worked for me, but no guarantee that it won't break anything... (looks good in my tests):
You need to change the source code, for example in ui-grid.js, i.e. the one your are deploying with your app:
In the addOrUseNode: function(...) inside the createTree: function(...) simply change COLLAPSED to EXPANDED for newNodes:
addOrUseNode: function (grid, row, parents, aggregationBase) {
...
var newNode = { state: uiGridTreeBaseConstants.EXPANDED, row: row, parentRow: null, aggregations: newAggregations, children: [] };
...
}
In module.service('uiGridTreeBaseService'... initializeGrid: function(grid) set grid.treeBase.expandAll from false to true (to let the tree know that all rows are expanded on initialitation)
[looks this is optional for the treeView]: Do the same In module.service('uiGridExpandableService', ['gridUtil', function (gridUtil) {...} in initializeGrid: function (grid). Change grid.expandable.expandedAll from false to true
I want to see totals (or generally any aggregation function) for each group in a grid.
This was requested and closed as done in issue: https://github.com/angular-ui/ng-grid/issues/95 (but unfortunately without any example).
I am able to redefine default template https://github.com/angular-ui/ng-grid/blob/master/src/templates/aggregateTemplate.html by aggregateTemplate config option. But I don't know how to extend it properly.
This template is evaluating in ng-grid scope and I don't know how to trigger my custom aggregation function. I want to create similar function as '''totalChildren''' (from https://github.com/angular-ui/ng-grid/blob/master/src/classes/aggregate.js )
Any ideas?
I found the answer: https://github.com/angular-ui/ng-grid/issues/290
For a completenes here is an example of my aggredate function:
function WorkLoadCtrl($scope, Issue, $routeParams, HttpCache) {
$scope.issues = Issue.jql_search({jql: $routeParams.jql});
$scope.aggFC = function (row) {
var res = 0;
var calculateChildren = function(cur) {
var res = 0;
var remaining;
angular.forEach(cur.children, function(a) {
remaining = a.getProperty('fields.timetracking.remainingEstimateSeconds');
if (remaining) { res += remaining; }
});
return res;
};
var calculateAggChildren = function(cur) {
var res = 0;
res += calculateChildren(cur);
angular.forEach(cur.aggChildren, function(a) {
res += calculateAggChildren(a);
});
return res;
};
return (calculateAggChildren(row) / 3600).toFixed(2);
}
$scope.mySelections = [];
$scope.gridOptions = {
data: 'issues.issues',
columnDefs: [
{field:'key', displayName:'key'},
{field:'fields.assignee.name', displayName:'Assignee'},
{field:'fields.status.name', displayName:'Status'},
{field:'fields.summary', displayName:'Summary'},
{field:'fields.timetracking.remainingEstimate', displayName:'Remaining'},
],
showFooter: true,
showGroupPanel: true,
enablePinning: true,
enableColumnResize: true,
enableColumnReordering: true,
showColumnMenu: true,
showFilter: true,
//jqueryUIDraggable: true, bug: when used grouping stop work, but column reordering start to work:(
selectedItems: $scope.mySelections,
multiSelect: false,
aggregateTemplate: '<div ng-click="row.toggleExpand()" ng-style="rowStyle(row)" class="ngAggregate"> <span class="ngAggregateText">{{row.label CUSTOM_FILTERS}} (count: {{row.totalChildren()}} {{AggItemsLabel}} Remaining: {{aggFC(row)}})</span> <div class="{{row.aggClass()}}"></div> </div>'
};
}
i need to drag from grlRicProd to drop into grlInsOrd
grlIRicProd:
.....
id: 'grlRicProd',
sm: new Ext.grid.RowSelectionModel({
singleSelect: false
}),
enableDragDrop: true, ddGroup: 'grlRicProd-dd',
ddText: 'Prodotto Selezionato',
......
grlInsOrd
....
id: 'grlInsOrd',
enableDragDrop:
true, ddGroup: 'grlInsOrd-dd',
listeners: {
"render": {
fn: function(grid) {
var ddrow = new Ext.dd.DropTarget(Ext.getCmp('grlInsOrd').getEl(), {
ddGroup: 'grlRicProd-dd', // Data come from??
copy: false,
notifyDrop: function(dd, e, data) {
var sm = Ext.getCmp('grlRicProd').getSelectionModel();
var rows = sm.getSelections();
var cindex = dd.getDragData(e).rowIndex; //cindex IS UNDEFINED! WHY?
if (sm.hasSelection()) {
for (i = 0; i < rows.length; i++) {
Ext.getCmp('grlRicProd').store.remove(Ext.getCmp('grlRicProd').store.getById(rows[i].id)); //THIS WORKS FINE
Ext.getCmp('grlInsOrd').insert(cindex,rows[i]);//ERROR cindex is not defined
}
sm.selectRecords(rows);
}
});
}
}
}
how can i solve it??
thanks!
See this example and its code:
http://dev.sencha.com/deploy/ext-4.0.2a/examples/dd/dnd_grid_to_grid.html
It works perfectly! You are doing something which isnt required. the copy, creation and removal is all done automatically.