Just an idea, but I think that you could add one child placeholder string to the group with "loading ..." in the first cell, with the onRowGroupOpened group event to do ajax to get data from the server, with onreadystatechange , then adding new lines and replacing it. The initial placeholder string may contain the totals calculated by the server to assign the total (cumulative) value in the cells of the group rows that remain unchanged when the real data replaces the placeholder.
I came up with a basic test approach. This is not ideal, as the grid is restored after each extension (I cannot find an elegant way to just add new lines), but it works.
At the very top of the script is an AJAX request for details. Although this happens later in the stream, I put it at the top, so if the server receives this request, it provides data and exits without loading the page again. Alternatively, you can simply put it in another file.
<?php if (isset($_REQUEST['g'])) { // this is the AJAX request for child data (called later, but needed at the start of the script) // get connection to database require_once 'db_connection.php'; $dbh=getConnection(); // query data to array $sql="SELECT accounts.description AS account, '' AS info, tx.amnt AS amount, 1 AS transactions FROM tx INNER JOIN accounts ON tx.account=accounts.account_id WHERE accounts.description='".$_REQUEST['g']."'"; $data=array(); $result = $dbh->query($sql); while ($row = $result->fetch_assoc()) { $data[]=$row; } $result->free(); // return data as JSON print json_encode($data, JSON_NUMERIC_CHECK); exit; } ?>
Then immediately after that a regular HTML page appears with a bit more php in javascript in the head:
<!DOCTYPE html> <html> <head> <script src="lib/ag-grid-enterprise-master/dist/ag-grid-enterprise.js"></script> <script> // get JSON for initial group-level data from server with a little snippet of php which is called when the page is first loaded var rowData = <?php // get connection to the database require_once 'db_connection.php'; $dbh=getConnection(); // query data to array $sql = "SELECT description AS account, 'loading...' AS info, SUM(tx.amnt) AS amount, COUNT(tx.tx_id) AS transactions FROM accounts INNER JOIN tx ON accounts.account_id=tx.account GROUP BY accounts.account_id"; $data=array(); $result = $dbh->query($sql); while ($row = $result->fetch_assoc()) { $data[]=$row; } $result->free(); // inject the JSON into the javascript assignment to rowData print json_encode($data, JSON_NUMERIC_CHECK); ?>; // (back in javascript again) // event function for when a group is expanded function getChildRows(data) { if (data.node.allLeafChildren) { if (data.node.allLeafChildren.length > 0) { if (data.node.allLeafChildren[0].data.info==="loading...") { // data for this group has not yet been loaded, so make AJAX request for it var xmlHttp=new XMLHttpRequest(); xmlHttp.onreadystatechange=function() { if ((xmlHttp.readyState===4) && (xmlHttp.status === 200)) { // call function to add the new rows to the grid addRecords(JSON.parse(xmlHttp.responseText)); } }; var requestParameters="g="+encodeURIComponent(data.node.key); xmlHttp.open("POST", "index.php", true); // call to this same script xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xmlHttp.send(requestParameters); } } } } function addRecords(data) { var x; var d=new Array(); var acc=data[0].account; for(x in gridOptions.api.inMemoryRowModel.rootNode.allLeafChildren) { if (gridOptions.api.inMemoryRowModel.rootNode.allLeafChildren[x].data.account===acc) { // this is group we are replacing with new data for (x in data) { d.push(data[x]); } } else { // this node is just the data as currently loaded to the grid (no change) d.push(gridOptions.api.inMemoryRowModel.rootNode.allLeafChildren[x].data); } } gridOptions.api.setRowData(d); } // set up the grid (standard stuff) var columnDefs = [ {headerName: "Account", field: "account", rowGroupIndex: 0, cellRenderer: "group", cellRendererParams : {suppressCount: true} }, {headerName: "Info", field: "info"}, {headerName: "Amount", field: "amount", aggFunc:"sum"}, {headerName: "Transactions", field: "transactions", aggFunc:"sum"} ]; var gridOptions = { columnDefs: columnDefs, rowData: rowData, groupSuppressAutoColumn: true, onRowGroupOpened: getChildRows /* event created above */ } document.addEventListener("DOMContentLoaded", function() { var eGridDiv = document.querySelector('#myGrid'); new agGrid.Grid(eGridDiv, gridOptions); }); </script> </head> <body> <div id="myGrid" style="height: 100%;" class="ag-fresh"></div> </body> </html>
@Niall - any ideas on how to add new lines more elegantly and keep the group extension status?