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 HTML datagrid
In the April 2025 release a new datagrid object was 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.22, 24th June 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 rowsSelectable* properties have been removed. A perfectly usable alternative is to use a checkbox or radio button in each row of your datagrid. This is discussed in the Integrating the datagrid with forms section below.

The datagrid component is new to RGraph in version 6.21 and is an 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, paging and a search function 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.datagrid.js" ></script>

<div style="width: 75%;margin-left: auto; margin-right: auto">
    <div id="myGrid"></div></div>
    <button onclick="myGrid.resetColumnWidths()" style="cursor: pointer; font-size: 20pt">Reset column sizes</button></button>
</div>

<script>
    data = [
        ['2001-01-02', 'Richard', 'Monday',       124],
        ['2004-10-11', 'Jane',    'Tuesday',      152],
        ['2003-02-28', 'Lucy',    'Wednesday',    98],
        ['2003-03-29', 'Jerry',   'Thursday',     95],
        ['2009-08-25', 'Alex',    'Friday',       103],
        ['2003-08-26', 'Freddy',  'Saturday',     311],
        ['2012-03-26', 'Kev',     'Monday',       112],
        ['2005-05-26', 'Mo',      'Thursday',     321],
        ['2007-01-26', 'Joe',     'Tuesday',      477],
        ['2006-05-26', 'Neil',    'Sunday',       233],
        ['2009-07-26', 'Bill',    'Monday',       633],
        ['2003-09-26', 'Hoolio',  'Wednesday',    122],
        ['2012-02-26', 'Vera',    'Friday',       466],
        ['2011-06-26', 'Luis',   'Tuesday',       355],
        ['2001-04-26', 'Fay',    'Thursday',      255],
        ['2000-02-26', 'Doug',   'Monday',        844],
        ['2015-03-26', 'Mo',     'Friday',        433],
        ['2010-06-26', 'Ben',    'Sunday',        748],
        ['2013-05-26', 'Kevin',  'Monday',        354],
        ['2010-02-26', 'Chloe',  'Thursday',      956],
        ['2008-08-26', 'Sammy',  'Sunday',        445],
        ['2006-11-26', 'Flo',    'Wednesday',     122],
        ['2003-06-26', 'Gill',   'Friday',        656],
        ['2004-12-26', 'Zak',    'Saturday',      321],
        ['2006-03-13', 'Peter',  'Tuesday',       56]
    ];
    
    myGrid = new RGraph.Datagrid({
        id: 'myGrid',
        data: data,
        options: {
            pagingPerPage: 10,
            columnsHeaders: ['Date','Name','Day of week','Amount'],
            columnsFooters: ['','',''],
            columnsResizable: true,
            columnsResizablePersistent: true,
            columnsUnitsPre: ['','','','&amp;pound;'],
            columnsHTML: 3,
            columnsFormatted: [0,3],
            columnsFormatter:[function (opt)
            {
                return RGraph.PHP.date('jS F Y', RGraph.parseDate(opt.value, 's'));
            }],
            search: true,
            style: [
                'table tbody tr td:nth-child(4) {font-weight: bold;}'
            ]
        }
    }).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.

Row properties

Name: rowsIDs
Description: 
If you want to be able to assign your own ID values to rows then you can do so with this property. These values are passed to various events (for example cellclick rowclick beforeedit beforeeditsave aftereditsave editcomplete) via the meta information that that is given to the event listener function (see the events section below). You can also get the meta information from the RGraph registry and you can do that like this: var meta = RGraph.Registry.get('row-click-meta'); or var meta = RGraph.Registry.get('cell-click-meta'); The IDs can then be passed to your server-side scripts to manipulate the rows as you see fit.
Default: null
Name: rowsClickCheckbox
Description: 
This is a convenience property that might make your life easier. If you have a checkbox in your data , in the first column perhaps, used so that your users can specify a particular row and then submit a form accordingly, if you specify this property the datagrid will automatically check the checkbox for you. There's an example below that shows this property in action.
Default: false
Name: rowsClickCheckboxIndex
Description: 
If you use the property above to have a checkbox checked when a row is clicked what happens if you have two checkboxes in your row? Which one is checked? That's when this property comes in handy. You can use it to specify which checkbox is checked and you do so by giving the index of the checkbox to this property. The numbering starts at zero, so the first checkbox is zero and that's the default value for this property. This property can also be an array of indexes if you want multiple checkboxes checked.
Default: ‌0
Name: rowsClickRadio
Description: 
Like the rowsClickCheckbox property above, this is similar but for radio buttons. If you have a radio button in your data - in the first column perhaps - used so that your users can specify a particular row and then submit a form accordingly, if you specify this property the datagrid will automatically check the radio button for you when the row is clicked.
Default: false
Name: rowsClickRadioIndex
Description: 
If you use the property above to have a radio button checked when a row is clicked, what happens if you have two radio buttons in your row? Which one is checked? That's when this property comes in handy. You can use it to specify which radio button is checked and you do so by giving the index of the radio button to this property. The numbering starts at zero, so the first radio button is zero - and that's the default value for this property. This property can also be an array of indexes if you want multiple radio buttons checked.
Default: ‌0

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. You also need to put the column index(es) in the columnsFormatted property. This column can be a range of column indexes. For example:
columnsHTML: '2-4',
columnsFormatted: '2-4',
Default: null
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 th and td tags which have the corresponding column index.
Default: null
Name: columnsFormatted
Description: 
This determines whether columns have numerical formatting applied to them. For example, if you were to have the value 12e88 in your column it will actually be changed to 1.2e+89 when formatting it to appear as a number. By default, everything is treated as a string so you see exactly what's in your data array. This column can be a range of column indexes.
Default: false
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>). This property can be both a string and an array (one value for each corresponding column).
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>). This property can be both a string and an array (one value for each corresponding column).
Default: [an empty string]
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. This property can be both a string and an array (one value for each corresponding column).
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. This property can be both a string and an array (one value for each corresponding column).
Default: ,
Name: columnsDecimals
Description: 
When numbers are formatted for display, this is how many decimal characters that are displayed. This property can be both a number and an array (one value for each corresponding column).
Default:  0
Name: columnsFormatter
Description: 
For numerical columns 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 metadata. It should return the relevant string to show to the user. This can be either 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]
For textual columns you can still specify this property, though the argument is a little different. It's still an object but has just four properties - the datagrid object, the row index, the column index and the value. Using this function allows you to set a formatter function for a textual column, such as a timestamp, that you wish to format into a presentable date (which you can easily do with the RGraph.parseDate and RGraph.PHP.date functions or the RGraph.common.moment.js library that's included in the RGraph archive). For example, you might have a timestamp that comes from your database and looks like this: 2006-05-01 15:12:03 so using the columsFormatter property, you could do this:
columnsFormatter: [function (opt)
{
   // opt.object - The datagrid object
   // opt.value  - The value in the cell
   // opt.column - The index of the column
   // opt.row    - The index of the row

   // REMEMBER: The RGraph.parseDate function returns a timestamp
   // in milliseconds by default, so you must specify the second
   // argument to get a value in seconds which you can then pass
   // to the RGraph.PHP.date function.
    var timestamp = RGraph.parseDate(opt.value,'s');
    
   // The desired format: 23:03 March 5th 2006
    return RGraph.PHP.date('H:i F jS Y', timestamp);
}]
Or using the moment.js library you coud also do this:
columnsFormatter: [function (opt)
{
   // opt.object - The datagrid object
   // opt.value  - The value in the cell
   // opt.column - The index of the column
   // opt.row    - The index of the row

    return moment(opt.value).format("HH:MM MMMM Do YYYY");
}]
And that means that the unfriendly looking timestamps now look like this:
23:03 March 5th 2006
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 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 falsey values. If the relevant value is falsey 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. This column can be a range of column indexes.
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 header 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 maintains its sorted state despite any page refreshes).
Default: false
Name: sortableColumns
Description: 
This property can be a range of column indexes 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-' This column can be a range of column indexes.
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

Search properties

Name: search
Description: 
You can set this property to true to add a search box to the top-left of the datagrid. Read more about the search feature here.
Default: false
Name: searchPlaceholder
Description: 
This is the text used as the search input placeholder text (what you see in the search box before you've typed anything).
Default: Search...
Name: searchFocus
Description: 
By default, the search input doesn't have focus when the datagrid loads. If you want this to happen though, you can set this property to true.

Note: If your datagrid is below the height of the browsers viewport setting this property to true can make the window jump to the datagrid when the page loads.

Default: false
Name: searchExclude
Description: 
This can be a range of column indexes that you don't wish to be included in a search (for example, you might have a checkbox or radio button in the first column of your datagrid). The column numbers are zero-indexed - meaning that the numbering starts at zero and the first column is zero. This column can be a range of column indexes.
Default: null
Name: searchUrlUpdate
Description: 
By setting this to true you can make the datagrid update the url when a search is performed. This allows you to employ server-based searching (useful if you have a large dataset or are using server-based paging and only showing a portion of the entire dataset). Any existing querystring parameters and/or the anchor are preserved in the links.
Default: false
Name: searchUrlQueryStringParameter
Description: 
This is the name of the querystring parameter that's used to pass the search query to the server. For example, if you only have a single datagrid on your page then you may want to change this to something shorter like search
Default: datagrid-[id]-search
Name: searchUrlAnchor
Description: 
If you want to go to a specific anchor when searching, you can specify it with this property. This can be different for each datagrid on the page. By default, this option is empty and no anchor is added to the url.
Default: [an empty string]
Name: searchUrlRandom
Description: 
To try and avoid any caching peculiarities RGraph can add a random querystring parameter (a random number) to the urls that are generated. By default, the name of this parameter is blank and thus it's not used. You can change it, though, with this option and set the name to something shorter, like r
Default: [an empty string]

Paging properties

Name: paging
Description: 
A simple true or false value that determines whether you see paging on your datagrid or not. Paging can be useful for larger datasets but if your dataset is really big then you may want to consider doing the paging on your server instead to avoid transferring large amounts of data to the client (that, possibly, may be entirely redundant as your users may not even be interested in looking through all of the results).
Default: true
Name: pagingPerPage
Description: 
Use this property to set the number of results that you see on one page. Obviously, the higher this number is, the fewer pages will be needed to show your dataset. But if you set it too high, you risk overwhelming the user with data!
Default: 25
Name: pagingCurrent
Description: 
This is the current page that's shown to the user. If you wish to start on a page other than one, then you can do so by simply setting this to the desired page number.
Default: 1
Name: pagingMaxpagelinks
Description: 
This determines the maximum number of page links that are shown. It should be a number that is 3 or higher. An odd number is preferred, but not required.
Default: 7
Name: pagingPersistent
Description: 
This controls whether the current page that you're viewing is made to be persistent across page refreshes by storing the current page number in the window.localStorage area in the browser.
Default: false
Name: pagingPosition
Description: 
This can be one of two values: top or bottom and determines where the paging controls sit.
Default: top
Name: pagingLabel
Description: 
This can be used to set the label which is placed on the left side of the page numbers. It can be blank if you don't want there to be a label.
Default: Page:
Name: pagingUrlUpdate
Description: 
By setting this to true you can make the datagrid update the url when the paging links are clicked. This does mean that another page request to your server is incurred, however, it also means that the url in the address bar is updated whenever you change the page. This makes it much easier for you to use the url to link to a specific page in the datagrid (you can just copy the url in your browsers address bar and use that). Any existing querystring parameters and/or the anchor are preserved in the links.
Default: false
Name: pagingUrlQueryStringParameter
Description: 
This is the name of the querystring parameter that's used to convey the page number. Simply add this into your url (eg myPage.html?datagrid-myGrid-page=4) and the page of the datagrid will be set to whatever number that you specify (4 in this case). Be careful of caching when you add this property to your object.
Default: datagrid-[id]-page
Name: pagingUrlAnchor
Description: 
If you want to go to a specific anchor when changing the page, you can specify it with this property. This can be different for each datagrid on the page. By default, this option is empty and no anchor is added to the url.
Default: [an empty string]
Name: pagingUrlRandom
Description: 
To try and avoid any caching peculiarities RGraph can add a random querystring parameter (a random number) to the urls that are generated. By default, this is blank and therefore not used. You can change this though, with this option.
Default: [an empty string]

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 the new value back to the server with ajax). For example:
events: {
   // This event fires just before the new data is to be saved.
   // You can use the event to check the data and reject it if
   // necessary. To reject the edit, you can set the
   // meta.cancelEdit property (as shown below) and
   // the edit will not be saved.
   // 
   // If you do this you'll probably want to also show a message
   // to the user telling them why their edit was rejected - you
   // can do this with a simple JavaScript alert() dialog or
   // perhaps with the ModalDialog that's bundled with RGraph.
   // The demos/datagrid-editable.html demo shows an example
   // of using the ModalDialog to tell the user their edit was
   // rejected.
    beforeeditsave: function (obj, meta)
    {
       // Verify the new data if necessary and either accept it
       // (do nothing) or set the meta.cancelEdit property to
       // reject it.
       // 
       // meta.cancelEdit = true;
    },
    
   // This event fires at the end of the edit when the new
   // data has been saved.
    editcomplete: function (obj, 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. This property can be a range of column indexes.
Default: null

Miscellaneous properties

Name: style
Description: 
Important! It's crucial that you're specific when setting your CSS rules - specificity matters! Not being specific enough can cause your CSS not to be applied and leave you scratching your head for a very long time! The datagrid will add the ID of the DIV tag (the same as what you give to the constructor) to the rule so you don't need to add this. Following this guidance will lead to fewer head-scratching moments!
This property allows you to add standard CSS styles to your datagrid, such as this:
style: [
    'table thead tr th:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}',
    'table tbody tr td:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}'
]
It can be either a single string or an array of strings. 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 thead th:nth-child(2) {font-weight: bold; color: red;background-color: #ddd;}',
    'div#myGrid table tbody 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: events
Description: 
This property is now (since version 6.22) the preferred way to add events to your datagrid object. You can see an example of how to use this property below.
Default: {} (an empty object)

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 hold metadata as well as the data - so if you want to get the data as a regular array, 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 metadata 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(number index)
Description: 
This method is useful if you have sorting enabled on your datagrid. It does exactly as the name implies and returns to 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 occurrences 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: 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: 
Note: Since version 6.22 there's now an events property which you can use to add events to your datagrid object. This is now the preferred way to add events. Read a bit more and see an example here.
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 metadata passed as the second argument to the function
   // (or you can also get it from 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.

Events

These events are available to help you to integrate the datagrid into your website. You can add them to your datagrid by using the events property just like other RGraph objects, as shown below. Some of the events are passed metadata as the second argument that you can use to determine how to act in the event listener. The events that support this are noted below.

<script>
    new RGraph.Datagrid({
        id: 'myGrid',
        data: [
            ['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'],
            
            events: {
                draw:       function (obj) {alert('The datagrid was drawn!');},
                rowclick:   function (obj, meta) {alert('A row was clicked!');},
                cellclick:  function (obj, meta) {alert('A cell was clicked!');}
            }
        }
    }).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. This can prevent unwanted loops from occurring that you might get if you were to use the draw event..
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 that 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. There's meta information available which is passed to your event listener function as the second argument. It's an object which has two properties: object and data (the row of new data).
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. There's meta information available which is passed to your event listener function as the second argument. It's an object which has two properties: object and data (the row of new data).
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). There's meta information available which is passed to your event listener function as the second argument. It's an object which has two properties: object and data (the row of new data).
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 (using the row property)and act accordingly.
events: {
    rowclick: function (obj, meta)
    {    
        var object  = meta.object;  // The RGraph object
        var event   = meta.event;   // The standard event object
        var data    = meta.data;    // All of the values in the row
        var element = meta.element; // THe HTML <tr> element
        var html    = meta.html;    // The innerHTML of the row
        var row     = meta.row;     // The index of the row
        var id      = meta.user_id; // The user ID which you can assign to the row with
                                    // the rowsIDs property
    }
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 row and column (using the row and column properties) and act accordingly.
events: {
    cellclick: function (obj, meta)
    {    
        var object  = meta.object;  // The RGraph object
        var event   = meta.event;   // The standard event object
        var data    = meta.data;    // The row of data
        var element = meta.element; // THe HTML <td>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
        var user_id = meta.user_id; // The user ID which you can assign to the row with
                                    // the rowsIDs property
    }
}
Name: beforeedit
Description: 
This event is fired at the start of when you edit a cell. There's meta information available to you that's passed to your listener function as the second argument and that is:
events: {
    beforeedit: function (obj, 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
        var user_id = meta.user_id;// The ID of the row if one has been assigned
                                   // with the rowsIDs property.
    }
}
Name: beforeeditsave
Description: 
This event fires just before the cell that you've been editing is saved. There's meta information available to you that's passed to your listener function as the second argument and an example of that follows.

Note: If you want to validate the edit before it's saved and (potentially) reject it, you can use this event to perform the validation. You can then do nothing and the edit will be saved or you can set the property meta.cancelEdit to true (as shown below) and the edit won't be saved. You can then show a message to the user telling them that the edit was rejected (for whatever reason).

  
events: {
    beforeeditsave: function (obj, meta)
    {
        var object   = meta.object;        // The RGraph object
        var original = meta.original_value;// The original value of the cell
        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
        var user_id  = meta.user_id;       // The ID of the row if one has been assigned
                                           // with the rowsIDs property.

       // Set this to true if you want to cancel/reject the edit
       // meta.cancelEdit = true;
    }
}
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 and it's passed to your listener function as the second argument:
events: {
    aftereditsave: function (obj, meta)
    {
        var object   = meta.object;        // The RGraph object
        var original = meta.original_value;// The original value of the cell
        var value    = meta.value;         // The new 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
        var user_id  = meta.user_id;       // The ID of the row if one has been assigned
                                           // with the rowsIDs property.
    }
}
Note that if you want the before and after values of the cell, you can use both this event and the beforeedit event.
Name: editcomplete
Description: 
This event is fired when the edit is complete. It's very similar in practice to the aftereditsave event.

Note: The edit will only be saved within the browser - if you refresh the page it will be lost. If you want to save it permanently you will need to send the edit back to your server using ajax. You can read more about the RGraph AJAX functions here. You can then use your server-side scripts to save the edit to disk (or update a database).

events: {
    editcomplete: function (obj, meta)
    {
        var object   = meta.object;        // The RGraph object
        var value    = meta.value;         // The new value of the cell
        var original = meta.original_value;// The original 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
        var user_id  = meta.user_id;       // The ID of the row if one has been assigned
                                           // with the rowsIDs property.
    }
}
Name: editcancelled
Description: 
This event is fired when the edit is cancelled by pressing the Esc key. Similar metadata as the beforeeditsave and aftereditsave events is available.
events: {
    editcancelled: function (obj, meta)
    {    
        var object  = meta.object;  // The RGraph object
        var value   = meta.value;   // The original value of the cell that was being edited
        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
        var user_id = meta.user_id; // The ID of the row if one has been assigned
                                    // with the rowsIDs property.
    }
}
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 column header bar. Obviously, if you don't have the columnsHeaders property in your configuration, 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 then, when you move your mouse left or right (to resize the column), this event fires.
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.

Searching the datagrid

If you enable the search feature, you'll be able to search the contents of the datagrid. There will be a search input above the datagrid into which you can enter one or more terms that you wish to search for. You can then press enter and the results that you see will be filtered to those that contain the search term.

There are two main styles of search:

  1. The first is a plain text search. You can enter a search like this: ora Or you can use multiple words like this: jul ora It's case-insensitive, so you can enter uppercase or lowercase letters and it won't matter. You can enter multiple words to narrow down the search and the only rows that are displayed will be those that contain all of the words. You can also use basic wildcards as part of your word(s)and these are:
    • * (asterisk) Use this to represent any number of characters.
    • ? (question mark) Use this to represent a single character.
  2. The second type of search is an advanced regular expression search. The syntax of a regular expression search is important so this may only be useful if you already know how to use regular expressions. The style of the regular expression is the same as normal javascript, though the only modifier that's supported is the i (case-insensitivity) modifier. Otherwise, the regular expression can be just like a normal javascript regular expression. You can mix and match regular expressions with normal words. You can learn more about regular expressions at the Mozilla Developer Network page.

Some examples of searches include:

Editing the datagrid

You can set the datagrid values to be editable if you wish by setting the editable property to true This gives you a good quality interface to show data from your database and let your users edit it (either all of the columns it or just certain columns).

There are events available that help with this and these are:

These events are documented above in the events section but the most useful is the beforeeditsave event. This allows you to verify the data as you wish and optionally set the meta.cancelEdit property to reject the edit. If you don't set this property the edit will be accepted.

Customising the datagrid with CSS

Important! It's crucial that you're specific when setting your CSS rules - specificity matters! Not being specific enough can cause your CSS not to be applied and leave you scratching your head for a very long time! The datagrid will add the ID of the DIV tag (the same as what you give to the constructor) to the rule so you don't need to add this. Following this guidance will lead to fewer head-scratching moments!

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 tbody tr.rgraph-datagrid-row-hover {
        background-color: #00f1;
    }




    /*
    * If you have two (or more) datagrids on a page, you can also do
    * this to provide the row highlighting for both of them in one
    * go.
    */
    div:is(#myGrid, #myGrid2) table tbody tr.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) */
    table tbody tr:nth-child(3) {
        background-color: yellow ;
    }
</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:

<script>
    new RGraph.Datagrid({
        id: 'myGrid',
        data: [
            [324, 'Richard', 'Web developer'],
            [435, 'Dave', 'Customer Services'],
            [112, 'Charles', 'Manager'],
            [698, 'Freddy', 'Driver'],
        ],
        options: {
            style: [
                'table tbody tr:nth-child(2) td:nth-child(2):hover div {color: red; font-weight: bold;}'
            ]
        }
    }).draw();
</script>

The rule is made a little bit more specific at runtime, specific to a single datagrid, by adding the ID of the div tag to it. So the above rule is actually transformed into the following:

<script>
    new RGraph.Datagrid({
        id: 'myGrid',
        data: [
            [324, 'Richard', 'Web developer'],
            [435, 'Dave', 'Customer Services'],
            [112, 'Charles', 'Manager'],
            [698, 'Freddy', 'Driver'],
        ],
        options: {
            style: [
                'div#myGrid table tbody tr:nth-child(2) td:nth-child(2):hover div {color: red; font-weight: bold;}'
            ]
        }
    }).draw();
</script>

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,
            rowsClickCheckbox: true
        }
    }).draw();
</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 table thead tr th:nth-child(1n+2) {
        background-color: black;
        color: white !important;
    }
    
    div#myGrid table thead tr th:nth-child(1),
    div#myGrid table tbody tr td:nth-child(1) {
        background-color: white;
    }
    
    div#myGrid table thead tr th:nth-child(1) div {
        border: none;
    }
</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 ()
    {
        // Use the standard DOM function to get references to all
        // of the checkboxes within the datagrid.
        var checkboxes = document.querySelectorAll('div#myGrid input[type=checkbox]');
        
        // Loop through the checkboxes setting the checked state
        // to the inverse of the window.allCheckboxesCheckedState
        // variable.
        checkboxes.forEach((value,key,array) =>
        {
            value.checked = !window.allCheckboxesCheckedState;
        });
        
        // Reverse the state of the window.allCheckboxesCheckedState
        // variable.
        window.allCheckboxesCheckedState = !window.allCheckboxesCheckedState;
    }
</script>

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

Column ranges in properties

Column ranges are used with several properties to allow you to specify a range of column indexes. The properties that accept column ranges are:

And you can specify any of the following:

For example:

columnsHTML: '4',
columnsFormatted: '2,3,4',
columnsResizableHandles: 1,
sortableColumns: '2-',
editableColumns: '-4',
searchExclude: '2,3,5-7,9-'

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">
    
    <!-- Search container -->
    <div class="rgraph-datagrid-search-container"></div>
    
    <!-- Paging links container -->
    <div class="rgraph-datagrid-paging-links"></div>

    <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 tbody tr.rgraph-datagrid-row-hover {
        background-color: #00f1; // You may also need to add the !important modifier
                                 // if your selector is not specific enough.
    }
</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.
    * You may need to use the !important modifier here too.
    */
    .rgraph-datagrid-row-hover {
        background-color: #00f1 !important;
    }
</style>

Instead of embedding the style in your page, you can utilise the style property for this to make it easy and that would look like this (this would be specific to the datagrid of course):

<script>
    new RGraph.Datagrid({
        id: 'myGrid',
        data: [
            [324, 'Richard', 'Web developer'],
            [435, 'Dave', 'Customer Services'],
            [112, 'Charles', 'Manager'],
            [698, 'Freddy', 'Driver'],
        ],
        options: {
            style: [
                'table tbody tr.rgraph-datagrid-row-hover {background-color: #00f1;}'
            ]
        }
    }).draw();
</script>

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 {
        display: block;
    }

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

Or using the style configuration property you could do this:

<script>
    data = [
        ['Richard','Oranges',  124],
        ['Jane',  'Apples',    152],
        ['Lucy',  'Grapes',    98],
        ['Jerry', 'Gooseberry',95],
        ['Alex',  'Mango',     103],
        ['Freddy','Apple',     111],
        ['Peter', 'Orange',    56],
        ['Jim',   'Pear',      16],
        ['James', 'Apple',     43],
        ['Doug',  'Blueberry', 84],
        ['Carl',  'Peach',     126],
        ['Dave',  'Kiwi',      13],
        ['Peter', 'Almonds',   84]
    ];

    myGrid = new RGraph.Datagrid({
        id: 'myGrid',
        data: data,
        options: {
            columnsHeaders: ['Name','Fruit','Amount (Kg)'],
            style: [
                'table {display: block;}',
                'table tbody {max-height: 150px;overflow-x:hidden;overflow-y:auto;display: block;width: 100%;}',
                'table tbody tr.rgraph-datagrid-row-hover {background-color: #00f1;}'
            ]
        }
    }).draw();
</script>

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 tr :where(th, td):nth-child(1) {
        display: none;
    }
</style>

And here's the resulting datagrid, which now has 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)
                'table :where(tbody, thead) tr :where(td, th):nth-child(1) {display: none;}',
                
                'table thead tr th div {background-color: black; color: white;}',
                'table thead tr th span {color: white;}'
            ]
        }
    }).draw();
</script>

You can of course just alter your data before you pass it to the datagrid if you prefer and that would look like this:

// The original data array
myData = [
    [48645, 'Richard', 'Web developer'],
    [88432, 'Alex', 'Web developer'],
    [35684, 'Nick','CTO'],
    [94325,'Kjell','Product manager'],
    [44351, 'Scott','Product manager'],
    [94643,'Doug','CEO'],
];

// Run the .slice() function on each entry in myArray and return
// the new array.
myData1 = myData.map(row => row.slice(1));

console.log(myData1);

// myData1 = [
//     ['Richard','Web developer'],
//     ['Alex',   'Web developer'],
//     ['Nick',   'CTO'],
//     ['Kjell',  'Product manager'],
//     ['Scott',  'Product manager'],
//     ['Doug',   'CEO'],
// ];