<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script>
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-balham.css">
</head>
<body>
<h1>Hello from ag-grid!</h1>
<div id="myGrid" style="height: 500px; width:700px;" class="ag-theme-balham"></div>
<script src="number-formatter.js"></script>
<script src="numeric-editor.js"></script>
<script src="range-filter.js"></script>
<script type="text/javascript" charset="utf-8">
const columnDefs = [
{headerName: 'Make', field: 'make'},
{headerName: 'Model', field: 'model'},
{
headerName: 'Price',
field: 'price',
editable: true,
cellRenderer: 'numberCellFormatter',
cellEditor: 'numericCellEditor',
filter: 'rangeFilter',
}
];
const gridOptions = {
columnDefs: columnDefs,
enableSorting: true,
enableFilter: true,
components: {
numberCellFormatter: NumberCellFormatter,
numericCellEditor: NumericCellEditor,
rangeFilter: RangeFilter
}
};
const eGridDiv = document.querySelector('#myGrid');
new agGrid.Grid(eGridDiv, gridOptions);
fetch('https://www.ag-grid.com/example-assets/row-data.json').then(function (response) {
return response.json();
}).then(function (data) {
gridOptions.api.setRowData(data);
})
</script>
</body>
</html>
# JavaScript AG Grid Customization Demo
A quick demo of customizing AG Grid with JavaScript to have custom filters, editors and cell renderers.
Blog:
https://blog.ag-grid.com/learn-to-customize-javascript-grid-in-less-than-10-minutes/
Code:
https://github.com/ag-grid/javascript-data-grid/tree/main/customization-demo
class NumberCellFormatter {
init(params) {
const text = params.value.toLocaleString(undefined, {style: 'currency', currency: 'EUR'});
this.eGui = document.createElement('span');
this.eGui.innerHTML = text;
}
getGui() {
return this.eGui;
}
}
class NumericCellEditor {
init(params) {
this.textInput = document.createElement('input');
this.textInput.value = params.value;
this.textInput.addEventListener('keypress', (event) => {
if (!isNumeric(event)) {
event.preventDefault();
}
function isNumeric(event) {
return /\d/.test(event.key);
}
});
this.textInput.addEventListener('keydown', (event) => {
if (event.keyCode === 39 || event.keyCode === 37) {
event.stopPropagation();
}
});
}
getGui() {
return this.textInput;
}
afterGuiAttached() {
if (this.textInput) this.textInput.focus();
};
getValue() {
return Number(this.textInput.value);
};
}
class RangeFilter {
init(params) {
this.params = params;
this.filter = '';
this.form = document.createElement('form');
this.input = document.createElement('input');
const button = document.createElement('button');
this.form.appendChild(this.input);
this.form.appendChild(button);
this.input.name = 'filter';
this.input.value = this.filter;
button.textContent = 'Apply';
this.form.addEventListener('submit', (event) => {
event.preventDefault();
let filter = event.target.elements.filter.value;
if (this.filter !== filter) {
this.filter = filter;
this.params.filterChangedCallback();
}
});
}
getGui() {
return this.form;
}
isFilterActive() {
return this.filter !== '';
}
doesFilterPass(params) {
const filter = this.filter.split('-');
const gt = Number(filter[0]);
const lt = Number(filter[1]);
const value = this.params.valueGetter(params.node);
return value >= gt && value <= lt;
}
getModel() {
return {filter: this.filter};
}
setModel(model) {
this.filter = model ? model.filter : '';
}
afterGuiAttached(params) {
this.input.focus();
}
}