Reputation: 11
When I filter a Javascript AG Grid by hiding columns, I only want to see row data if the remaining columns actually contain data. How can I do this?
Here is my example grid:
index.html:
<!doctype html>
<html lang="en">
<head>
<title>JavaScript Example - Side Bar - Boolean Configuration</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex" />
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;700&display=swap"
rel="stylesheet"
/>
<style media="only screen">
:root,
body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
font-family: -apple-system, "system-ui", "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
"Noto Color Emoji";
}
body {
padding: 16px;
overflow: auto;
background-color: transparent;
}
</style>
</head>
<body>
<div id="myGrid" class="ag-theme-quartz" style="height: 100%"></div>
<script>
(function () {
const appLocation = "";
window.__basePath = appLocation;
})();
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ag-grid-charts-enterprise.js?t=1731498721360"></script>
<script src="main.js"></script>
</body>
</html>
Here's my main.js:
let gridApi;
const gridOptions = {
columnDefs: [
{ field: "A" },
{ field: "B" },
{ field: "C" },
{ field: "D" },
],
rowData: [
{ A: "y", B: "", C: "", D: "" },
{ A: "y", B: "y", C: "", D: "" },
{ A: "y", B: "y", C: "y", D: "" },
{ A: "y", B: "y", C: "y", D: "y" },
{ A: "y", B: "y", C: "y", D: "y" },
{ A: "y", B: "y", C: "y", D: "y" },
],
defaultColDef: {
flex: 1,
minWidth: 100,
enableValue: true,
enableRowGroup: true,
enablePivot: true,
filter: true,
},
autoGroupColumnDef: {
minWidth: 200,
},
sideBar: true,
};
// setup the grid after the page has finished loading
document.addEventListener("DOMContentLoaded", function () {
var gridDiv = document.querySelector("#myGrid");
gridApi = agGrid.createGrid(gridDiv, gridOptions);
});
Here's my package.json file (why is this even needed??):
{
"name": "ag-grid-packages",
"dependencies": {
"ag-grid-community": "^32.3.3",
"ag-grid-charts-enterprise": "^32.3.3"
}
}
Put these all together, and you get a simple grid that has the sidebar with the columns and filters toolbars added.
If you open the columns toolbar and uncheck column A, the first row still remains, even though there is no data in it. **I want that row to go away, if possible, if it contains no data **so there are fewer rows to deal with. I would want it to come back if I check column A again.
Next, if you open the columns toolbar and uncheck column A, and then go into the Filters toolbar, you will still see column A there. I want to hide that column in the filters toolbar if it is unchecked in the columns toolbar and restore it if the column is checked again.
I've tried googling the issue, but I don't seem to be asking the right question. I know the answer is out there, I'm just not using the correct terminology or something, or my understanding of what I'm trying to do is totally flawed. Part of the objective of this question is to find out what I need to be asking.
I deeply apologize if these are noob questions. I'm not a developer by trade, so I'm very inexperienced with all of this.
UPDATE: Nov.20, 2024: I tried using ChatGPT to see if it could figure out the issue. It seemed to be fairly confident that it could. It found several functions that it felt would make it so that the row would be hidden if none of the visible columns contained any values. Here is what it came up with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AG Grid with Sidebar</title>
<!-- AG Grid Enterprise Scripts -->
<script src="https://cdn.jsdelivr.net/npm/ag-grid-enterprise/dist/ag-grid-enterprise.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-grid.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-theme-alpine.min.css">
</head>
<body>
<div id="myGrid" class="ag-theme-alpine" style="height: 500px; width: 800px;"></div>
<!-- AG Charts Enterprise -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ag-grid-charts-enterprise.js"></script>
<script>
// Provide your AG Grid Enterprise license key here if you have one
agGrid.LicenseManager.setLicenseKey("YOUR_LICENSE_KEY");
// Define column definitions
const columnDefs = [
{ field: 'A', filter: true },
{ field: 'B', filter: true },
{ field: 'C', filter: true },
{ field: 'D', filter: true },
];
// Define row data
const originalRowData = [
{ A: 'y', B: '', C: '', D: '' },
{ A: 'y', B: 'y', C: '', D: '' },
{ A: 'y', B: 'y', C: 'y', D: '' },
{ A: 'y', B: 'y', C: 'y', D: 'y' },
];
// Grid options with filtering and sidebar
const gridOptions = {
columnDefs: columnDefs,
rowData: originalRowData,
defaultColDef: {
filter: true,
sortable: true,
resizable: true,
},
sideBar: {
toolPanels: [
{ id: 'columns', labelDefault: 'Columns', toolPanel: 'agColumnsToolPanel' },
{ id: 'filters', labelDefault: 'Filters', toolPanel: 'agFiltersToolPanel' },
],
defaultToolPanel: 'filters',
},
onGridReady: function (params) {
// Assign APIs to gridOptions for future reference
gridOptions.api = params.api;
gridOptions.columnApi = params.columnApi;
// Run the initial check for visible rows
updateVisibleRows();
},
onFilterChanged: updateVisibleRows,
onColumnVisible: updateVisibleRows, // Trigger row update when columns are hidden or shown
};
// Function to update visible rows based on filters and column visibility
function updateVisibleRows() {
// Ensure columnApi and api are available
if (!gridOptions.columnApi || !gridOptions.api) return;
// Get the visible columns from columnApi
const visibleColumns = gridOptions.columnApi
.getAllColumns()
.filter(col => col.getVisible()) // Filter out columns that are not visible
.map(col => col.getColId());
// Loop through all rows and update their visibility
gridOptions.api.forEachNode((node) => {
// Only check rows that have data
const rowValues = visibleColumns.map(colId => node.data[colId]);
const isNotEmpty = rowValues.some(value => !isEmptyValue(value));
// Set row visibility by calling setDataValue to "visibility" flag (which is not part of the row data)
if (isNotEmpty) {
node.setDataValue('hidden', false); // Keep it visible
} else {
node.setDataValue('hidden', true); // Hide it if it's empty
}
});
// Force a refresh after updating the row data visibility
gridOptions.api.refreshCells();
}
// Helper function to check if a value is considered empty
function isEmptyValue(value) {
return value === null || value === undefined || (typeof value === 'string' && value.trim() === '');
}
// Initialize the grid using createGrid
document.addEventListener('DOMContentLoaded', () => {
const gridDiv = document.getElementById('myGrid');
const { api, columnApi } = agGrid.createGrid(gridDiv, gridOptions);
// Assign APIs to gridOptions for use in event callbacks
gridOptions.api = api;
gridOptions.columnApi = columnApi;
});
</script>
</body>
</html>
This unfortunately didn't work. And this was after multiple iterations. It keeps insisting it should work, but it doesn't. However, interestingly, something weird happens with the filters toolbar. If you go into the filters toolbar, and then uncheck "y" under column A, then all the rows are hidden. If you uncheck "y" under column B, then the first row is visible. If you uncheck "y" under column C, then the first and second rows are visible. If you uncheck "y" under column D, then the first, second, and third rows are visible, but not the fourth. So, the rows are being hidden if they contain no data, but it is being triggered by the column value filters in the filters toolbar, rather than the column filters in the columns toolbar.
I don't really understand why.
Upvotes: 1
Views: 53