#### Keen - The Ultimate Multi-Demo Bootstrap Admin Theme

#### The most complete UI/UX template solution for today's web projects of any size

## Keen Datatable

### Overview

`KTDatatable` is a Keen's custom plugin defined in `[root]/theme/default/src/theme/framework/components/base/datatable/datatable.js`.

### Initialization

Below code shows basic initialization of the datatable from element with attribute ID`k_datatable`:

    <div id="kt_datatable"></div>

    var datatable = $('#kt_datatable').KTDatatable(options);

You can also init the datatable using the class name.

    <div class="my_datatable" id="kt_datatable"></div>

    var datatable = $('.my_datatable').KTDatatable(options);

The ID attribute is required for the datatable session state such as pagination, query, etc. Datatable save state can be disabled if it's not required.

    var datatable = $('.kt_datatable').KTDatatable({
      // datasource definition
      data: {
        type: 'remote',
        source: {
          read: {
            url: 'inc/api/datatables/demos/default.php',
            map: function(raw) {
              // sample data mapping
              var dataSet = raw;
              if (typeof raw.data !== 'undefined') {
                dataSet = raw.data;
              }
              return dataSet;
            },
          },
        },
        pageSize: 10,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true,
      },

      // layout definition
      layout: {
        scroll: false,
        footer: false,
      },

      // column sorting
      sortable: true,

      pagination: true,

      search: {
        input: $('#generalSearch'),
      },

      // columns definition
      columns: [
        {
          field: 'id',
          title: '#',
          sortable: 'asc',
          width: 40,
          type: 'number',
          selector: false,
          textAlign: 'center',
        }, {
          field: 'employee_id',
          title: 'Employee ID',
        }, {
          field: 'name',
          title: 'Name',
          template: function(row, index, datatable) {
            return row.first_name + ' ' + row.last_name;
          },
        }, {
          field: 'email',
          width: 150,
          title: 'Email',
        }, {
          field: 'phone',
          title: 'Phone',
        }, {
          field: 'hire_date',
          title: 'Hire Date',
          type: 'date',
          format: 'MM/DD/YYYY',
        }, {
          field: 'gender',
          title: 'Gender',
        }, {
          field: 'status',
          title: 'Status',
          // callback function support for column rendering
          template: function(row) {
            var status = {
              1: {'title': 'Pending', 'class': 'kt-badge--brand'},
              2: {'title': 'Delivered', 'class': ' kt-badge--metal'},
              3: {'title': 'Canceled', 'class': ' kt-badge--primary'},
              4: {'title': 'Success', 'class': ' kt-badge--success'},
              5: {'title': 'Info', 'class': ' kt-badge--info'},
              6: {'title': 'Danger', 'class': ' kt-badge--danger'},
              7: {'title': 'Warning', 'class': ' kt-badge--warning'},
            };
            return '' + status[row.status].title + '';
          },
        }, {
          field: 'type',
          title: 'Type',
          // callback function support for column rendering
          template: function(row) {
            var status = {
              1: {'title': 'Online', 'state': 'danger'},
              2: {'title': 'Retail', 'state': 'primary'},
              3: {'title': 'Direct', 'state': 'accent'},
            };
            return ' ' +
                status[row.type].title + '';
          },
        }, {
          field: 'Actions',
          title: 'Actions',
          sortable: false,
          width: 130,
          overflow: 'visible',
          textAlign: 'center',
          template: function(row, index, datatable) {
            var dropup = (datatable.getPageSize() - index) <= 4 ? 'dropup' : '';
            return '\
                        \
                            \
                                \
                            \
                            \
                        \
                        \
                            \
                        \
                        \
                            \
                        \
                    ';
          },
        }],

    });

### Options

Field | Type | Description
--- | --- | ---
`data.type` | `string` | Required. Set type to `remote` for remote data get public URL. `local` is for local data predefined in variable.
Sample
    type: 'remote'
`data.source.read.url` | `string` | If `data.type` is defined as `remote`. Type of remote datasource can be static or dynamic. For the static datasource you can define static JSON file URL. And for dynamic datasource with pagination, sorting and filtering need to be defined as above sample. `url` is required, and `params` object is optional.
Sample
    url: 'inc/api/datatables/demos/orders.php'
`data.source.read.method` | `string` | Request method for ajax request. The value can be `GET` or `POST`. The default value is `POST`.
Sample
    method: 'GET'
`data.source.read.headers` | `object` | Headers parameter object will be sent along in the datatable API request headers.
Sample
    headers: {
        'x-my-custom-header': 'some value',
        'x-test-header': 'the value'
    },
`data.source.read.contentType` | `object` | Content type to be sent to the server. Default to `application/x-www-form-urlencoded; charset=UTF-8`
Sample
    contentType: 'application/json',
`data.source.read.params` | `object` | Your own API may require some parameter to call for getting the data. E.g. token, search keywords, IDs, etc. This query parameters object will be sent along in the datatable API request.
Sample
    params: {
      generalSearch: '',
      EmployeeID: 1
      token: 'tokenvalue'
    }
`data.source.read.map` | `function` | Custom mapping the received data into datatable grid.
Sample
    map: function(raw) {
      // sample data mapping
      var dataSet = raw;
      if (typeof raw.data !== 'undefined') {
    	dataSet = raw.data;
      }
      return dataSet;
    }
`data.source.read.timeout` | `number` | Number of milliseconds before the request ended. Default is 30000, equal to 30 seconds.
Sample
    timeout: 30000
`data.pageSize` | `number` | Define page size of data for each request. Default value is 10.
Sample
    pageSize: 10
`data.saveState.cookie` | `boolean` | Set true or false to enable/disable datatable state to save in `cookie`. Default value is true.
Sample
    cookie: true
`data.saveState.webstorage` | `boolean` | Set true or false to enable/disable datatable state to save in `webstorage`. Default value is true.
Sample
    webstorage: true
`data.serverPaging` | `boolean` | Enable/disable pagination in server side. Only applied for the `remote` data.type.
Sample
    serverPaging: true
`data.serverFiltering` | `boolean` | Enable/disable filtering in server side. Only applied for the `remote` data.type.
Sample
    serverFiltering: true
`data.serverSorting` | `boolean` | Enable/disable sorting in server side. Only applied for the `remote` data.type.
Sample
    serverSorting: true
`data.autoColumns` | `boolean` | Enable/disable auto create columns. By enabling this, the datatable will automatically create all available data in an object.
Sample
    autoColumns: true
Layout
`layout.theme` | `string` | Define which class of theme to apply into datatable.
Sample
    theme: 'default'
`layout.class` | `string` | Custom class to add into datatable.
Sample
    class: 'kt-datatable--brand'
`layout.scroll` | `boolean` | Enable/disable scroll.
Sample
    scroll: true
`layout.height` | `string` | Define fixed height for the datatable.
Sample
    height: 300
`layout.footer` | `boolean` | Enable/disable footer.
Sample
    footer: false
`layout.header` | `boolean` | Enable/disable header.
Sample
    header: false
`layout.customScrollbar` | `boolean` | Enable/disable custom scrollbar. Default is true.
Sample
    customScrollbar: true
`layout.spinner.overlayColor` | `string` | Spinner background overlay color.
Sample
    overlayColor: '#000000'
`layout.spinner.opacity` | `number` | Spinner background opacity.
Sample
    opacity: 0
`layout.spinner.type` | `string` | Spinner type.
Sample
    type: 'loader'
`layout.spinner.state` | `string` | Spinner state style. Default to brand.
Sample
    state: 'brand'
`layout.spinner.message` | `boolean` `string` | Enable/disable loading message during spinner is active. Set boolean or text string message.
Sample
    message: true
    message: 'Loading..'
`layout.icons.sort` | `object` | Options config for the icons class for sorting icon ascending and descending.
Sample
    sort: {
      asc: 'la la-arrow-up',
      desc: 'la la-arrow-down'
    }
`layout.icons.pagination` | `object` | Icons for pagination buttons.
Sample
    pagination: {
      next: 'la la-angle-right',
      prev: 'la la-angle-left',
      first: 'la la-angle-double-left',
      last: 'la la-angle-double-right',
      more: 'la la-ellipsis-h'
    }
`layout.icons.rowDetail` | `object` | rowDetail is for expand and collapse icon for table with child table.
Sample
    rowDetail: {
      expand: 'fa fa-caret-down',
      collapse: 'fa fa-caret-right'
    }
Others
`sortable` | `boolean` | Enable/disable columns sortable globally.
Sample
    sortable: true
`pagination` | `boolean` | Enable/disable pagination globally.
Sample
    pagination: true
`search.onEnter` | `boolean` | Set the search input keyup event to enter. The internal search will be triggered using `Enter` button. Set false to trigger search on keyup any buttons.
Sample
    search: {
       onEnter: true,
    },
`search.input` | `jQuery` | Pass the jQuery element of input. The datatable will add onKeyup event to the input to trigger the internal search filter the data that already in the table.
Sample
    search: {
       input: $('#generalSearch'),
    },
`search.delay` | `number` | Control the speed of search and data load request to reduce the search call frequency automatically. Default value is 400ms. Set the number of milliseconds.
Sample
    search: {
      // search delay in milliseconds
      delay: 400,
    },
Toolbar
`toolbar.layout` | `array` | Set the order of pagination and info by array index.
Sample
    layout: ['pagination', 'info']
`toolbar.placement` | `array` | An array list of placement for pagination buttons. Can be multiple values. Set the pagination placement to bottom or top.
Sample
    placement: ['bottom']
`toolbar.items .pagination.type` | `string` | Pagination type.
Sample
    type: 'default'
`toolbar.items .pagination.pages.desktop` | `object` | Pagination pages responsive config for desktop. An object that contains layout and pagesNumber. Default value for layout is default. Define pagesNumber to specify how many number of page for each responsive breakpoint.
Sample
    desktop: {
      layout: 'default',
      pagesNumber: 6
    }
`toolbar.items .pagination.pages.tablet` | `object` | Pagination pages responsive config for tablet. An object that contains layout and pagesNumber. Default value for layout is default. Define pagesNumber to specify how many number of page for each responsive breakpoint.
Sample
    tablet: {
      layout: 'default',
      pagesNumber: 3
    }
`toolbar.items .pagination.pages.mobile` | `object` | Pagination pages responsive config for mobile. Default value for layout is compact. Layout compact type do not have to specify pagesNumber.
Sample
    mobile: {
      layout: 'compact'
    }
`toolbar.items .pagination.navigation` | `object` | Enable/disable pagination buttons for prev, next, first, last.
Sample
    navigation: {
      prev: true,
      next: true,
      first: true,
      last: true
    },
`toolbar.items .pagination.pageSizeSelect` | `array` | Array of Number for select size dropdown to select pagination size. -1 is used for "All" option.
Sample
    pageSizeSelect: [10, 20, 30, 50, 100]
`toolbar.items.info` | `boolean` | Enable/disable display of records and pagination info.
Sample
    info: true
Translate
`translate.records.processing` | `string` | Translation for records loading during spinner is active.
Sample
    processing: 'Please wait...'
`translate.records.noRecords` | `string` | Translation for no records message.
Sample
    noRecords: 'No records found'
`translate.toolbar .pagination.items.default` | `object` | Translation for pagination. Contains key for first, prev, next, last, more, input, select.
Sample
    default: {
      first: 'First',
      prev: 'Previous',
      next: 'Next',
      last: 'Last',
      more: 'More pages',
      input: 'Page number',
      select: 'Select page size'
    }
`translate.toolbar .pagination.items.info` | `string` | Translation for info template.
Sample
    info: 'Displaying {{start}} - {{end}} of {{total}} records'
Detail |
`detail.title` | `string` | Sub table title.
Sample
    title: 'Load sub table'
`detail.content` | `object` | A callback function of `Datatable` instance as a sub table of each record. The callback has one parameter which you can access the row data `event.data` and child table element in `event.detailCell`.
Sample
    content: function (event) {
    }
Rows
`rows` | `object` | An array of columns with options object for each column. First column should be define as a unique key for each records.
`rows.callback` | `string` | Row callback. `Deprecated in v5.0.6` Use `rows.beforeTemplate` instead.
Sample
    callback: function (row, data, index) {
    }
`rows.beforeTemplate` | `string` | Row callback that call before template being rendered. Receive 3 params which are the row jQuery element, the row data and row number index.
Sample
    beforeTemplate: function (row, data, index) {
    }
`rows.afterTemplate` | `string` | Row callback that call after rows has been rendered. Receive 3 params which are the row jQuery element, the row data and row number index.
Sample
    afterTemplate: function (row, data, index) {
    }
`rows.autoHide` | `boolean` | Auto hide columns which are overflow in a row for the responsive mode. By default is enabled.
Sample
    autoHide: true,
Columns
`columns` | `array` | An array of columns with options object for each column. First column should be define as a unique key for each records.
`columns[ColName].field` | `string` | Required. The field name of column.
Sample
    field: 'ColumnName'
`columns[ColName].title` | `string` | Required. The title name and will be displayed as header or footer.
Sample
    title: 'Column Name'
`columns[ColName].sortable` | `boolean` | Enable/disable sort feature for the column.
Sample
    sortable: false
`columns[ColName].width` | `number` | The width size of cells under this column.
Sample
    width: 40
`columns[ColName].textAlign` | `string` | The alignment of cells text under this column.
Sample
    textAlign: 'center'
`columns[ColName].template` | `function` `string` | A callback function support for column rendering and recieve a parameter object of current row's value. Can be also a string with placeholder and define with field name {{field}}.
Sample
    template: function (row) {
      return '' + row.OrderID + '';
    }
    template: '{{OrderID}}'
`columns[ColName].sortCallback` | `function` `string` | A callback function support for custom sorting.
Input Parameters
Name | Type | Description
--- | --- | ---
`data` | `object` | JSON string array of original data for sorting
`sort` | `string` | Sorting type of `asc` for ascending or `desc` for descending.
`column` | `object` | Column config object
Sample
    sortCallback: function (data, sort, column) {
        var field = column['field'];
        return $(data).sort(function (a, b) {
            var aField = a[field];
            var bField = b[field];
            if (sort === 'asc') {
                return parseFloat(aField) > parseFloat(bField)
                    ? 1 : parseFloat(aField) < parseFloat(bField)
                        ? -1
                        : 0;
            } else {
                return parseFloat(aField) < parseFloat(bField)
                    ? 1 : parseFloat(aField) > parseFloat(bField)
                        ? -1
                        : 0;
            }
        });
    }
`columns[ColName].overflow` | `string` | CSS overflow value.
Sample
    overflow: 'visible'
`columns[ColName].responsive` | `object` | Set visible or invisible for each responsive breakpoint.
Sample
    responsive: {
      visible: 'md',
      hidden: 'lg'
    }
`columns[ColName].selector` | `object` | Enable column as selector (checkbox only with no text) and provide custom `class` name.
Sample
    selector: {
      class: 'kt-checkbox--solid'
    }
`columns[ColName].locked` | `object` | Set the column to which side to be locked or static. Set object with which side left/right as key and the value is which responsive breakpoint to lock.
Sample
    locked: {left: 'xl'}
`columns[ColName].autoHide` | `boolean` | When rows.autoHide option is enabled, by default all overflowing columns will be hidden in the details row. Set this option to `false`, to force this column from being hidden.
Sample
    autoHide: false

### Events

Method | Description
--- | ---
`kt-datatable--on-init` | Initialization of table.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`options` | `object` | Datatable ID and initialized options.
`kt-datatable--on-destroy` | On datatable destroyed.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`kt-datatable--on-layout-updated` | Event that will be triggered on layout rendering update and resizing datatable.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Provide table parameters, eg. datatable ID attribute
`kt-datatable--on-ajax-done` | After ajax request is completed.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`data` | `object` | List of all records.
`kt-datatable--on-ajax-fail` | Ajax request is failed.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`jqXHR` | `object` | jQuery XMLHttpRequest from jQuery request, include error details.
`kt-datatable--on-goto-page` | Navigate to any page number.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Page details.
`kt-datatable--on-update-perpage` | Update page size.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Page details.
`kt-datatable--on-reloaded` | Reload datatable.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`kt-datatable--on-check` | On check checkbox selector.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Checked records details.
`kt-datatable--on-uncheck` | On uncheck checkbox selector.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Unchecked records details.
`kt-datatable--on-sort` | Sorting datatable.
Input Parameters
Name | Type | Description
--- | --- | ---
`event` | `object` | Default event object.
`args` | `object` | Sorting details. Eg. field and sort type of asc or desc.

### API Methods

Method | Description
--- | ---
`datatable.load()` | Load datatable datasource. Same function with datatable.reload().
`datatable.reload()` | Reload datatable datasource and rerender the table.
`datatable.destroy()` | Destroy the datatable instance and revert the HTML.
`datatable.getRecord(id)` | Select record in the datatable by ID. ID is refers to the value of first column. Use with chaining methods `datatable.getColumn(columnName)`
Input Parameters
Name | Type | Description
--- | --- | ---
`id` | `string` | ID is refers to the first columns value of each rows.
`datatable.getColumn(columnName)` | Get column by column name. Use with chaining methods `datatable.getValue()` to get a cell value.
Input Parameters
Name | Type | Description
--- | --- | ---
`columnName` | `string` | Column name as defined in datatable options init `columns[ColName].field`
`datatable.getValue()` | Get selected records values as string.
Returns
`string`
Sample
    datatable.getRecord(1).getColumn('columnName').getValue();
`datatable.sort(columnName, sort)` | Sort datatable by columnName field. Sort by ascending or descending.
Input Parameters
Name | Type | Description
--- | --- | ---
`columnName` | `string` | Column name as defined in datatable options init `columns[ColName].field`
`sort` | `string` | Sort type to ascending or descending, can accept value asc and desc.
`datatable.setActive(cell)` | Set datatable selector checkbox to active state.
Input Parameters
Name | Type | Description
--- | --- | ---
`cell` | `string` | Cell is a string of selector checkbox value.
`datatable.setInactive(cell)` | Set datatable selector checkbox to inactive state.
Input Parameters
Name | Type | Description
--- | --- | ---
`cell` | `string` | Cell is a string of checkbox value.
`datatable.setActiveAll(active)` | Set datatable selector checkbox active/inactive for all records.
Input Parameters
Name | Type | Description
--- | --- | ---
`active` | `boolean` | Set records selector active or inactive state by pass the boolean true or false.
`datatable.setSelectedRecords()` | `Deprecated in v5.0.6` Set selected selector checkbox.
`datatable.getSelectedRecords()` | Get selected records.
Returns
jQuery element of selected record rows.
`datatable.search(value, column)` | Execute search method to filter datatable records.
Input Parameters
Name | Type | Description
--- | --- | ---
`value` | `string` | Value to filter.
`column` | `string` | Column field name which defined in options config.
`datatable.setDataSourceParam(param, value)` | Modify the datasource parameters and save it in datatable state. Must be call `datatable.load()` to load new modified datasource and rerender table.
Input Parameters
Name | Type | Description
--- | --- | ---
`param` | `string` | Param key value. Can accept pagination, sort, query.
`value` | `string` | The string value of param.
`datatable.getDataSourceParam(param)` | Get current datasource parameters by param type of pagination, sort, or query.
Input Parameters
Name | Type | Description
--- | --- | ---
`param` | `string` | Param key value. Can accept pagination, sort, query.
`datatable.getDataSourceQuery()` | A helper function shortcut to `datatable.getDataSourceParam('query')`. Get current query datasource parameter.
Returns
    {
      pagination: {
        field: "ShipDate",
        page: 1,
        pages: 18,
        perpage: 20,
        sort: "asc",
        total: 350
      },
      query: {
      },
      sort: {
        sort: "asc",
        field: "ShipDate"
      }
    }
`datatable.getCurrentPage()` | Get current selected page number
Returns
`number`
`datatable.getPageSize()` | Get current selected page size number.
Returns
`number`
`datatable.getTotalRows()` | Get total rows of record.
Returns
`number`
`datatable.hideColumn(columnName)` | `Deprecated in v5.0.6` Hide column by column's field name.
Input Parameters
Name | Type | Description
--- | --- | ---
`fieldName` | `string` | Field name of the column defined in initialized options.
`datatable.showColumn(columnName)` | `Deprecated in v5.0.6` Show column by column's field name.
Input Parameters
Name | Type | Description
--- | --- | ---
`fieldName` | `string` | Field name of the column defined in initialized options.
`datatable.table()` | Return the jQuery element of the table
`datatable.row(selector)` | Select a single row from the table by css selector. The method return datatable instance.
Input Parameters
Name | Type | Description
--- | --- | ---
`selector` | `string` | Class name, id attribute or tag name.
`datatable.rows(selector)` | Select multiple rows from the table by css selector. The method return datatable instance.
Input Parameters
Name | Type | Description
--- | --- | ---
`selector` | `string` | Class name, id attribute or tag name.
`datatable.column(index)` | Select a single column from the table index. The method return datatable instance.
Input Parameters
Name | Type | Description
--- | --- | ---
`index` | `number` | Zero-based index number.
`datatable.columns(selector)` | Select multiple columns from the table by css selector. The method return datatable instance.
Input Parameters
Name | Type | Description
--- | --- | ---
`selector` | `string` | Class name, id attribute or tag name.
`datatable.remove()` | Delete selected a single row or multiples rows. Can be used after selector methods `row(selector)` or `rows(selector)`.
`datatable.visible(visibility)` | Set the visibility of selected rows or columns. Can be used after selector methods `row(selector)` or `rows(selector)`.
Input Parameters
Name | Type | Description
--- | --- | ---
`visibility` | `boolean` | Set `true` to visible, and `false` to hide.
`datatable.nodes()` | Return nodes of the selected rows or columns. Can be used after selector methods `row(selector)` or `rows(selector)`.

### Ajax Response

Below is the sample ajax response from back-end for the remote source datatable.

    {
        "meta": {
            "page": 1,
            "pages": 35,
            "perpage": 10,
            "total": 350,
            "sort": "asc",
            "field": "ShipDate"
        },
        "data": [
            {
                "RecordID": 10,
                "OrderID": "55154-5393",
                "ShipCountry": "NG",
                "ShipCity": "Sapele",
                "ShipName": "Moen, Kertzmann and Mills",
                "ShipAddress": "1 Nancy Junction",
                "CompanyEmail": "epere9@sina.com.cn",
                "CompanyAgent": "Ely Pere",
                "CompanyName": "Jacobi, O'Conner and Kuhlman",
                "Currency": "NGN",
                "Notes": "adipiscing molestie hendrerit at vulputate vitae nisl aenean lectus pellentesque eget nunc donec quis orci eget orci vehicula",
                "Department": "Shoes",
                "Website": "whitehouse.gov",
                "Latitude": 5.8750769,
                "Longitude": 5.6931356,
                "ShipDate": "1\/1\/2016",
                "PaymentDate": "2017-06-20 10:42:35",
                "TimeZone": "Africa\/Lagos",
                "Status": 3,
                "Type": 1,
                "TotalPayment": "88,211.68 NGN"
            },
            {
                "RecordID": 263,
                "OrderID": "43406-0032",
                "ShipCountry": "US",
                "ShipCity": "Fort Pierce",
                "ShipName": "Moore-Schaden",
                "ShipAddress": "451 Fuller Junction",
                "CompanyEmail": "tdefau7a@google.pl",
                "CompanyAgent": "Tristan Defau",
                "CompanyName": "Mayer and Sons",
                "Currency": "USD",
                "Notes": "mauris enim leo rhoncus sed vestibulum sit amet cursus id turpis integer aliquet massa id lobortis convallis tortor risus",
                "Department": "Music",
                "Website": "cornell.edu",
                "Latitude": 27.3980151,
                "Longitude": -80.3714326,
                "ShipDate": "1\/1\/2017",
                "PaymentDate": "2017-05-21 01:45:57",
                "TimeZone": "America\/New_York",
                "Status": 2,
                "Type": 2,
                "TotalPayment": "7,105.23 USD"
            },
            {
                "RecordID": 77,
                "OrderID": "68016-527",
                "ShipCountry": "PH",
                "ShipCity": "Batarasa",
                "ShipName": "Gibson Inc",
                "ShipAddress": "948 Roxbury Center",
                "CompanyEmail": "smatitiaho24@dailymotion.com",
                "CompanyAgent": "Skippy Matitiaho",
                "CompanyName": "Monahan, Haley and Murphy",
                "Currency": "PHP",
                "Notes": "sit amet consectetuer adipiscing elit proin risus praesent lectus vestibulum quam sapien varius",
                "Department": "Jewelery",
                "Website": "printfriendly.com",
                "Latitude": 8.5015747,
                "Longitude": 117.3557854,
                "ShipDate": "1\/12\/2017",
                "PaymentDate": "2016-09-07 16:34:55",
                "TimeZone": "Asia\/Manila",
                "Status": 1,
                "Type": 3,
                "TotalPayment": "9,541.82 PHP"
            },
            {
                "RecordID": 330,
                "OrderID": "54868-5303",
                "ShipCountry": "PH",
                "ShipCity": "Sillon",
                "ShipName": "Balistreri Group",
                "ShipAddress": "8203 Truax Center",
                "CompanyEmail": "kvickarman95@storify.com",
                "CompanyAgent": "Kipp Vickarman",
                "CompanyName": "Kerluke and Sons",
                "Currency": "PHP",
                "Notes": "lobortis ligula sit amet eleifend pede libero quis orci nullam molestie",
                "Department": "Clothing",
                "Website": "vkontakte.ru",
                "Latitude": 11.186148,
                "Longitude": 123.7487563,
                "ShipDate": "1\/14\/2017",
                "PaymentDate": "2017-05-16 18:29:45",
                "TimeZone": "Asia\/Manila",
                "Status": 6,
                "Type": 1,
                "TotalPayment": "8,300.97 PHP"
            },
            {
                "RecordID": 51,
                "OrderID": "49884-659",
                "ShipCountry": "ID",
                "ShipCity": "Atap",
                "ShipName": "Blanda Group",
                "ShipAddress": "1 Monica Alley",
                "CompanyEmail": "sjackes1e@reuters.com",
                "CompanyAgent": "Shelagh Jackes",
                "CompanyName": "Schiller Inc",
                "Currency": "IDR",
                "Notes": "iaculis justo in hac habitasse platea dictumst etiam faucibus cursus",
                "Department": "Jewelery",
                "Website": "forbes.com",
                "Latitude": 3.8152026,
                "Longitude": 117.1147095,
                "ShipDate": "1\/15\/2016",
                "PaymentDate": "2016-06-24 03:01:19",
                "TimeZone": "Asia\/Makassar",
                "Status": 2,
                "Type": 1,
                "TotalPayment": "8,397.18 IDR"
            },
            {
                "RecordID": 313,
                "OrderID": "23155-179",
                "ShipCountry": "PA",
                "ShipCity": "Potrero Grande",
                "ShipName": "Olson, Schmeler and Little",
                "ShipAddress": "3 Bartillon Place",
                "CompanyEmail": "cgrandison8o@auda.org.au",
                "CompanyAgent": "Corliss Grandison",
                "CompanyName": "Mills-Beatty",
                "Currency": "PAB",
                "Notes": "egestas metus aenean fermentum donec ut mauris eget massa tempor convallis nulla neque libero convallis eget eleifend",
                "Department": "Clothing",
                "Website": "mlb.com",
                "Latitude": 8.881634,
                "Longitude": -79.8268729,
                "ShipDate": "1\/16\/2016",
                "PaymentDate": "2017-12-06 10:30:59",
                "TimeZone": "America\/Panama",
                "Status": 3,
                "Type": 2,
                "TotalPayment": "85,706.89 PAB"
            },
            {
                "RecordID": 153,
                "OrderID": "53341-515",
                "ShipCountry": "MD",
                "ShipCity": "Saharna",
                "ShipName": "Leffler, Sawayn and Denesik",
                "ShipAddress": "07247 Del Sol Hill",
                "CompanyEmail": "fshank48@spotify.com",
                "CompanyAgent": "Findley Shank",
                "CompanyName": "Reilly LLC",
                "Currency": "MDL",
                "Notes": "dui nec nisi volutpat eleifend donec ut dolor morbi vel lectus in quam fringilla rhoncus mauris enim leo",
                "Department": "Industrial",
                "Website": "discuz.net",
                "Latitude": 47.6949791,
                "Longitude": 28.9654659,
                "ShipDate": "1\/17\/2016",
                "PaymentDate": "2017-01-05 15:53:50",
                "TimeZone": "Europe\/Chisinau",
                "Status": 6,
                "Type": 1,
                "TotalPayment": "993,295.17 MDL"
            },
            {
                "RecordID": 112,
                "OrderID": "50580-198",
                "ShipCountry": "PT",
                "ShipCity": "Loureiro",
                "ShipName": "Labadie, Hegmann and Jones",
                "ShipAddress": "9986 Arapahoe Place",
                "CompanyEmail": "bglaister33@bbb.org",
                "CompanyAgent": "Baxie Glaister",
                "CompanyName": "Stark, Haley and Koepp",
                "Currency": "EUR",
                "Notes": "suspendisse potenti in eleifend quam a odio in hac habitasse platea dictumst maecenas",
                "Department": "Tools",
                "Website": "apple.com",
                "Latitude": 41.4808684,
                "Longitude": -8.3624629,
                "ShipDate": "1\/17\/2016",
                "PaymentDate": "2016-04-24 01:53:42",
                "TimeZone": "Europe\/Lisbon",
                "Status": 3,
                "Type": 3,
                "TotalPayment": "9,705.78 EUR"
            },
            {
                "RecordID": 29,
                "OrderID": "30142-106",
                "ShipCountry": "RU",
                "ShipCity": "Loukhi",
                "ShipName": "Klein-Streich",
                "ShipAddress": "61 Cascade Plaza",
                "CompanyEmail": "mgallamores@businesswire.com",
                "CompanyAgent": "Minor Gallamore",
                "CompanyName": "Huels-Strosin",
                "Currency": "RUB",
                "Notes": "sollicitudin ut suscipit a feugiat et eros vestibulum ac est lacinia nisi venenatis tristique",
                "Department": "Beauty",
                "Website": "epa.gov",
                "Latitude": 66.0733463,
                "Longitude": 33.0544476,
                "ShipDate": "1\/17\/2016",
                "PaymentDate": "2016-03-09 04:40:38",
                "TimeZone": "Europe\/Moscow",
                "Status": 2,
                "Type": 2,
                "TotalPayment": "931,956.17 RUB"
            },
            {
                "RecordID": 135,
                "OrderID": "49348-387",
                "ShipCountry": "FR",
                "ShipCity": "Sens",
                "ShipName": "Collins, Hackett and Vandervort",
                "ShipAddress": "594 Hanover Crossing",
                "CompanyEmail": "tkiezler3q@live.com",
                "CompanyAgent": "Tommy Kiezler",
                "CompanyName": "Eichmann and Sons",
                "Currency": "EUR",
                "Notes": "etiam faucibus cursus urna ut tellus nulla ut erat id mauris vulputate elementum nullam varius nulla facilisi",
                "Department": "Toys",
                "Website": "instagram.com",
                "Latitude": 48.1903349,
                "Longitude": 3.2995005,
                "ShipDate": "1\/18\/2017",
                "PaymentDate": "2016-12-28 03:56:57",
                "TimeZone": "Europe\/Paris",
                "Status": 2,
                "Type": 2,
                "TotalPayment": "811,814.44 EUR"
            }
        ]
    }

Field | Type | Description
--- | --- | ---
`meta` | `object` | Meta object should contain the metadata that required for the datatable pagination to work.
`meta.page` | `number` | The current page number.
`meta.pages` | `number` | Total number of pages available in the server.
`meta.perpage` | `number` | Total records per page.
`meta.total` | `number` | Total all records number available in the server
`meta.sort` | `string` | Sort type `asc` for ascending and `desc` for descending.
`meta.field` | `string` | Field name which the sort should be applied to.
`data` | `array` | Array of objects.

### Extensions

The datatable can be enhanced by extensions, which give new user interaction and configuration options.

###### Checkbox

Checkbox extension is use for the checkbox selector logic. Below is the default options.

    var datatableOptions = {
       ...
       extensions: {
          checkbox: {
             vars: {
               selectedAllRows: 'selectedAllRows',
               requestIds: 'requestIds',
               rowIds: 'meta.rowIds',
             },
          },
       }
       ...
    };

Field | Type | Description
--- | --- | ---
`vars.selectedAllRows` | `string` | Flag params for selected all rows, to be sent to the server in the request.
`vars.requestIds` | `string` | Enable to request the all rows IDs from server.
`vars.rowIds` | `string` | Response path for all rows IDs in the server response.

### Keen’s Key Features

Keen empowers your project with virtually limitless array of options
to create endless unique projects.

- Based On Bootstrap 4.x
- Multi-Demo Concept
- Enterprise Ready Architect
- Integrated Build Tools: Gulp, NPM, Yarn, SASS
- Full RTL Support
- Included Classic(without build tool) Version
- Enterprise Ready Core Framework
- Full SASS Support
- Re-Usable Component System
- And many more...

> We truly hope that our love and dedication to produce an incredibly powerful high level solution suits all your project needs. We will continue to deliver incredible enterprise ready solutions for Angular, React and VueJS to serve you better. We sincerely hope you enjoyed using Keen as much as we enjoyed building it.

> Sean, Keenthemes Co-Author