AG-Grid Tutorial With Asp.Net Core Razor Pages - Part 2
Tags: dotnet, javascript, tutorial
Published: 2020-02-03 10:37:09

Continuing the AG Grid series, I added some other features to my previous post. I cleaned the repo a little bit, removing some unnecessary files and dependencies, and also adding the ag-grid specific js and css files to the local folder, instead of accessing them from the internet. So, I apologize because of the quality of the previous code.

My observation until now is that DataTables.js as a free JavaScript grid is an easier solution versus Ag-Grid. Later on I will try some enterprise features of Ag-Grid, maybe this will compensate for that.

Preliminary steps:
1. check the previous tutorial: https://dev.to/zoltanhalasz/ag-grid-tutorial-with-asp-net-core-razor-pages-part-1-26mn
1. application is live under: https://ag-grid2.zoltanhalasz.net/
2. zipped(cleaned) repo of the application: https://drive.google.com/open?id=10A0as_DTC94ve_oVtDF2uFW1cX19k4J7

*How the app will look like:*
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a7csd0k485be31p8q7ld.png)

**The steps of the tutorial are:**


A. please remove the unnecessary files from the wwwroot (if you are using the part 1 repo).

B. check their official community resource from github, cloning their repo https://github.com/ag-grid/ag-grid/tree/master/community-modules/all-modules/dist

i. take the file ag-grid-community.min.js and copy it under wwwroot/js folder
(or ag-grid-community.noStyle.js)

ii. the same, for the CSS files, taken from the Styles folder in the repo above
copy the them in the Css folder, and then reference them from the Layout file:
```html
    <link rel="stylesheet" href="~/css/ag-grid.css">
    <link rel="stylesheet" href="~/css/ag-theme-balham.css">
```

C. the whole source of the index page will be:


```html
<script src="~/js/ag-grid-community.min.js"></script>
<h1>Hello from ag-grid - Part 2</h1>

<div>
    <div id="mybutton">
        <button onclick="onExportCsv()" class="btn-info">Export Csv</button>
    </div>
    <div id="myGrid" style="height: 450px;width:900px;" class="ag-theme-balham"></div>
</div>


<script type="text/javascript" charset="utf-8">

    var deleteRenderer = function(params) {
        var eDiv = document.createElement('div');
        eDiv.innerHTML = '<span class="my-css-class"><button class="btn-del btn-danger btn-xs">Delete</button></span>';
        var eButton = eDiv.querySelectorAll('.btn-del')[0];

        eButton.addEventListener('click', function() {         
            console.log('will be deleted, invoice no:', params.data.ID);
            window.location.href = './Delete?id='+params.data.ID;
        });

        return eDiv;
    }
    var editRenderer = function (params) {
        var eDiv = document.createElement('div');
        eDiv.innerHTML = '<span class="my-css-class"><button class="btn-edit btn-warning btn-xs">Edit</button></span>';
        var eButton = eDiv.querySelectorAll('.btn-edit')[0];

        eButton.addEventListener('click', function() {         
            console.log('will be edited, invoice no:', params.data.ID);
            window.location.href = './Edit?id='+params.data.ID;
        });

        return eDiv;
    }

    var detailsRenderer = function (params) {
        var eDiv = document.createElement('div');
        eDiv.innerHTML = '<span class="my-css-class"><button class="btn-details btn-info btn-xs">Details</button></span>';
        var eButton = eDiv.querySelectorAll('.btn-details')[0];

        eButton.addEventListener('click', function() {         
            console.log('will be info, invoice no:', params.data.ID);
                  window.location.href = './Detail?id='+params.data.ID;
        });

        return eDiv;
    }
    // specify the columns
    var columnDefs = [
        { headerName: "InvoiceNumber", field: "InvoiceNumber" },
        { headerName: "Amount", field: "Amount" },
        { headerName: "CostCategory", field: "CostCategory" },
        { headerName: "Period", field: "Period" },
        { headerName: "Delete", field: null, cellRenderer: deleteRenderer },
        { headerName: "Edit", field: null, cellRenderer: editRenderer },
        { headerName: "Details", field: null, cellRenderer: detailsRenderer },
    ];

    // let the grid know which columns to use
    var gridOptions = {
        columnDefs: columnDefs,
        defaultColDef: {
            sortable: true,
            filter: true,
            width: 120,

        },
        rowHeight : 35,
        pagination: true,
        paginationPageSize: 10,     
    };

    // lookup the container we want the Grid to use
    var eGridDiv = document.querySelector('#myGrid');



    function getParams() {
        return {
            suppressQuotes: null,
            columnSeparator: null,
            customHeader: null,
            customFooter: null
        };
    }

    function onExportCsv() {
        var params = getParams();
         gridOptions.api.exportDataAsCsv(params);
    }
 
    // 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>

```

D. pagination
- this is solved using the gridOptions object, setting the properties:
```
        pagination: true,
        paginationPageSize: 10,  
``` 

E. Csv export (basic)
- this is managed using the button with id = "mybutton", and writing its onclick event function:
```
    function onExportCsv() {
        var params = getParams();
         gridOptions.api.exportDataAsCsv(params);
    }
```

for the params object, I returned the basic features for a csv export using getParams function.

See more detailed explanation about csv export on their page: https://www.ag-grid.com/javascript-grid-csv/

F. height and width on the rows/columns
```
     width: 120, // in defaultColDef properties
     rowHeight: 35, // in gridOptions properties
```

G. cell rendering (basic)
for example, in the columnDef for Delete
```
      { headerName: "Delete", field: null, cellRenderer: deleteRenderer },
```
deleteRenderer will be a function generating html for the delete button

```
    var deleteRenderer = function(params) {
        var eDiv = document.createElement('div');
        eDiv.innerHTML = '<span class="my-css-class"><button class="btn-del btn-danger btn-xs">Delete</button></span>';
        var eButton = eDiv.querySelectorAll('.btn-del')[0];

        eButton.addEventListener('click', function() {         
            console.log('will be deleted, invoice no:', params.data.ID);
            window.location.href = './Delete?id='+params.data.ID;
        });

        return eDiv;
    }
```
H. Detail, Edit, Delete Razor pages added for complete CRUD, as per cell rendering links suggest.
This is achieved using Entity Framework applied on the In-Memory database.