Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

JavaScript Grid Plugin

5.00/5 (9 votes)
27 Apr 2014CPOL5 min read 24.7K  
Lightweight and easy to use JavaScript plugin to create UI Grids

Introduction

Many times in a data driven application, we have to display information in the form of a grid. For that purpose, we can normally use a range of JavaScript and jQuery based plugins available out there. When I was working on one such requirement then I tried to use several of those grid plugins but I found none of them good enough to handle JSON data, apply all sorts of templates and customizations and be lightweight at the same time. I needed to dynamically update the data, event based row updates, binding of input elements directly to the json data-source, handle complex templating, etc.

Although frameworks like AngularJS, Sencha, etc. can help in achieving this but they are big in size and loading the entire framework just to create a single grid is an overkill. So I made a note to myself to address this specific problem and I started working on a plugin made entirely in JavaScript and independent of supportive libraries like jQuery.

The good thing about this plugin is that it is lightweight (~13KB compressed), independent of supportive libraries, and highly customizable. I created this by keeping in mind that there can be a lot of different kinds of requirements while creating a web UI grid and a user should be able to micro-manage the entire grid template. The name of this plugin is GridJS and it provides a very easy way to setup UI grids and bind json data to it.

Image 1

The Good Parts

Json Array Driven

This plugin takes data in the Json-Array format as its data-source. The good thing about this is that we can flexibly assign any data as the grid's data-source as long as it is in the form of json.

Templating

We can use templates (in the form of {{value}}) in the grid, the templates can be any object property in the json-array data source, they can be a long chain of objects and properties and they can even be custom defined functions to assign rule based values as data in the data grid.

Input Binding

Input binding is as easy as it can get. Any input element can be directly bound to specific properties in the json-array. The data-source of the grid gets updated as per the user input in the input fields. The data changes can even be fetched separately.

Individual IDs

Every row and column and the included input elements (that have an id assigned) will have unique ids so that they can be post processed and referenced after the grid has been rendered.

Pagination

There can be any number of rows in a single grid page and the rest can be accessed by the pagination that can be activated anytime after defining the number of rows in a single page.

Event Handlers

There are event handlers for grid load, row additions, before page change, after page change and so on.

Sequential Row Colors

There can be any number of sequential colors to color the rows. When all the colors in the sequence are applied, then the cycle repeats from the start of the color list. This allows us to create amazing looking grids with minimal effort.

Apply Custom Css

Custom CSS can be applied to almost any element inside the grid. You can have custom CSS classes for the entire grid, for header, for data rows, for specific columns, and if that's not enough, you can have custom CSS for pagination normal and active numbers also.

Tens of Thousands of Records

Sometimes, we need to have really large grids populating thousands of records. This plugin can handle large number of records and can even provide support of pagination with that.

Using the Code

Using this plugin is very easy. First, we will have to create an HTML markup for our grid like we do for any other table. Then, we just need to apply templating to show values in our grid. The templating feature allows us to directly replace the templates with the specific data from the Json-Array data source.

Step 1

Include the GridJS script in your HTML page.

HTML
<head>
    <script type="text/javascript" src="Scripts/grid.main.js"></script>
</head> 

Step 2

Create the markup for your grid as follows:
  • Use <gridJS-grid> custom element to create the grid.
  • Use <headerRow> element inside <gridJS-grid> to create a header row.
  • Use <dataRow> element inside <gridJS-grid> to create the data row template.
  • Use <footerRow> element inside <gridJS-grid> to create a footer row.
  • Add <column> elements inside <headerRow>, <dataRow> and <footerRow> to add columns to the grid.

The <gridJS-grid> custom element is internally registered on plugin load using document.registerElement(). However, even if a browser does not support registerElement, still the grid will be rendered but the custom element will not be identified by the browser. For more information on this, refer to this link:

For example:
HTML
 <gridjs-grid id="gridNorthWind" class="NorthWindGrid">
    <headerRow class="NorthWindGridHeaderRow">
        <column><b>Order ID</b></column>
        <column><b>Customer ID</b></column>
        <column><b>Emp ID</b></column>
        <column><b>Order Date</b></column>
        <column><b>Shipped Date</b></column>
        <column><b>Freight</b></column>
        <column><b>Ship Name</b></column>
        <column><b>Ship City</b></column>
        <column><b>Ship Postal Code</b></column>
        <column><b>Ship Country</b></column>
    </headerRow>
    <dataRow class="NorthWindGridRow">
        <column>{{OrderID}}</column>
        <column>{{CustomerID}}</column>
        <column>{{EmployeeID}}</column>
        <column>{{GetOrderDate()}}</column>
        <column>{{GetShippedDate()}}</column>
        <column>{{Freight}}</column>
        <column>{{ShipName}}</column>
        <column>{{ShipCity}}</column>
        <column>{{ShipPostalCode}}</column>
        <column>{{ShipCountry}}</column>                
    </dataRow>
    <footerRow>
    </footerRow>
</gridjs-grid> 

After this, the only thing that remains is to initialize a new gridJS object and set its properties and data-source to kick start our UI grid.

JavaScript
var gridJS = new GridJS({
    gridId: 'gridNorthWind',
    dataSource: NorthWindDataSource,
    cellPadding: 6,
    pagination: 10,
    pageButtonCss: { normalCss: 'NorthWindPaginationButton', activeCss: '' },
    dataRowColors: ["#0B6121", "#0A2A0A"]
})
.addCustomFunction("GetOrderDate", function (data, rowIndex) {
    var date = new Date(Date.parse(data[rowIndex].OrderDate));
    return getDate(date);
})
.addCustomFunction("GetShippedDate", function (data, rowIndex) {
    var date = new Date(Date.parse(data[rowIndex].ShippedDate));
    return getDate(date);
});
 
//returns meaningful date format
function getDate(rawDate) {
    month = rawDate.getMonth(),
    day = rawDate.getDate(),
    year = rawDate.getYear();
    return month + "/" + day + "/" + year;
} 

Example data source in the form of Json-aray:

JavaScript
 (function (w) {
    var northWindDataSource =
        {
            "odata.metadata": "http://services.odata.org/V3/Northwind/Northwind.svc/$metadata#Orders"
            , "value":
                [
                    {
                        "Order_Details":
                            [
                                { "OrderID": 10248, "ProductID": 11, "UnitPrice": 
                                "14.0000", "Quantity": 12, "Discount": 0 }
                                , { "OrderID": 10248, "ProductID": 42, "UnitPrice": 
                                "9.8000", "Quantity": 10, "Discount": 0 }
                                , { "OrderID": 10248, "ProductID": 72, "UnitPrice": 
                                "34.8000", "Quantity": 5, "Discount": 0 }
                            ]
                        , "OrderID": 10248
                        , "CustomerID": "VINET"
                        , "EmployeeID": 5
                        , "OrderDate": "1996-07-04T00:00:00"
                        , "RequiredDate": "1996-08-01T00:00:00"
                        , "ShippedDate": "1996-07-16T00:00:00"
                        , "ShipVia": 3
                        , "Freight": "32.3800"
                        , "ShipName": "Vins et alcools Chevalier"
                        , "ShipAddress": "59 rue de l'Abbaye"
                        , "ShipCity": "Reims"
                        , "ShipRegion": null
                        , "ShipPostalCode": "51100"
                        , "ShipCountry": "France"
                    }
                    ,...{}};
w["NorthWindDataSource"] = northWindDataSource.value;

})(window); 

Step 3

Call the draw() function of our gridJS object to draw the grid.

JavaScript
gridJS().draw(); 

and that's it, we have in front of us a UI grid with all the data bindings that we created without breaking a sweat.

Image 2

Points of Interest

The code of this plugin converts the inside HTML of the custom <gridJS-grid> element into HTML table with Ids for every row, so that they can be styled and referenced accordingly later on. For every json object in the datasource, a new data row is added, so the end result consists of simply an HTML table inside the <gridJS-grid> element. No use of jQuery allows to avoid including jQuery code entirely for basic scenarios and small applications.

Browser Support

  • Google Chrome: Great
  • Firefox: Awesome
  • Internet Explorer: ???

Samples and Documentation

You can find the detailed documentation of the GridJS API and many different kinds of samples to see how this plugin can be customized for a variety of grid setup needs at the following link:

Conclusion

Feel free to report any bug or errors that you may encounter if you decide to use this code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)