<h4>Simple Example</h4>
<div id="example"></div>
var table = new hx.DataTable('#example')
table.feed(hx.dataTable.objectFeed({
headers: [
{name: 'Name', id: 'name'},
{name: 'Age', id: 'age'},
{name: 'Profession', id: 'profession'}
],
rows: [
{
id: 0, // hidden details can go here (not in the cells object)
cells: {'name': 'Bob', 'age': 25, 'profession': 'Developer'}
},
{
id: 1,
cells: {'name': 'Jan', 'age': 41, 'profession': 'Artist'}
},
{
id: 2,
cells: {'name': 'Dan', 'age': 41, 'profession': 'Builder'}
}
]
}))
<h4>Lazy Example</h4>
<div id="lazy-example"></div>
var finalSize = undefined
var backendRows = [
{
id: 0, // hidden details can go here (not in the cells object)
cells: {'name': 'Bob', 'age': 25, 'profession': 'Developer'}
},
{
id: 1,
cells: {'name': 'Jan', 'age': 41, 'profession': 'Artist'}
},
{
id: 2,
cells: {'name': 'Dan', 'age': 41, 'profession': 'Builder'}
}
]
new hx.DataTable('#lazy-example', {
pageSize: 2,
pageSizeOptions: [1, 2, 3, 10],
filterEnabled: false,
feed: {
headers: function (cb) {
return cb([
{name: 'Name', id: 'name'},
{name: 'Age', id: 'age'},
{name: 'Profession', id: 'profession'}
])
},
rows: function (range, cb) {
return cb({
rows: backendRows.slice(range.start, range.end + 1),
filteredCount: (finalSize !== undefined || range.end >= 2) ? finalSize = 3 : undefined
})
},
totalCount: function (cb) {
return cb(undefined)
}
}
}).render()
<h4>Advanced Search Example</h4>
<div id="advanced-search-example-container"></div>
var tableFeed = hx.dataTable.objectFeed({
headers: [
{ name: 'Name', id: 'name' },
{ name: 'Age', id: 'age' },
{ name: 'Profession', id: 'profession' }
],
rows: [
{
id: 0,
cells: { 'name': 'Bob', 'age': 25, 'profession': 'Developer' }
},
{
id: 1,
cells: { 'name': 'Jan', 'age': 41, 'profession': 'Artist' }
},
{
id: 2,
cells: { 'name': 'Dan', 'age': 41, 'profession': 'Builder' }
}
]
})
// Use the fluid api to append the content
hx.select('#advanced-search-example-container')
.add(hx.dataTable({
feed: tableFeed,
filterEnabled: false, // Disable the normal filter
showSearchAboveTable: true, // Show the search above the table instead of below
advancedSearchEnabled: true // Enable the advanced search
}))
<h4>Advanced Search Criteria Example</h4>
<div id="advanced-criteria-example"></div>
var tableFeed = hx.dataTable.objectFeed({
headers: [
{ name: 'Name', id: 'name' },
{ name: 'Age', id: 'age' },
{ name: 'Profession', id: 'profession' }
],
rows: [
{
id: 0,
cells: { 'name': 'Bob', 'age': 25, 'profession': 'Developer' }
},
{
id: 1,
cells: { 'name': 'Jan', 'age': 41, 'profession': 'Artist' }
},
{
id: 2,
cells: { 'name': 'Dan', 'age': 41, 'profession': 'Builder' }
}
]
})
// Use the fluid api to append the content
hx.select('#advanced-criteria-example')
.add(hx.dataTable({
feed: tableFeed,
filterEnabled: false, // Disable the normal filter
advancedSearchEnabled: true, // Enable the advanced search
advancedSearchCriteria: hx.filter.types(), // Enable all the filter types
advancedSearch: [
[
{column: "age", term: "26", criteria: "greater"}
],
[
{column: "name", term: "Bob", criteria: "exact"}
]
]
}))
hx.userFacingText('dataTable', 'addFilter')
showAdvancedSearch
and advancedSearchEnabled
are both set to true, showing and enabling the advanced search. See the Using the Advanced Search section at the bottom of the page for more information on the advanced search hx.filter.types()
.
Setting this to undefined disables the ability to change the filter criteria and uses 'contains' filtering. advancedSearch
is passed in, this is set to true. If filterEnabled
is set to false and this is set to true, the advanced search will be shown on it's own with no toggle for switching the filter type. See the Using the Advanced Search section at the bottom of the page for more information on the advanced search hx.userFacingText('dataTable', 'search')
hx.userFacingText('dataTable', 'advancedSearch')
hx.userFacingText('dataTable', 'anyColumn')
function (element, cell, row) {
hx.select(element).text(cell);
}
hx.userFacingText('dataTable', 'clearFilters')
{
"columnid": {
sortEnabled: true,
cellRenderer: function (element, cell, row) {
hx.select(element).text(cell);
}
}
}
Feed
and hx.dataTable
objects for information on feeds. function (element, cell, headers) {
hx.select(element).text(cell.name);
}
function (row) {
return false;
}
function (row) {
return !row.disabled;
}
function (row) {
return row.id;
}
function (row) {
return true;
}
'$total'
variables can be substituted in, e.g for a table with 3 rows and 1 row selected: options = {
selectedRowsText: '$selected of $total selected.'
}
// Would evalate to '1 of 3 selected.'
advancedSearchEnabled
is true or an advancedSearch
is passed in, this is set to true. selectEnabled
must also be true for this to take effect. columns
option. true
{
headers: function (cb) { ... }
totalCount: function (cb) { ... }
rows: function (range, cb) { ... }
rowsForIds: function (ids, cb) { ... }
}
hx.dataTable
object. A data table expects data to be returned in the callback of each function with a specific value. If a custom feed is created, it must return the values expected by the table. {
start: 0,
end: 14,
filter: "",
sort: {
column: 'name'
direction: 'desc'
},
useAdvancedSearch: true, // Whether to filter using the advanced search
advancedSearch: [
[
{ column: 'any', term: '' }
]
]
}
[
{
id: 0, // The ID for a row
// hidden details can be specified here (not in the cells object)
cells: {
'columnID': 'value' // The cell values for a row in columnID/value pairs
}
},
... // Additional rows
]
DataTable::rowsForIds
is called. hx.identity
function(term, rowSearchTerm) {
var whitespaceSplitRegex = /\s+/
var stripLeadingAndTrailingWhitespaceRegex = /^\s+|\s+$/g
var arr = term.replace(stripLeadingAndTrailingWhitespaceRegex, '').split(whitespaceSplitRegex)
var validPart = hx.find(arr, function(part) {
return ~rowSearchTerm.indexOf(part)
})
return hx.defined(validPart)
}
{
headers: [
{ name: 'Name', id: 'name' },
... // Additional Headers
],
rows: [
{
// hidden details can go here (not in the cells object)
id: 0,
cells: {
'name': 'Bob',
... // Additional cell data (each header should have linked cell data for each row)
}
},
... // Additional Rows
]
}
hx.identity
function (term, row) {
var rowSearchTerm = Object.keys(row.cells).map(function (key) { return row.cells[key]}).join(' ').toLowerCase()
term = term.toLowerCase.split(' ');
for (var i in term) {
var part = term[i];
if (rowSearchTerm.indexOf(part) === -1) {
return false
}
}
return false
}
function(term, rowSearchTerm) {
var whitespaceSplitRegex = /\s+/
var stripLeadingAndTrailingWhitespaceRegex = /^\s+|\s+$/g
var arr = term.replace(stripLeadingAndTrailingWhitespaceRegex, '').split(whitespaceSplitRegex)
var validPart = hx.find(arr, function(part) {
return ~rowSearchTerm.indexOf(part)
})
return hx.defined(validPart)
}
var tableData = {
headers: [
{ name: 'Name', id: 'name' },
{ name: 'Age', id: 'age' },
{ name: 'Profession', id: 'profession' }
],
rows: [
{
id: 0,
cells: { 'name': 'Bob', 'age': 25, 'profession': 'Developer' }
},
{
id: 1,
cells: { 'name': 'Jan', 'age': 41, 'profession': 'Artist' }
},
{
id: 2,
cells: { 'name': 'Dan', 'age': 41, 'profession': 'Builder' }
}
]
}
var table = new hx.DataTable('#selector')
table.feed(hx.dataTable.objectFeed(tableData))
hx.json('path_to_your_request.file', function(err, data){
if (!err) table.feed(hx.dataTable.objectFeed(tableData));
})
hx.dataTable.urlFeed('request_url', {
cache: true, // Whether to attempt caching of data
extra: // Any extra data to be sent with every request
})
POST
requests: {
type: 'headers',
extra: // As defined in the options
}
[
{
"name": "columnName", // The name for the heading to display in the table
"id": "columnID" // The unique ID for the column
},
... // Additional headers
]
{
type: 'totalCount',
extra: // As defined in the options
}
{
"count": 123 // The total number of rows in the data set
}
{
type: 'rows',
range: {
start: 0, // The start index to get
end: 14, // The end index to get
sort: {
column: undefined, // the sort column
direction: undefined // The sort direction
},
filter: undefined, // The current filter.
useAdvancedSearch: false // Whether the advanced search is enabled
advancedSearch: undefined // The currently set advanced search
}
extra: // As defined in the options
}
{
"filteredCount": 10, // The number of rows in the filtered set
"rows": [
{
"id": 0, // The ID for a row
// hidden details can be specified here (not in the cells object)
"cells": {
"columnID": "value" // The cell values for a row in columnID/value pairs
}
},
... // Additional rows
]
}
{
type: 'rowsForIds',
ids: [1, 2, 3] // The array of ids to get row data for
extra: // As defined in the options
}
[
{
"id": 0, // The ID for a row
// hidden details can be specified here (not in the cells object)
"cells": {
"columnID": "value" // The cell values for a row in columnID/value pairs
}
},
... // Additional rows
]
hx.dataTable
object are not suitable, custom feeds can be created. For instance, if using POST
is not suitable, an alternative could be created: // Serializes an object into param=value¶m[child]=value
function serialize (obj, prefix) {
var arr = []
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + '[' + p + ']' : p, v = obj[p]
arr.push(typeof v == 'object' ?
serialize(v, k) :
encodeURIComponent(k) + '=' + encodeURIComponent(v))
}
}
return arr.join('&')
}
function createCustomURLFeed (url) {
var fetcher = function (data, cb) {
// Serializes the data so it can be passed over as a GET request
hx.json(url + '?' + serialize(data), function (err, data) { cb(data) })
}
// Return the feed object with headers, rows, rowsForIds and totalCount properties
return {
headers: function (cb) {
fetcher({ type: 'headers' }, cb)
},
rows: function (range, cb) {
fetcher({ type: 'rows', range: range }, cb)
},
rowsForIds: function (ids, lookupRow, cb) {
fetcher({ type: 'rowsForIds', ids: ids }, cb)
},
totalCount: function (cb) {
fetcher({ type: 'totalCount' }, cb)
}
}
}
columns
{
headers:[
{ id: 'name', name: 'Name', groups: ['Group 1']},
{ id: 'age', name: 'Age' },
{ id: 'gender', name: 'Gender', groups: ['Group 2']},
{ id: 'dob', name: 'Date of Birth', groups: ['Group 2']},
{ id: 'salary', name: 'Salary (£)', groups: ['Group 2']}
],
rows: [
//...
]
}
allowHeaderWrap
option for an individual column by providing the allowWrap
property in the header colums: {
headers:[
{ id: 'name', name: 'Name' },
{ id: 'age', name: 'Age' },
{ id: 'gender', name: 'Gender' },
{ id: 'dob', name: 'Date of Birth' allowWrap: true },
{ id: 'salary', name: 'Salary (£)' }
],
rows: [
//...
]
}
rowEnabledLookup
function is called. If it returns false, the row will visually disabled and unselectable. By default, a row can be made unselectable using a property in the row object: [
{
id: 'rowId',
disabled: true,
cells: {
...// Row data
}
},
... // Additional rows
]
rowSelectableLookup
function is called to check whether the row is selectable. If it returns false, the row will not be selected. By default, the rowSelectableLookup
function allows all rows to be selected. However, by setting the rowSelectableLookup
, the row can be made unselectable: dataTable.rowSelectableLookup(function (row) {
return !row.unselectable;
})
[
{
id: 'rowId',
unselectable: true,
cells: {
...// Row data
}
},
... // Additional rows
]
{
filterEnabled: true,
showAdvancedSearch: true
}
<div id="advanced-search-toggle"></div>
var dt = new hx.DataTable('#advanced-search-toggle', {
feed: tableFeed,
filterEnabled: true,
showAdvancedSearch: true
})
dt.render()
{
filterEnabled: false,
advancedSearchEnabled: true
}
advancedSearchEnabled
option is used here. It causes showAdvancedSearch
to be true and shows the advanced search. <div id="advanced-search-only"></div>
var dt = new hx.DataTable('#advanced-search-only', {
feed: tableFeed,
filterEnabled: false,
advancedSearchEnabled: true
})
dt.render()
column
and term
property The logic behind the filtering uses Disjunctive Normal Form (an OR
of AND
s) [
[
{ column: 'any', term: 'a' },
// AND
{ column: 'name', term: 'b' }
],
// OR
[
{ column: 'profession', term: 'c' }
]
]
(Any column contains 'a' and the name column contains 'b') or (The profession column contains 'c')
AND
or OR
filters and splits the array(s) accordingly. <div id="advanced-search-with-data"></div>
var dt = new hx.DataTable('#advanced-search-with-data', {
feed: tableFeed,
advancedSearch: [
[
{ column: 'any', term: 'a' },
{ column: 'name', term: 'b' }
],
[
{ column: 'profession', term: 'd' }
]
]
})
dt.render()
rows
function will be given some additional properties as part of the range
object: {
type: 'rows',
range: {
start: 0,
end: 14,
sort: {
column: undefined,
direction: undefined
},
filter: undefined,
useAdvancedSearch: true // Indicates that the filtering should be done using the advanced search
advancedSearch: [ // The currently set advanced search
[
{ column: 'any', term: 'a' },
{ column: 'name', term: 'b' }
],
[
{ column: 'profession', term: 'd' }
]
]
}
extra: {}
}
useAdvancedSearch
should be used to determine whether to filter using the advanced search or the regular filter.