AgGrid: add/remove rows, in Grid already having grouping/sorting/filtering applied - ag-grid

To be able to add/remove rows, in a grid which has already applied grouping/sorting/filtering, without reapplying the grouping/sorting/filtering on this row add/remove. It is that user can work on a group, updating some new values/adding new record which may still not belong to same group of grouping is reapplied, but we do not want to reapply grouping as user input will get scattered in grid, and hard to review for user.
What we tried with ("ag-grid": "^10.0.0", "ag-grid-enterprise": "^10.0.0", "ag-grid-react": "^10.0.0",)
Add a new row on some event/ btn click, in an already rendered grid with some data on startup, using the below(Skipping the refresh):
Let newItems = [];
let newItem= {
id: 'SomethingNewId'+Math.random(),
qty: 300,
owner:"Deepak Kumar SHarma",
isUpdated: true
};
newItems.push(newItem); this.gridOptions.api.insertItemsAtIndex(4, newItems, true); // Saying do not refresh the grid
After, above step, I see by iterating that a rowNode has been added, but row was not visible in grid. Then tried to refresh this newly added row only, so that it is visible in grid, expecting it to be without reapply this filter/sorting/filtering:
let nodes = [];
this.gridOptions.api.forEachNode( (node, index) => {
if (node.data!==null && node.data!==undefined && node.data.isUpdated===true) {
nodes.push(node);
}
});
this. gridOptions.api.refreshRows(nodes);
But still do not see the newly added row in grid.
If I just change the sorting/filtering/grouping manually again to some new setting, I see the new row in grid.

Related

Ag-grid cell renderer doesn't update its rowIndex in real time?

I'm wondering how I can complete my cell renderer. The renderer adds a new row when clicking an icon, and removes it when clicked again. The problem is the invididual cell renderers row indexes do not change unless I hard refresh the entire grid (which then disables the state of the dropdown itself)
How can I complete this?
const insertIndex = params.rowIndex + 1;
this.eventListener = () => {
if (!this.eButton.classList.contains('open')) {
gridOptions.api.applyTransaction({add:[{step: this.dropdownValue, dropdownRow: true}], addIndex: insertIndex });
} else {
let rowData = [];
gridOptions.api.forEachNode(function (node) {
rowData.push(node);
});
let insertedRow = rowData[insertIndex];
gridOptions.api.applyTransaction({remove:[insertedRow.data]});
}
this.eButton.classList.toggle('open');
};
this.eButton.addEventListener('click', this.eventListener);
}
option 1: Hard refresh the grid, but I lose the 'open' status of the dropdown icon. How can i carry state over after a hard refresh?
option 2: Find a way that params.rowIndex is updated after applyTransaction.
Ive tried using the default rowGroup feature, however it hides all columns by default and I havent found a way to make it work the way I need.
The solution im after is a simple 'open/close' toggle for a single row underneath without affecting the other rows

How can I update data within Detail table and don't loose range selection and filters?

I have latest enterprise React agGrid table with Master/Detail grid. My data is fetched on the client every 5 seconds and then put immutably to the redux store. React grid component is using deltaRowDataMode={true} props and deltaRowDataMode: true in Detail options.
My master grid performs normally as expected: if I have range selected, grid would keep selection after the data updates, so would filters and visibility menu would be still opened. But Detail grid behaves differently: on data refresh selections are being removed, visibility menu closes and grid jumps if filters were changed.
I've read in docs that when I open Detail grid it's being created from scratch, but in my case I don't close Detail. Anywhere I've tried keepDetailRows=true flag, which solved problems with jumping on update and selection loss, but Detail grid doesn't update data now.
It seems there are only two possible options according to the docs https://www.ag-grid.com/javascript-grid-master-detail/#changing-data-refresh. The first one is a detail table redraws everytime a data in a master row changes and the second one is a detail row doesn't changes at all if a flag suppressRefresh is enabled. Strange decision, awful beahviour...
Update.
Hello again. I found a coupe of solutions.
The first one is to use a detailCellRendererParams in table's options and set suppressRefresh to true. It gives an opportunity to use getDetailGridInfo to get detail-table's api.
While the detail-table's refreshing is disabled, using detailGridInfo allows to set a new data to a detail-table.
useEffect(() => {
const api = gridApiRef;
api && api.forEachNode(node => {
const { detailNode, expanded } = node;
if (detailNode && expanded) {
const detailGridInfo = api.getDetailGridInfo(detailNode.id);
const rowData = detailNode.data.someData; // your nested data
if (detailGridInfo) {
detailGridInfo.api.setRowData(rowData);
}
}
});
}, [results]);
The second one is to use a custom cellRenderer, wicth is much more flexible and allows to use any content inside a cellRenderer.
In table's options set detailCellRenderer: 'yourCustomCellRendereForDetailTable.
In yourCustomCellRendereForDetailTable you can use
this.state = {
rowData: [],
}
Every cellRenderer has a refresh metod which can be used as follow.
refresh(params) {
const newData = [ ...params.data.yourSomeData];
const oldData = this.state.rowData;
if (newData.length !== oldData.length) {
this.setState({
rowData: newData,
});
}
if (newData.length === oldData.length) {
if (newData.some((elem, index) => {
return !isEqual(elem, oldData[index]);
})) {
this.setState({
rowData: newData,
});
}
}
return true;
}
Using method refresh this way gives a fully customizable approach of using a detailCellRenderer.
Note. To get a better performance with using an immutable data like a redux it needs to set immutableData to true in both main and detail tables.

ag-grid programmatically selecting row does not highlight

Using Angular 4 (typescript), I have some code like below using ag-grid 12.0.2. All I'm trying to do is load my grid and automatically (programmatically) select the first row.
:
this.gridOptions = ....
suppressCellSelection = true;
rowSelection = 'single'
:
loadRowData() {
this.rowData = [];
// build the row data array...
this.gridOptions.api.setRowData(this.rowData);
let node = this.gridOptions.api.getRowNode(...);
// console logging here shows node holds the intended row
node.setSelected(true);
// console logging here shows node.selected == true
// None of these succeeded in highlighting the first row
this.gridOptions.api.redrawRows({ rowNodes: [node] });
this.gridOptions.api.redrawRows();
this.gridOptions.api.refreshCells({ rowNodes: [node], force: true });
First node is selected but the row refuses to highlight in the grid. Otherwise, row selection by mouse works just fine. This code pattern is identical to the sample code here: https://www.ag-grid.com/javascript-grid-refresh/#gsc.tab=0 but it does not work.
Sorry I am not allowed to post the actual code.
The onGridReady means the grid is ready but the data is not.
Use the onFirstDataRendered method:
<ag-grid-angular (firstDataRendered)="onFirstDataRendered($event)">
</ag-grid-angular>
onFirstDataRendered(params) {
this.gridApi.getDisplayedRowAtIndex(0).setSelected(true);
}
This will automatically select the top row in the grid.
I had a similar issue, and came to the conclusion that onGridReady() was called before the rows were loaded. Just because the grid is ready doesn't mean your rows are ready.(I'm using ag-grid community version 19) The solution is to setup your api event handlers after your data has loaded. For demonstration purposes, I'll use a simple setTimeout(), to ensure some duration of time has passed before I interact with the grid. In real life you'll want to use some callback that gets fired when your data is loaded.
My requirement was that the handler resizes the grid on window resize (not relevant to you), and that clicking or navigating to a cell highlights the entire row (relevant to you), and I also noticed that the row associated with the selected cell was not being highlighted.
setUpGridHandlers({api}){
setTimeout(()=>{
api.sizeColumnsToFit();
window.addEventListener("resize", function() {
setTimeout(function() {
api.sizeColumnsToFit();
});
});
api.addEventListener('cellFocused',({rowIndex})=>api.getDisplayedRowAtIndex(rowIndex).setSelected(true));
},5000);
}
Since you want to select the first row on page load, you can do onething in constructor. But your gridApi, should be initialized in OnGridReady($event) method
this.gridApi.forEachNode((node) => {
if (node.rowIndex === 0) {
node.setSelected(true);
}
It's setSelected(true) that does this.
We were using MasterDetail feature, its a nested grid and on expanding a row we needed to change the selection to expanded one.
Expanding a row was handled in
detailCellRendererParams: {
getDetailRowData: loadNestedData,
detailGridOptions: #nestedDetailGridOptionsFor('child'),
}
and withing loadNesteddata, we get params using we can select expanded row as
params.node.parent.setSelected(true)
Hope this helps.

How to implement Expand/Collapse for a table with Multiple columns - GWT - Google Visualization API

I have list of Items with parent child relation.
At present I am displaying them in a single table. In each row, fist column starts with number of '-'s indicating the depth.
Now I want show only top level items first and with a '+' button before that.
When the user clicks on the '+' button it should turn to '-' and the children of that particular Item need to be displayed.
So, Please help me how to implement that Expand and Collapse functionality in GWT.
EDIT:
I have my Items in a tree format.
Now I am creating a DataTable and Displaying it using GoogleTableChart
The code as follows:
DataTable data = DataTable.create();
data.addColumn(ColumnType.STRING, "Item Name ");
data.addColumn(ColumnType.STRING, "Item Id");
data.addColumn(ColumnType.NUMBER, "Quantity");
data.addColumn(ColumnType.NUMBER, "Price ($)");
data.addRows(treeList.size());
int i=0;
while(i<treeList.preOrderTraversal().size())
{
int col=0;
Item d=(Item) treeList.preOrderTraversal().get(i);
int level=d.getLevel();
//setting values to DataTable goes here
i++;
}
GoogleTableChart tblChart = new GoogleTableChart();
vPanel.add(tblChart.showFlexibleTable1(data));
Here is my solution:
I create Nested VertialPanels for each Item. And put the reference in a map.
Hide/unhide the panels based on clicks.
For root Item take one panel and add all its children.
After adding one child, add all its children to another panel,hide it and add to root panel.
repeat the steps recursively.
before each row place put (+/-) label and add click handler which take item id as parameter.
when these lables are clicked, based on the status we hide/unhide the panels, taken from the map.
Any Better Solution ... ??

Smart GWT listgrid, how to expand and row span at the same time

So I have a Smart GWT ListGrid and I want to be able to make the rows expandable and at the same time do a row span on them. Expanding rows which are not merged (by doing row span) works fine, however if I have several rows that are merged the expand icon disappears. My code for expanding and row spanning is this:
lisgrid = new LisGrid()
{
#Override
protected Canvas getExpansionComponent(final ListGridRecord record)
{
// Add a nested grid to display the remaining requests for the tag
// (after the first N being shown be default).
VLayout layout = new VLayout(5);
layout.setPadding(1);
final ExtendedListGrid requestGrid = new ExtendedListGrid();
requestGrid.setWidth(500);
requestGrid.setHeight(224);
requestGrid.setCellHeight(22);
requestGrid.setDataSource(datasource);
requestGrid.fetchData();
layout.addMember(requestGrid);
return layout;
}
};
listGrid.setAllowRowSpanning(true);
listGrid.setCanExpandRecords(true);
listGrid.setMergeCols(new String[] { "requestSummaryTagId", "gca" });
I have overridden the getRowSpan method of the ListGrid to span a cell until the cell right under (same column index and next row index) it has the same value, and I also have a method, setMergeCols, that tells the grid which cells to span across rows. Here is what it looks like. As you can see, the first 2 cells at the bottom span 4 rows, but the expand symbol is missing, while for the rows above (which don't have any row span) the expand symbol is there. Any idea why?