Besides DataTables.js, I always wanted to check Ag-Grid, which is another great Javascript Grid solution for the front-end. As my apps are from the business world, and have many tables, I wanted to see how AG-Grid would look like in Asp.Net Razor pages.
I quickly checked their Javascript documentation, and prepared a short tutorial, firstly for myself.
The material is based on the existing Datatables tutorial, from my previous posts. It uses an in-memory database and context, injected in the page model.
Please check the following, before starting the tutorial:
1. general introduction: https://www.ag-grid.com/javascript-grid/
2. see previous tutorial, which this one builds upon: https://mydev-journey.blogspot.com/2019/12/datatablejs-tutorial-for-net-core-razor_11.html
3. working example of the tutorial: https://ag-grid1.zoltanhalasz.net/
4. code repo for the tutorial:(zipped) https://drive.google.com/open?id=1BXYkn5RwHnC4w8USCeIBCV0lsDGi-qFh
Explanation of the project:
a. Base class for the application, identical with datatable tutorial above
public class InvoiceModel
{
[JsonProperty(PropertyName = "ID")]
public int ID { get; set; }
[JsonProperty(PropertyName = "InvoiceNumber")]
public int InvoiceNumber { get; set; }
[JsonProperty(PropertyName = "Amount")]
public double Amount { get; set; }
[JsonProperty(PropertyName = "CostCategory")]
public string CostCategory { get; set; }
[JsonProperty(PropertyName = "Period")]
public string Period { get; set; }
}
b. Context for in-memory database, idem
public class InvoiceContext : DbContext
{
public InvoiceContext(DbContextOptions<InvoiceContext> options)
: base(options)
{
}
public DbSet<InvoiceModel> InvoiceTable { get; set; }
}
c. In the Pages/Shared folder, we will edit the _Layout page
insert the following stylesheet links specific to AG-grid, just before </head>
<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">
d. The index page, will have the following methods:
public class IndexModel : PageModel
{
private InvoiceContext _context;
public List<InvoiceModel> InvoiceList;
public IndexModel(InvoiceContext context)
{
_context = context;
}
// this will populate the page, if you want to show the table using the list (with foreach)
public async Task<IActionResult> OnGet()
{
InvoiceList = _context.InvoiceTable.ToList();
return Page();
}
//method to provide list in json format, for the ag-grid
public JsonResult OnGetArrayData()
{
InvoiceList = _context.InvoiceTable.ToList();
return new JsonResult(InvoiceList);
}
}
e. the html razor file, will contain the javascript code, based on the tutorial from ag-grid page
@page
@model IndexModel
@{
Layout = "_Layout";
}
@*//script used to load the grid*@
<script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script>
<h1>Hello from ag-grid!</h1>
<div id="myGrid" style="height: 600px;width:800px;" class="ag-theme-balham"></div>
<script type="text/javascript" charset="utf-8">
// specify the columns
var columnDefs = [
{ headerName: "InvoiceNumber", field: "InvoiceNumber" },
{ headerName: "Amount", field: "Amount" },
{ headerName: "CostCategory", field: "CostCategory" },
{ headerName: "Period", field: "Period" },
];
// let the grid know which columns to use
var gridOptions = {
columnDefs: columnDefs,
defaultColDef: {
sortable: true,
filter: true
},
rowClassRules: {
// row style function
'bigexpense-warning': function(params) {
var numExpense = params.data.Amount;
return numExpense > 20 && numExpense <= 50;
},
// row style expression
'bigexpense-breach': 'data.Amount > 50',
'bigexpense-ok': 'data.Amount <=20'
}
};
// lookup the container we want the Grid to use
var eGridDiv = document.querySelector('#myGrid');
// create the grid passing in the div to use together with the columns & data we want to use
new agGrid.Grid(eGridDiv, gridOptions);
agGrid.simpleHttpRequest({ url: './Index?handler=ArrayData' }).then(function (data) {
gridOptions.api.setRowData(data);
});
</script>
f. create the gridformat.css file in the folder wwwroot/css
include the following in this file
.ag-theme-balham .bigexpense-warning {
background-color: sandybrown !important;
}
.ag-theme-balham .bigexpense-breach {
background-color: lightcoral !important;
}
.ag-theme-balham .bigexpense-ok {
background-color: mediumseagreen !important;
}
- include the reference to gridformat.css in the _Layout file, just above the ag-grid css links
g. some description of the javascript in the index.cshtml
Grid is marked by id:
<div id="myGrid" style="height: 600px;width:800px;" class="ag-theme-balham"></div>
Column headers are defined by array:
var columnDefs = [
{ headerName: "InvoiceNumber", field: "InvoiceNumber" },
{ headerName: "Amount", field: "Amount" },
{ headerName: "CostCategory", field: "CostCategory" },
{ headerName: "Period", field: "Period" },
];
Sorting and filtering (basic) is setup by:
defaultColDef: {
sortable: true,
filter: true
},
Double click on the row headers will sort the column.
There is a basic text filter included.
The formatting of rows, where the invoice Amount is between certain values
rowClassRules: {
// row style function
'bigexpense-warning': function(params) {
var numExpense = params.data.Amount;
return numExpense > 20 && numExpense <= 50;
},
// row style expression
'bigexpense-breach': 'data.Amount > 50',
'bigexpense-ok': 'data.Amount <=20'
}
If you check the simpleHttpRequest function it's called on the handler defined in the pagemodel of the index page:
'./Index?handler=ArrayData'
The final result will be: