MENU
.net Powerful JavaScript charts
About
RGraph is a JavaScript charts library based on HTML5 SVG and canvas. RGraph is mature (over 17 years old) and has a wealth of features making it an ideal choice to use for showing charts on your website.

More »

 

New datagrid in v6.21
In version 6.21 a new datagrid object has been added. This makes it easy to add static or dynamic data tables to your pages. It can be used whether you use the canvas or SVG libraries or entirely standalone.

Read more »

 

Download
Get the latest version of RGraph (version 6.21, 10th April 2025) from the download page. You can read the changelog here. There's also older versions available, minified files and links to cdnjs.com hosted libraries.

Download »

 

License
RGraph can be used for free under the GPL or if that doesn't suit your situation there's an inexpensive (£129) commercial license available.

More »

The datagrid component

Introduction

The datagrid component is new to RGraph in version 6.21 and is a very easy way to show data to your users. It's very customisable with standard css and extensible with a whole host of events and api calls that are available. It can be quickly integrated into your pages and forms so it allows you to quickly and easily build your website and standardise the look of data tables across all of your pages.

Example

Here's a basic example of the datagrid with resizable columns which can be sorted by clicking on the column headers. There's a button underneath the datagrid which resets the column widths back to the default by using an api call.

<script src="RGraph.common.core.js" ></script>
<script src="RGraph.common.datagrid.js" ></script>


<script>
    data = [
        ['Richard','Monday',  124],
        ['Jane',  'Tuesday',    152],
        ['Lucy',  'Wednesday',    98],
        ['Jerry', 'Thursday',95],
        ['Alex',  'Friday',     103],
        ['Freddy','Saturday',     111],
        ['Peter', 'Sunday',    56],
    ];
    
    myGrid = new RGraph.Datagrid({
        id: 'myGrid',
        data: data,
        options: {
            columnsHeaders: ['Name','Day of week','Amount'],
            columnsResizable: true,
            columnsResizablePersistent: true,
            columnsUnitsPre: ['','','<b>&pound;'],
            columnsUnitsPost: ['','','</b>'],
            columnsHTML:[,,true]
        }
    }).draw();
</script>

Properties

You can use these properties to control how the datagrid appears. You can set them by including them in the options section of the configuration as shown above.

Column properties

Name: columnsHeaders
Description: 
An array of strings that are used as the headers to the columns. By default, these are bolded but you can change that by overriding the css that the datagrid specifies with your own. The headers are standard th tags instead of td tags and are nested inside a thead tag instead of the tbody tag.
Default: null
Name: columnsFooters
Description: 
An array of strings that are used as the footers. The footers are standard td tags and are nested inside a tfoot tag instead of the tbody tag.
Default: null
Name: columnsWidths
Description: 
If you want a column to be a specific width (by default the columns are given equal width across the whole table) you can specify that width in this array. For example, if your first column is just an ID number or a checkbox/radio button then you may want this column to be smaller than the rest.
Default: [] (an empty array)
Name: columnsHTML
Description: 
By default, html is not interpreted by the datagrid and is shown as-is to the user. You can change this behaviour though by specifying the column index in this option. It can either be a single number - the index of the field (the numbering starts at zero remember) or it can be an array of numbers denoting the column indexes that you want to allow html in.
Default: null
Name: columnsUnitsPre
Description: 
You can use this property to apply a small bit of text to the beginning of the value. You can specify a unit (eg $) or if you're allowing html in this column it could be an opening tag (eg <b>).
Default: [an empty string]
Name: columnsUnitsPost
Description: 
You can use this property to apply a small bit of text to the end of the value. You can specify a unit (eg kg) or if you're allowing html in this column it could be a closing tag (eg </b>).
Default: [an empty string]
Name: columnsCssClass
Description: 
If you want to add a custom css class to the columns (either the th or td tags) you can do so with this property. It can either be a string - in which case it's added to all of the columns - or it can be an array - in which case it's added to the td tag which has the corresponding column index.
Default: null
Name: columnsPoint
Description: 
When numbers are formatted for display this is the string that's used as the decimal point. It can be one or more characters.
Default: .
Name: columnsThousand
Description: 
When numbers are formatted for display this is the string that's used as the thousand separator. It can be one or more characters.
Default: ,
Name: columnsDecimals
Description: 
When numbers are formatted for display this is how many decimal characters that are displayed.
Default:  0
Name: columnsFormatter
Description: 
If you want to control all aspects of how numbers are formatted this can be a function that does that. Your function should accept a single argument which is an object that contains both the number and meta information. It should return the relevant string to show to the user. This can be both a single function that handles the formatting of all of the columns or it can be an array of different functions - one per column. It can look like this:
columnsFormatter: function (opt)
{
    console.log(opt);
    return opt.number;

},
Or like this:
var f1 = function (opt)
{
    // This is the formatter function for the THIRD column
    console.log(opt);
    return opt.number;
}

var f2 = function (opt)
{
    // This is the formatter function for the SIXTH column
    console.log(opt);
    return opt.number;
}

//...

columnsFormatter: [,,f1,,,f2]
Default: null
Name: columnsResizable
Description: 
If you want the columns to be resizable then set this to true. When enabled, there are resize handles between the header cells that you can grab to drag the columns left or right. If there are no column headers then your datagrid columns will not be resizable.
Default: false
Name: columnsResizablePersistent
Description: 
By default when you refresh the page the columns will return to their initial sizes. If you want the sizes to persist across page refreshes though you can set this to true. The sizing information is stored inside the browser in the window.localStorage variable.
Default: false
Name: columnsResizableHandles
Description: 
This property controls whether the resize handles (the vertical bars that sit between the columns in the header) appear or not. It should be an array of truthy or falsy values. If the relevant value is falsy then no resize handle is shown. For example, if your first column is checkboxes, radio buttons or an ID number for that row then you might not want the first resize handle to be shown.
Default: null
Name: columnsDescriptions
Description: 
This allows you to add an aria description to each of the column headers. These can help with assistive technologies and alternative browsing technologies.
Default: null

Sorting properties

Name: sortable
Description: 
Use this to enable column sorting. Click on a column to sort by that column in ascending order; click it again to sort in descending order and then click it again to return to the original, unsorted state.
Default: true
Name: sortablePersistent
Description: 
Use this to dictate whether sorting is persistent or not (ie it remains sorted despite any page refreshes).
Default: false
Name: sortableColumns
Description: 
This can be an array of column indexes (the indexing begins at zero) that dictate whether a column is sortable or not. So for example, if your first column is a checkbox that you don't want to be sortable you can specify something like this: [1,2,3,4,5,6]
Default: null
Name: sortableInitial
Description: 
This specifies the column that's used to initially sort the datagrid . This property overrides any column index that's stored in your browser's localStorage so if you change the ordering and refresh the page the sorting will revert to what's specified with this property.
Default: null
Name: sortableInitialDirection
Description: 
This property goes hand-in-hand with the above property and is used to give the direction of sorting. It can be either 1 (the default) for ascending or -1 for descending. It can also be 0 for no sorting.
Default: 1 (Ascending)
Name: sortableCompare
Description: 
This property allows you to specify your own, custom sort function. By doing this you can control exactly how you want the sorting to occur. An example of a sorting function that sorts by the last letter of the contents of the cell follows. This property can be a single function - which is used for every column - or it can be an array of functions - one per column. If you use an array you can leave an entry blank or null in the array so that the default sorting is used for that column.
// An example of a custom sort function which sorts
// the rows by the last character in the cell.
// Because an array encapsulates the function -
// this function will only be used for the first
// column. Normal sorting is used for the other
// columns.
// 
// @param object obj       The chart object
// @param number column    A number representing the column index
//                         (starts at zero).
// @param number direction The direction to be sorted in. 1
//                         means ascending and -1 means
//                         descending.
// @param mixed  a         The first value to compare.
// @param mixed  b         The second value to compare.
// 
sortableCompare: [function (obj, column, direction, a, b)
{
    a = a.substr(-1).charCodeAt(0);
    b = b.substr(-1).charCodeAt(0);

    return direction > 0 ? a - b : b - a;
}]
Default: null

Editable properties

Name: editable
Description: 
This determines whether the datagrid is editable or not. To edit a cell you can double-click on it. You can use the various datagrid events to perform an action when editing is either cancelled or completed (eg send that value back to the server with ajax). For example:
.on('editcomplete', function (obj)
{
    var meta = RGraph.Registry.get('cell-edit-meta');
    var data = obj.getData();
    
    console.log(data[meta.row]);
});
Default: false
Name: editableColumns
Description: 
If you want to limit editing to certain columns then this property allows you to do that. It can be an array of column indexes that are allowed to be edited - for example: [1,6] This would allow the second and seventh columns to be edited (remember that the indexing begins at zero). It can also be a string of column indexes that can be editable (remember the indexing starts at zero) - some examples:
  • 1-3 - The columns 1, 2 and 3 are editable.
  • 1- - The columns with an index of 1 or higher are editable.
  • -3 - The columns with an index of 3 or lower are editable.
  • 3 - The column with the index 3 is editable.
  • 1,2,3 - The columns with indexes 1, 2 or 3 are editable.
  • 0,1-3,4,5-6 - The columns with the indexes 1, 2, 3, 4, 5 or 6 are editable.
Default: null

Selectable rows properties

Name: rowsSelectable
Description: 
If you want the rows on your table to be selectable (by users simply clicking on the rows) then set this property to true. By making use of the rowsSelectable* properties you can easily incorporate the datagrid into a dynamic application. You'll most likely want to specify the property below as well.
Default: false
Name: rowsSelectableIds
Description: 
This property allows you to assign your own ids to the data. The order of the ids should correspond with the order of the data that you give to the datagrid. There are demos of this property in the download archive. In order for the selected rows to be persistent you must give this property.
Default: null
Name: rowsSelectablePersistent
Description: 
By setting this property to true the selected rows will be remembered across page refreshes. You must also provide your own ids with the rowSelectableIds property too for persistence to work.
Default: false
Name: rowsSelectableCount
Description: 
By setting this to a number greater than zero (the default) you can limit the number of items on the datagrid that can be selected at one time.
Default:  0

Miscellaneous properties

Name: style
Description: 
This allows you to add standard css styles to your datagrid such as this:
style: [
    'th:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}',
    'td:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}'
]
This property can either be a single string or an array of strings. As is shown in the example above, this doesn't have to be the full css selector - it will be modified with the id that you give to the constructor to limit the possibility of clashes. So the example above would be converted to look like this (assume that #myGrid is the id of your div tag):
style: [
    'div#myGrid table.rgraph-datagrid th:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}',
    'div#myGrid table.rgraph-datagrid td:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}'
]
Default: null
Name: description
Description: 
This property allows you to add an aria description to the datagrid. This aids people using assistive technologies - such as screen readers - to make more sense of the datagrid.
Default: null
Name: caption
Description: 
The caption property adds a standard caption tag to the datagrid. The caption can be styled with css and can be used in place of a title. The caption can sometimes be skipped by screen readers though so you may prefer to use a regular heading tag instead. (eg a standard h2 tag)
Default: null
Name: filter
Description: 
You can set this property to true to add a filter box to the top left of the datagrid. The filter is quite straightforward - just type into the text input and the rows that are displayed will be narrowed down to those that contain that text. The search is done in a case-insensitive manner and there's no regular expression search or boolean logic support.
Default: false

Methods

You can use these functions to do various things allowing you to control and manipulate the datagrid.

Name: mixed get(string name)
Description: 
An accessor that you can use to retrieve the values of properties.
Name: object set(string name, mixed value)
Description: 
An accessor that you can use to set the values of properties.
Name: array getData()
Description: 
An accessor that you can use to get all of the data in the datagrid. The raw data in the object is an array of objects that holds meta information as well as the data - so if you want to get the raw data you should use this method.
Name: array row(number index)
Description: 
This function returns the row of data as specified by the index that you give it. The index can be negative - in which case the counting begins from the end of the data and goes backwards. The row is returned taking into account the current sort settings. If the specified index doesn't exist then null is returned.
Name: array column(number index)
Description: 
This function returns you the column of data as specified by the index that you give it. The index can be negative - in which case the counting begins from the end of the data and goes backwards. The column is returned taking into account the current sort settings. If the specified index doesn't exist then null is returned.
Name: array setData(array data)
Description: 
An accessor that you can use to set the data on the object if you need to. This method takes the data and sets up the data structure that the datagrid code requires. Because of that, this method should be used to set the data instead of setting the data property directly. The return value is the data that you give the function.
Name: array getUnsortedData()
Description: 
As well as containing extra meta data the obj.data property won't necessarily be in the original, unsorted order. So if that's what you want you can use this method to get the original, unsorted data.
Name: number getOriginalIndex()
Description: 
This method is useful if you have sorting enabled on your datagrid. It does exactly as the name implies and returns you the original, unsorted index of the index that you give it.
Name: null resetData()
Description: 
This method resets the data back to its original, unsorted state. After doing this it fires the resetdata event.
Name: null append(array data)
Description: 
This method appends data onto the end of the datagrid. It gets appended onto the original, unsorted data and then the data is sorted again using the current sort settings. For this reason, a row that you append may not be added at the end of the datagrid. After doing this it fires the append event.
Name: null prepend(array data)
Description: 
Similar to the append method, this method adds the data to the start of the dataset. Again, your current sort settings are taken into account so your new data may not appear at the start of the dataset. When the function is finished the prepend event is fired.
Name: null insert(number index, array data)
Description: 
This method allows you to insert new data into the dataset at a point of your choosing (as given by the index argument). The new data should have the same number of items/columns as the existing data. The index argument is zero-indexed and can also be negative. In that case the counting starts at the end of the dataset and works backwards. When finished the method fires the insert event.
Name: null delete(number index)
Description: 
This method deletes a row of data from the dataset. It works on the unsorted data so if you delete the row with the index of zero it may not be the first row that you see that gets deleted (because of your current sort settings). Negative indexes can be given - in which case the counting starts from the end of the dataset. After deletion, the data is then sorted again using your current sort settings. After completion, the delete event is fired.
Name: array find(string query[,object options])
Description: 
The find function searches through the data for the search query that you give it. You can either give the function a string in which case the cell value has to match exactly or you can give it a Regular Expression which affords you a lot of flexibility in the search. Normally this function stops when it has found the first instance of the search query and returns but you can change this behaviour by passing an object as the second argument which has an all property set to true. Some examples:
obj.find('Jerry');              // Find the first instance of the word Jerry
obj.find('Jerry', {all: true}); // Find all instances of the word Jerry
obj.find(/^jer/i);              // Regular expression find
obj.find(/^jer/i, {all: true}); // Use a Regular expression and find all of the matches
By default, the return value is an object containing the row index (the row property), the column index (the column property) and the html table cell object (the element property). If you use the second argument to the function though to stipulate that all occurences of the search query should be found then the return value is an array with one element per match. Each element is an object with the same properties as the object returned when performing a single search.
Name: array findAll(string query)
Description: 
This is a convenience function that does exactly the same as the find function but with the difference that it returns all of the rows that contain the search query - not just the first one that it finds. You can use the find function for this or the findAll function - your choice.
obj.find('Jerry', {all: true}); // These two functions are the same
obj.findAll('Jerry');           // These two functions are the same
Name: null clear()
Description: 
This function clears the container div and essentially removes the datagrid from the document. It uses the modern and quick replaceChildren dom function to do this. It fires two events: the beforeclear at the start of the function before anything has been done and then the clear event after the container has been cleared of the datagrid.
Name: null redraw()
Description: 
This function does exactly what it says on the tin and removes the datagrid from the container div and then redraws it. It fires two events: the beforeredraw at the beginning of the call and the redraw event after the datagrid has been redrawn.
Name: null resetSortData()
Description: 
This function allows you to reset the sort data back to the default unsorted state.
Name: object exec(function function)
Name: object on(string event, function function)
Description: 
This method can be used to add an event listener to your object. It operates similarly to the jquery on function. The first argument is the event that you want to attach to and the second is the handler function. For example:
.on('draw', function (obj)
{
    // Put your code here. Depending on the event, you can sometimes
    // get meta information from the RGraph registry. See the list
    // of event types below for more detail.
});
Name: object parseCellIdentifier()
Description: 
This function takes a typical cell identifier as used by Google Sheets or Microsoft Excel - eg A2, C6, BC88) and converts it into the corresponding row index and cell index and returns them to you. The return value is an object with two properties - row and column.
Name: null select(number index)
Description: 
This method selects a row for you. The argument is the zero-indexed index of the row that you want to highlight. Visually, it applies the rgraph-datagrid-row-selected css class. By default, this turns the background color blue and the color white - like Windows does when selecting icons (for example). This method is only useful when the rowsSelectable property is enabled.
Name: null toggleSelected(number index)
Description: 
This method toggles the selected state of the desired row. The index that you give it is the zero-indexed index of the row. If the row isn't selected then it will be; and if it is selected then it will be deselected. This method is only useful when the rowsSelectable property is enabled.
Name: array getSelected()
Description: 
This method returns you an array of objects that represent the current state of the selected items. It returns to you an array of objects and each object has two properties - the current index in the datagrid (this can change when the datagrid is sorted) and the user-supplied id which can be given with the rowsSelectableIds property. This method is only useful when the rowsSelectable property is enabled.
Name: boolean isSelected(number index)
Description: 
This method returns a true or false value as to whether the row with the given index is currently selected or not. This method is only useful when the rowsSelectable property is enabled.
Name: null deselect(number index)
Description: 
This method deselects the row with the given index. If the row isn't currently selected it doesn't do anything. It removes the rgraph-datagrid-row-selected css class from the row in order to remove the blue/white selection coloring. This method is only useful when the rowsSelectable property is enabled.
Name: null deselectAll()
Description: 
This method is an easy way to remove the selected state from all of the rows in the datagrid. This method is only useful when the rowsSelectable property is enabled.

Events

These events are available to enable you to integrate your own code with the datagrid. You can use the on function to attach them to your chart as is shown in the example below.

<script>
    new RGraph.Datagrid({
        id: 'myGrid',
        ata: [
            ['15th March 2006',    'Jane',   19],
            ['8th August 2006',    'Freddy'],23,
            ['21st September 2006','Rod',    41],
            ['5th December 2006',  'Peter',  12],
            ['21st February 2007', 'Gary',   24],
            ['24th March 2007',    'Jamie',  37]
        ],
        options: {
            columnsHeaders: ['Date','Competitor','Score']
        }
    }).on('draw', function (obj) {
        alert('Hello!');
    }).draw();
</script>
Name: beforedraw
Description: 
This event fires at the start of the draw function - before it runs.
Name: firstdraw
Description: 
This event fires after the draw function runs - but only once. On subsequent draws, this event is not triggered.
Name: draw
Description: 
This event fires when the draw event has completed. If you attach some code to the draw event after you call the draw function then this code will not run straight away - because the draw function would have completed before you attach to the event.
Name: beforeredraw
Description: 
This event fires at the start of a call to the redraw function - before the redraw has happened.
Name: redraw
Description: 
This event fires at the end of a call to the redraw function - after the datagrid has been redrawn.
Name: beforeclear
Description: 
This event fires at the start of a call to the clear function - before the datagrid has been cleared.
Name: clear
Description: 
This event fires at the end of a call to the clear function - after the datagrid has been cleared.
Name: resetdata
Description: 
This event fires when the resetData function is called, which resets the data back to that which was initially given to the datagrid.
Name: beforesort
Description: 
This event is fired just before the datagrid data is sorted (by clicking on the headers to the columns).
Name: sort
Description: 
This event is fired just after the datagrid data is sorted (by clicking on the headers to the columns).
Name: append
Description: 
This event is fired at the end of the append method which is used to add data to the end of the datagrid.
Name: prepend
Description: 
This event is fired at the end of the prepend method which is used to add data to the start of the datagrid.
Name: insert
Description: 
This event is fired at the end of the insert method which is used to insert data into the datagrid (at some point).
Name: delete
Description: 
This event is fired at the end of the delete method which is used to remove data from the datagrid.
Name: rowclick
Description: 
This event is an easy way to add a click event listener to a row. You can't add the event listener to a specific row but what you can do is use the meta information that's provided to you to check the index of the row and act accordingly.
.on('rowclick', function (obj)
{
    var meta = RGraph.Registry.get('row-click-meta');

    var object  = meta.object; // The RGraph object
    var event   = meta.event;  // The standard event object
    var element = meta.element;// THe HTML element
    var html    = meta.html;   // The innerHTML of the row
    var row     = meta.row;    // The index of the row
    var value   = meta.value;  // All of the values of the row
})
Name: cellclick
Description: 
This event is an easy way to add a click event listener to a cell. You can't add the event listener to a specific cell but what you can do is use the meta information that's provided to you to check the index of the cell and act accordingly.
.on('cellclick', function (obj)
{
    var meta = RGraph.Registry.get('cell-click-meta');

    var object  = meta.object; // The RGraph object
    var event   = meta.event;  // The standard event object
    var element = meta.element;// THe HTML element
    var html    = meta.html;   // The innerHTML of the cell
    var row     = meta.row;    // The index of the row
    var column  = meta.column; // The index of the column
    var value   = meta.value;  // The value of the cell
})
Name: beforeedit
Description: 
This event is fired at the start of when you edit a cell. There's meta information available to you in the RGraph Registry and that is:
.on('beforeedit', function (obj)
{
    var meta = RGraph.Registry.get('cell-edit-meta');

    var object  = meta.object; // The RGraph object
    var value   = meta.value;  // The value of the cell
    var cell    = meta.cell;   // The HTML  cell
    var row     = meta.row;    // The index of the row
    var column  = meta.column; // The index of the column
})
Name: beforeeditsave
Description: 
This event fires just before the cell that you've been editing is saved. There's meta information available to you and that is as follows:
.on('beforeedit', function (obj)
{
    var meta = RGraph.Registry.get('cell-edit-meta');

    var object  = meta.object; // The RGraph object
    var value   = meta.value;  // The value of the cell that's about to be saved
    var cell    = meta.cell;   // The HTML  cell
    var row     = meta.row;    // The index of the row
    var column  = meta.column; // The index of the column
})
Name: aftereditsave
Description: 
This event fires right after an edit to a cell that you've made has been saved. The meta information that's available to you is the same as the beforeeditsave event:
.on('afteredit', function (obj)
{
    var meta = RGraph.Registry.get('cell-edit-meta');

    var object  = meta.object; // The RGraph object
    var value   = meta.value;  // The value of the cell that's about to be saved
    var cell    = meta.cell;   // The HTML  cell
    var row     = meta.row;    // The index of the row
    var column  = meta.column; // The index of the column
})
Note that if you want the before and after values of the cell you can use this event and the beforeedit event.
Name: editcomplete
Description: 
This event is fired when the edit is complete. It's much the same as the aftereditsave event.
Name: editcancelled
Description: 
This event is fired when the edit is cancelled by pressing the Esc key. The same meta information as the beforeeditsave and aftereditsave events is available.
.on('editcancelled', function (obj)
{
    var meta = RGraph.Registry.get('cell-edit-meta');

    var object  = meta.object; // The RGraph object
    var value   = meta.value;  // The value of the cell that's about to be saved
    var cell    = meta.cell;   // The HTML  cell
    var row     = meta.row;    // The index of the row
    var column  = meta.column; // The index of the column
})
Name: resizebegin
Description: 
When resizable columns are enabled using the columnsResizable property this event fires when resizing begins. This is when you initially click on the column resize handle in the columns header bar. Obviously, if you don't have the columnsHeaders property in your config then you won't see the resize handles and thus won't be able to resize the columns.
Name: resize
Description: 
This event fires every time the columns are resized. In practice, this means that once you've clicked on the resize handle the resizebegin event fires and also when you move your mouse left or right to resize the column.
Name: resizeend
Description: 
This event will fire when you release the mouse button after you've finished resizing a column. Much like the mouseup event.

Customising the datagrid with CSS

At its most basic level, the datagrid is an html table utilising standard tags. You can see the structure in the FAQ question below. This means that you can use standard css selectors to change the way that things look to the user. For example:

<style>
    /*
    * Remember that you may need to use the !important modifier
    * if you're overriding the default styles.
    */
    div#myGrid table.rgraph-datagrid tr.rgraph-datagrid-row-hover {
        background-color: #00f1 !important;
    }




    /*
    * If you have multiple datagrids on a page then you can also do
    * this to provide the row highlighting for all of them in one
    * go.
    */
    .rgraph-datagrid-row-hover {
        background-color: #00f1 !important;
    }
</style>

Or if you want to highlight a particular row you can make use of the css nth-child pseudo-selector like this:

<style>
        /* Highlight the third row (in CSS the counting begins at 1) */
        div#myGrid table.rgraph-datagrid tr:nth-child(3) {
            background-color: yellow !important;
        }
    </style>

Using the style property to set CSS

As well as setting your css the normal way - using style html tags - you can also use the style property of the datagrid. Here's an example:

style: [
    'tr:nth-child(2) td:nth-child(2):hover {color: red; font-weight: bold;}',
    // ...
],

You shouldn't worry too much about naming clashes though because, if not present, the rule is made more specific by adding the id of the div tag to it. So the above rule is actually transformed into the following:

style: [
    'div#myGrid table.rgraph-datagrid tr:nth-child(2) td:nth-child(2):hover {color: red; font-weight: bold;}',
    // ...
],

Integrating the datagrid with forms

Integrating the datagrid with a form on your webpage can make it very useful when presenting the user with a choice and getting an answer from them. Consider the following example:

This is the html code for this datagrid. Notice that it sits within a form tag and there's a submit button just below where the datagrid will be rendered.

<form action="datagrid.html" method="post">
    <div style="margin-left: auto; margin-right: auto; width: 600px">
        <div style="width: 600px" id="myGrid"></div>
        <input type="submit" name="submit" value="Update" style="font-size: 20pt; cursor: pointer"/>
    </div>
</form>

And here's the code for the datagrid. Notice that the columnsHTML option has been given and is set to an array that contains just one number - 0 This means that the first column (the numbering begins at zero) is allowed to have html in it. So a checkbox will be shown and not the html tag for the checkbox.

<script>
    data = [
        ['<input type="checkbox" name="players[]" value="15" style="transform: scale(1.5)" />', 'Mary','1st October 1985','Winner by default'],
        ['<input type="checkbox" name="players[]" value="2" style="transform: scale(1.5)" />', 'Freddy','27th July 1980','3rd place - runner up'],
        ['<input type="checkbox" name="players[]" value="43" style="transform: scale(1.5)" />', 'Jamie','6th March 1967','2nd place - finalist'],
        ['<input type="checkbox" name="players[]" value="21" style="transform: scale(1.5)" />', 'Gary','7th April 1982','1st place - winner'],
    ];
    myGrid = new RGraph.Datagrid({
        id: 'myGrid',
        data: data,
        options: {
            columnsHeaders: ['', 'Person','Date of event','Final position'],
            columnsHTML: [0],
            columnsWidths: [30],
            sortable: false
        }
    }).draw();

    /////////////////////////////////////////////////////////////
    // The following code is OPTIONAL - it allows you to click //
    // the entire row to select and unselect the checkbox as   //
    // well as the checkbox itself.                            //
    /////////////////////////////////////////////////////////////

    //(function ()
    //{
    //    // 
    //    // Get all of the rows in the datagrid and add click event
    //    // listeners that check the checkbox in that row.
    //    //
    //    var els  = document.querySelectorAll('div#myGrid1 table tbody tr');
    //   
    //    for (var i=0; i<els.length; ++i) {
    //   
    //        els[i].addEventListener('click', function (e)
    //        {
    //            var tr    = e.currentTarget;
    //            var input = tr.querySelector('input[type=checkbox]');
    //       
    //            input.checked = !input.checked;
    //        }, false);
    //   
    //        //
    //        // If the checkbox is clicked on directly - cancel any
    //        // propagation up the event tree.
    //        //
    //        var el  = els[i].querySelector('input[type=checkbox]');
    //        
    //        el.addEventListener('click', function (e)
    //        {
    //            e.stopPropagation();
    //        }, false);
    //    }
    //})();
</script>

But what if you didn't want the first column to have the same styling as the rest of the table? Well, you could do that with a snippet of css, utilising the nth-child pseudo-selector and moving the submit button to the right a small amount accordingly - so that it lines up with, what is now, the main table. Here's the updated example along with the necessary css code:

The necessary css markup:

<style>
    div#myGrid-container input[type=submit]{
        margin-left: 30px;
    }

    div#myGrid input[type=checkbox] {
        cursor: pointer;
    }
    
    div#myGrid th:nth-child(1n+2) {
        background-color: black !important;
        color: white !important;
    }
    
    div#myGrid thead th:nth-child(1),
    div#myGrid tbody td:nth-child(1) {
        background-color: white !important;
    }
    
    div#myGrid thead th:nth-child(1) div,
    div#myGrid tbody td:nth-child(1) div {
        border: none !important;
    }
</style>

The html markup and the javascript code is the same as the example above - so you can use that.

Adding a "select all" button to your datagrid

If you're adding checkboxes to your datagrid then one thing that you may want is an easy way for your users to check all of those checkboxes at once. This is quite easy and just requires a little javascript function like this:

<script>
    //
    // A function that facilitates the easy selection of all of
    // the checkboxes on the datagrid in one go.
    //
    function selectAll ()
    {
        var checkboxes = document.querySelectorAll('div#myGrid input[type=checkbox]');
        
        checkboxes.forEach((value,key,array) =>
        {
            value.checked = !window.allCheckboxesCheckedState;
        });
        
        window.allCheckboxesCheckedState = !window.allCheckboxesCheckedState;
    }
</script>

<button onclick="selectAll()">Select all</button>

Frequently asked questions

What is the structure of the resulting table?

The RGraph datagrid produces a standard html table element with the following structure:

<div id="myGrid">
    <table class="rgraph-datagrid">
        
        <!-- Column headers -->
        <thead>
            <tr>
                <th><div class="rgraph-datagrid-cell-content">Name</div></th>
                <th><div class="rgraph-datagrid-cell-content">Day</div></th>
                <th><div class="rgraph-datagrid-cell-content">Amount</div></th>
            </tr>
        </thead>
        
        <!-- Data rows -->
        <tbody>
        
            <!-- First row -->
            <tr>
                <td><div class="rgraph-datagrid-cell-content">Richard</div></td>
                <td><div class="rgraph-datagrid-cell-content">Monday</div></td>
                <td><div class="rgraph-datagrid-cell-content">23</div></td>
            </tr>

            <!-- Second row -->
            <tr>
                <td><div class="rgraph-datagrid-cell-content">David</div></td>
                <td><div class="rgraph-datagrid-cell-content">Tuesday</div></td>
                <td><div class="rgraph-datagrid-cell-content">46</div></td>
            </tr>
        </tbody>
        
        <!-- Column footers -->
        <tfoot>
            <tr>
                <td><div class="rgraph-datagrid-cell-content"></div></td>
                <td><div class="rgraph-datagrid-cell-content"></div></td>
                <td><div class="rgraph-datagrid-cell-content"></div></td>
            </tr>
        </tfoot>
    </table>
</div>

How do I make the rows highlighted when they're hovered over?

You can do this by adding a small bit of css to your page. To be specific to a single datagrid you could add this:

<style>
    /* Add row highlighting to a single datagrid */
    div#myGrid table.rgraph-datagrid tr.rgraph-datagrid-row-hover {
        background-color: #00f1 !important;
    }
</style>

Or to add row highlighting to all of the datagrid instances on the page you can use a css: selector that's a broader match like this:

<style>
    /* Add row highlighting to all of the datagrids on the page */
    .rgraph-datagrid-row-hover {
        background-color: #00f1 !important;
    }
</style>

How can I add scrolling to my datagrid?

If you have a lot of data that you want to show in the datagrid but don't want it to take up a large amount of vertical space then there is something that you can do and that's to add scrolling to the datagrid body. This is demonstrated by the datagrid that's shown above and you can also see a demo in the download archive. It's done by adding a small amount of css to your page and that is as follows:

<style>
    div#myGrid table.rgraph-datagrid {
        display: block;
    }

    div#myGrid table.rgraph-datagrid tbody {
        max-height: 150px;
        overflow-x:hidden;
        overflow-y:auto;
        display: block;
        width: 100%;
    }
</style>

How do I hide the ID column on my grid?

What if you have a set of data and the first column is an id that perhaps is coming from your database? Maybe it's just not practical to not select that column in the first place but you don't want that information displayed to the user. Well instead of messing with the data you can just hide that column with a little css. Here's the datagrid before the css has been applied with the id column still visible.

And here's the css that hides the first column. It also centers the datagrid in its container (there's a tiny bit of space left on either side and this is because of the now missing column).

<style>
    div#myGrid table {
        margin-left: auto;
        margin-right: auto;
    }

    div#myGrid table.rgraph-datagrid tr :where(th, td):nth-child(1) {
        display: none;
    }
</style>

And here's the resulting datagrid which has now got the first column hidden.

<script>
        myGrid6 = new RGraph.Datagrid({
            id: 'myGrid6',
            data: [
                [435, 'Richard','Web developer',25000],
                [884, 'Jane', 'Customer Service Operative',18000],
                [463,'Martha','Sales executive',23000],
                [135,'Janet','Office admin',21000]
            ],
            options: {
                columnsHeaders: ['','Name','Occupation','Salary'],
                
                // Reduce the size of the first column
                columnsWidths: [5],
                
                style: [
                    // Center the datagrid in its div
                    'table {margin-left: auto;margin-right: auto;}',
                    
                    // Hide the first column (which has the ID numbers in)
                    'tr :where(td, th):nth-child(1) {display: none;}'
                    
                    'tr th div {background-color: black; color: white;}',
                    'tr th span {color: white;}'
                ]
            }
        }).draw();
    </script>

How do I make my checkboxes toggle when the row is clicked?

The datagrid example that's shown above shows you how to do this and has an example of the necessary code beneath the datagrid. The commented-out code (in green) is the javascript that's necessary to add to your page.