<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.identityfunction(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.identityfunction (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.