- Fetch data from any source: local data or remote data (using ajax, deferred function or plugin)
- Render a simple HTML Table easy to style (no imposed css)
- Simple columns definition
- Semi-automatic sorter and pager (for remote data, you need to code server side)
- Plugins for cell, pager and sorter renderers (easy to create, very easy to extend)
- Events on each step (you do what you want with your data)
- Convert form elements (input, select) into automatic filters (magic!)
bower install jquery.datagrid
or
npm install jquery.datagrid
Just load jquery.datagrid.js
(and optional plugin scripts if you want to use them)
A simple example with remote data (fetch by ajax post)
<script type="text/javascript" src="jquery.datagrid.js"></script>
<script type="text/javascript">
$( document ).ready( function() {
var datagrid = $(container).datagrid({
url: "get-data-url",
col: [{
field: "name",
title: "Name",
sortable: true
},{
field: "age",
title: "Age",
render: function( data ) {
return "<strong>" + data.value + "<strong>";
}
}]
})
});
</script>
Another simple example with local data
<script type="text/javascript" src="jquery.datagrid.js"></script>
<script type="text/javascript">
$( document ).ready( function() {
var datagrid = $(container).datagrid({
data: [{
firstname: "Bob",
lastname: "Dylan"
},{
firstname: "Jimi",
lastname: "Hendrix"
}],
col: [{
field: "firstname",
title: "Firstname"
},{
field: "lastname",
title: "Lastname",
sortable: true,
render: function( data ) {
return "<strong>" + data.value + "<strong>";
}
}]
})
});
</script>
// All options with default values
{
source: "default", // plugin
url: "",
data: false,
autoload: true,
paramsDefault: {},
paramsMapping: {
page: "page",
paging: "paging",
orderby: "orderby",
direction: "direction"
},
parse: function( data ) {
if ( $.type( data ) === 'string' ) {
return JSON.parse( data );
} else {
return data;
}
},
col: [],
attr: {},
attrSortable: {},
noData: "no data",
onBefore: false,
onData: false,
onRowData: false,
onComplete: false,
sorter: "default", // plugin
pager: "default", // plugin
pagerPosition: "bottom"
}
List of option names
( expected values )
source
( string || object || function ) : data fetching method: function, plugin name (string) or plugin name with config (object). - see Source Plugins belowurl
( string ) : server url where data are fetch (with POST params data). Used bydefault
source.data
( false || array ) : local data (no remote fetch). If notfalse
,source
will be automatically set to"data"
.autoload
( boolean ) : auto load data. If set tofalse
, you need to load manualy the data withdatagrid.fetch()
method.paramsDefault
( object ) : default params added to the data request.paramsMapping
( object ) : you can map param names used for paging and sorting (keys used: see default value).parse
( function ) : callback function that parse data before render. By default, decode data inJSON
if data is astring
.
col
( array ) : array of column definition objects. - see Column options belowattr
( false || object ) : an object of attribute-value pairs: generate the table element attributes.attrSortable
( false || object ) : an object of attribute-value pairs: params for$(th).attr()
if column is sortable.noData
( string || function ) :string
: it will be displayed instead of the table if there is no data.function
: the result returned by the function will be displayed.
sorter
( string || object ) : display text or icon on table header when columns are sorted (asc or desc). - see Plugins belowpager
( string || object ) : render the pager.default
pager write page numbers in aspan
, all in adiv
. - see Plugins belowpagerPosition
( false || "top" || "bottom" || ["top","bottom"] ) : display the pager on"bottom"
of thetable
, or on the"top"
, or both with["top","bottom"]
.
onBefore
( false || function ) : callbackfunction()
. Scope isdatagrid
.onData
( false || function ) : callbackfunction( { "total": Total number of data without paging, "data": [ Array of row ] } )
onRowData
( false || function ) : callbackfunction( data[ numrow ], numrow, $tr )
onComplete
( false || function ) : callbackfunction()
. Scope isdatagrid
.
// All column options with default values
{
field: "", // Field name
title: "", // Title display in the `th`content
attrHeader: {}, // Param for `$(th).attr()`
attr: {}, // Param for `$(td).attr()`
sortable: false, // `true` activate column sort on `th` click
render: "default" // *see cell rendering below*
}
How to display td
content depends on column render
value.
- Use a plugin registered with
"plugin-name"
("default"
plugin just displayfield
value)
render: "plugin-name"
- Use a registered plugin
"plugin-name"
withparams
render: { "plugin-name": params }
- Use a callback function
render: function( data ){
// scope (this) is the `$(td)` in the callback
// fill `td` with `$(td).html( returned value )`
return data.value;
// if you return false, `td` content will not be changed
// you can update cell with `this.html()`, `this.append()`, ...
this.html( data.value );
return false;
// `data` is an object like this
data = {
value: "the value of the field key",
field: "the field key name",
row: "row data object (row.fieldname = value)",
colindex: "column number (first is 0)"
}
}
To fetch data and launch the flow, you need to call datagrid fetch( filters )
method.
It will be automatically executed when option.autoload = true
.
filters
is an optional object of attribute-value pairs. They are merged with paging and sorting params and send when fetching data.
Fetching data do not reset previous params (usefull with auto filters). You can reset params to default with reset()
method.
// Scope (this) in the callback is `datagrid` (the plugin).
"onBefore()" event is called (if defined) before fetching data.
How data is fetched depends on source
option type:
Plugin will be used (if it exists).
"default"
plugin use $.post( options.url )
to get data. see Source plugin below
$.when( options.source() )
is used.
Scope (this
) in the callback is the datagrid instance.
So you can get datagrid params with params()
method.
After data is fetched from source, render( data )
is called automatically when you defer.resolve( data )
.
// example with deferred $.get()
"source": function() {
return $.get( "url", this.params() );
}
// example with deferred function
"source": function() {
return $.Deferred(function( defer ) {
async_call(
callback_success( data ) {
defer.resolve( data );
},
callback_error( error ) {
defer.reject( error );
}
);
}).promise();
}
Data is parsed by parse()
method. Default method parse data with JSON.parse()
(if data is a string).
Method can be changed with datagrid parse
option.
Data format expected to render the datagrid is an object like this:
{
total: Number of rows (without pagination),
data: [{
"fieldname1": value1,
"fieldname2": value2,
...
},
{
"fieldname1": value3,
"fieldname2": value4,
...
}
}]
}
HTML table is displayed when datagrid.render( data )
method is called.
// Data is in expected format.
// Data returned replace old data. Return false or nothing to not change data.
"onData( data )" event is called (if defined).
If a sorter
plugin is defined, click events are attached on th
(if column sortable
option is set to true
)
// Usefull to change attributes of a `tr`.
// Data returned replace old data. Return false or nothing to not change data.
"onRowData( rowdata, numrow, $tr )" event is called on each "tr" line (if defined).
Each cell is displayed (see cell rendering)
"onComplete()" event is called (if defined) when all is rendered.
Methods can be called in 2 ways:
- With selector used to create datagrid
$( selector ).datagrid( "methodName", methodParams );
- Or with a reference to the datagrid instance
datagrid.methodName( methodParams );
You can get a reference to the datagrid instance with
$( selector ).datagrid( "datagrid" );
// it's chainable
$( selector ).datagrid( "datagrid" ).methodName( methodParams );
// fetch source (get data). `filters` is an object of attribute-value pairs (optional).
$( selector ).datagrid( "fetch", filters );
// get page number (first page is 1).
$( selector ).datagrid( "page" );
// set page number. `fetch()` is not called.
$( selector ).datagrid( "page", page );
// get paging number (default paging is 15).
$( selector ).datagrid( "paging" );
// set paging number. `fetch()` is not called.
$( selector ).datagrid( "paging", paging );
// get orderby (default orderby is "").
$( selector ).datagrid( "orderby" );
// set orderby. `fetch()` is not called.
// sorter plugin use field name.
$( selector ).datagrid( "orderby", orderby );
// get direction (default direction is "").
$( selector ).datagrid( "direction" );
// set direction. `fetch()` is not called.
// sorter plugin use "asc" or "desc".
$( selector ).datagrid( "direction", direction );
// get params used for data request.
$( selector ).datagrid( "params" );
// reset params to default.
$( selector ).datagrid( "reset" );
// render HTML table.
$( selector ).datagrid( "render", data );
// define selected form element(s) (and children) as automatic filters. *see __Filters__ below*
$( selector ).datagrid( "filters", selector );
You can magically add automatic filters with the filters( selector )
method.
It works with all form elements.
// just pass a $element (jquery element) or a "selector" string to the filters method
$( selector ).datagrid( "filters", $element );
// you can also use `datagrid` reference
$( selector ).datagrid( "datagrid").filters( $element );
All form elements (input, select, textarea) contents in the $element
win a change
event that automatically call datagrid.fetch()
.
The changed element value is added to the sent params (key is the html element name).
You can disable an element by adding a "data-datagrid-filter"="disable"
attribute.
If you don't specify a plugin, default
plugin is used.
Plugin are used to:
- fetch data (
source
plugins) - display information on sorted columns header (
sorter
plugins) - display formated data in the table cells (
cell
plugins) - display pagination (
pager
plugins).
For each plugin's type, the plugin name is unique. If you add 2 plugins on the same type with the same name, the second will replace the first.
// with default options (or if plugin has no options)
"plugin-type": "plugin-name"
// with options (depends on plugin)
"plugin-type": { "plugin-name": options }
All plugins are created like this
$.fn.datagrid( "plugin", "plugin-type", "plugin-name", callback );
"plugin-type"
is aString
. Allowed values are"source"
,"cell"
,"sorter"
or"pager"
."plugin-name"
is what you want (just aString
). If you use"default"
name, you'll change default plugin.callback
is aFunction
. Arguments send to the function and expected return value depends on plugin's type (see each type for more information).
You can also extend existing plugins
$.fn.datagrid( "plugin", "plugin-type", "new-plugin-name", "extended-plugin-name", options );
"plugin-type"
is aString
. Value need to match with plugin extended."new-plugin-name"
is the name of your new plugin (aString
)."extended-plugin-name"
is the name of the plugin extended (the "source"). You can extend"default"
plugin.options
is anObject
passed as last argument to"extended-plugin-name"
callback when"new-plugin-name"
is called.options
are merged.
And off course you can extend an extended plugin! :-)
source
plugin is used to fetch data.
In the callback, this
is the instance of the datagrid plugin. So you can get datagrid params with params()
method.
To display the HTML table, you need to call datagrid render( data )
method.
"default"
plugin (alias "post"
) call $.post()
to get data. The only option is url
. If not set, it use datagrid url
option.
"data"
plugin is used for local data. You can change sorter and filter functions by your own with sorter
and filter
options. If data
option is filled, it will be used instead of datagrid data
option. All options are optional.
$( selector ).datagrid({
source: {
data: {
sorter: function( data, key, comparator ) {
// `data`: all the data
// `key`: sorted fieldname
// `comparator`: `1` (asc) or `-1` (desc)
return sortedData;
},
filter: function( data, filters ) {
// `data`: all the data
// `filters`: object of attribute-value pairs
return filteredData;
},
data: [] // array of object (attribute-value pairs)
}
}
});
// example: "get" instead of "post" ajax
$.fn.datagrid( "plugin", "source", "get", function( sourceOptions ) {
var options = {
url: ""
};
if ( sourceOptions ) {
$.extend( options, sourceOptions );
}
var datagrid = this;
$.get( options.url, datagrid.params(), function( result ) {
datagrid.render( result );
});
});
cell
plugin is used to render <td>
content.
"default"
plugin render the cell value and has no options.
// example: "date" display.
// use awesome moment.js (http://momentjs.com).
$.fn.datagrid( "plugin", "cell", "date", function( data, cellOptions ) {
var options = {
format: "DD/MM/YYYY"
};
if ( cellOptions ) {
$.extend( options, cellOptions );
}
return moment( data.value ).format( options.format );
});
And you can extend it like other plugins
// example: "date-us" display.
$.fn.datagrid( "plugin", "cell", "date-us", "date", { format: "MM/DD/YYYY" } );
sorter
plugin is used to display information on sorted column (icons, chevron, arrow, ... or what you want !).
"default"
plugin options are { up: " ↑", down: " ↓" }
.
In the callback, this
is the $(th)
. You don't need to return value. Use this
to change the <th>
content.
Column title is already displayed when callback is executed. You can use this.html()
to get title.
You can extend "default"
plugin like this
$.fn.datagrid( "plugin", "sorter", "text", "default", { up: " - up", down: " - down" } );
Or define a new plugin with a callback function. ascendant
argument is a Boolean
(true
for ascendant sorted column, false
for descendant).
// example: just write "up" or "down"
$.fn.datagrid( "plugin", "sorter", "text", function( ascendant, sorterOptions ) {
if ( ascendant ) {
this.append( " up" );
} else {
this.append( " down" );
}
});
You don't need to handle click
events on sortable columns. sorter
plugins are just renderers.
pager
plugin is used to display pager section (returns HTML).
"default"
plugin handle click
events on page items.
Default options are
{
// pager element wrapper
container: "div",
// pager element wrapper attributes set by `container.attr( attrContainer )`
attrContainer: {},
// if `item` is "li", append an `ul` element to the `container` and set `ul` attributes with `ul.attr( attrUl )`
attrUl: {},
// html element used for pages: "span", "div", "li" (auto insert ul)
item: "span",
// attributes set to active page item (current page)
attrItemActive: {},
// attributes set to disabled page items
attrItemDisabled: {},
// html display before page number
before: " ",
// html display after page number
after: " ",
// if `link = true`, wrap page number with an `a` HTML tag
link: false,
// if `firstPage !== false`, add a page item "first"
// Display value as text (for example `firstPage: "first page"`)
firstPage: false,
// if `prevPage !== false`, add a page item "previous"
// Display value as text (for example `prevPage: "previous page"`)
prevPage: false,
// if `nextPage !== false`, add a page item "next"
// Display value as text (for example `nextPage: "next page"`)
nextPage: false,
// if `lastPage !== false`, add a page item "last"
// Display value as text (for example `lastPage: "last page"`)
lastPage: false,
// if `hideDisabled = true`, hide disabled pages
// (for example, hide `firstPage` and `prevPage` when current page is 1)
hideDisabled: false,
// behavior = false (show all pages)
// behavior = "sliding" (current page always on middle of the pager)
// behavior = { "sliding": { "pages": 3 } } (change number of pages displayed before and after current page)
behavior: false
}
You can write you own pager from scratch with a callback function.
this
in this callback is the datagrid instance.
$.fn.datagrid( "plugin", "pager", "scratch-pager", function( page, lastpage, pagerOptions ) {
// your pager logic, based on "page" (current page) and "lastpage"
var datagrid = this;
var html = ...;
// you must return html pager
return html;
});
You don't need to handle click
events on page items: they are automatically attached on elements with datagrid-page
class. You just need to set target page with data-page
attribute.
jquery.datagrid is distributed under MIT License.