| Version | Date | Notes | By |
|---|---|---|---|
| 0.3 | 2017-08-28 | Changes to selectable variable | ROB |
| 0.2 | 2017-02-27 | Changes mad to the edit/destroy route | JFM |
| 0.1 | 2017-01-31 | Initial release | FPA |
This document will quickly guide you through the configuration and usage of the datatables plugin that will be responsible to render a listing table.
The datatables plugin does not only share the name with the well known DataTables plugin, it is highly inspired by it and was created with the intention of making available most of its functionalities but in a Aurelia way.
This plugin's main responsibility is to communicate with the remote server and retrieve a collection of data to display in a table. Besides that, it also allows to easily sort (in a ascending or descending way) the data based on a given column, filter and paginate the records. In this last matter, it allows the user to define how many records he wants to display at each page.

This is how a typical datatables listing will be looking. The table data will be updated in real-time each time the user takes an action - filter, sort, paginate, etc.
In our view model we only need to add two variables: listingId and datatable.
The first one must contain a unique id that will identify our listing across all application (it is necessary because we can have more than one listing rendered at the same time).
export class ListUsers extends BaseViewModel {
listingId = 'administration-users-listing';
// ... more view-model stuff here
}
The convension assumed for the listingId variable is: module_slug - entity -listing. In our example above. administration is the module slug and users is the entity.
The second variable, datatable, must contain a javascript object that represents the datatable schema. A simple example of the structure this object can have is presented below.
this.datatable = {
repository: this.repository,
edit: 'administration.users.edit',
destroy: 'administration.users.destroy',
actions: [
{
icon: 'icon-file-pdf',
action: (row) => this.openReport(row),
tooltip: 'form.button.export-to-pdf'
},
{
icon: 'icon-file-excel',
action: (row) => this.exportToExcel(row),
tooltip: 'form.button.export-to-excel',
visible: (row) => row.created_by === this.appContainer.authenticatedUser.user.id,
attributes: {
class: ''
}
}
],
buttons: [
{
attributes: { 'data-toggle': 'model' },
label: 'form.button.create_new_f',
icon: 'icon-plus3',
className: 'btn bg-success',
action: () => {
// do something
}
}
],
selectable: true,
sorting: {
column: 0,
direction: 'asc'
},
columns: [
{
data: 'id',
name: 't00_users.id',
title: '#'
},
{
data: 'name',
name: 't00_users.name',
title: 'form.field.name'
},
{
data: 'username',
name: 't00_users.username',
title: 'form.field.username'
},
{
data: 'email',
name: 't00_users.email',
title: 'form.field.email',
type: 'email'
},
{
data: 'role',
name: 't00_role_translations.name',
title: 'form.field.role'
},
{
data: 'created_at',
name: 't00_users.created_at',
title: 'form.field.created_at'
},
{
data: 'status',
name: 't00_user_status_translations.name',
title: 'form.field.status',
type: 'label'
}
]
}
Below is a table of contents describing each property of the schema object.
| Part | Type | Required | Description | Observations |
|---|---|---|---|---|
| repository | Object | Yes | The repository object that will be used to fetch the data from | |
| edit | String / Boolean | No | The route name for the edit page | If only true is passed, datatables assumes that the current route ends with index and the edit route end with edit. That way, datatables gets the current route and replaces index with edit. Alternatively it can be an anonymous function with the pretended logic |
| edit | String / Boolean | No | Option to destroy the record | true to show the option, false of not declared to not show the option. Alternatively it can be an anonymous function with the pretended logic |
| actions | Array | Yes | An array of objects that represents each extra action button | Will be explained in detail later in this page |
| buttons | Array | Yes | An array of objects that represents each extra button | Will be explained in detail later in this page |
| selectable | Boolean / Function | Yes | Indicates if the table will have the first column with the checkboxes, if function is used it will receive the current row as the first parameter and the return must be a boolean | for the function use case, it will allow for controlling the rows on which the checkbox will appear |
| sorting | Object | Yes | An object containing the sorting settings | Will be explained in detail later in this page |
| columns | Array | Yes | An array of objects that define each table column | Will be explained in detail later in this page |
this.datatable = {
// ...
actions: [
{
icon: 'icon-file-pdf',
action: (row) => this.openReport(row),
tooltip: 'form.button.export-to-pdf'
},
{
icon: 'icon-file-excel',
action: (row) => this.exportToExcel(row),
tooltip: 'form.button.export-to-excel',
visible: (row) => row.created_by === this.appContainer.authenticatedUser.user.id,
attributes: {
class: ''
}
}
],
// ...
}
| Part | Type | Required | Description |
|---|---|---|---|
| icon | String | Yes | The icon class |
| action | Function | Yes | An anonymous function that receives the corresponding row and executes something |
| tooltip | String | Yes | The translation slug for the tooltip we want to present |
| visible | Boolean/Function | No | Indicates if the action button will be visible. It can be a boolean or an anonymous function that returns a boolean |
| attributes | Object | No | An object with attributes that will be added to the html element |
this.datatable = {
// ...
buttons: [
{
label: 'form.button.create_new',
icon: 'icon-plus3',
className: 'btn bg-success',
action: () => {
// do something
},
attributes: {
'data-toggle': 'model'
},
}
],
// ...
}
| Part | Type | Required | Description |
|---|---|---|---|
| label | String | Yes | The translation slug for the label we want to present |
| icon | String | Yes | The icon class |
| className | String | Yes | The button class |
| action | Function | Yes | An anonymous function that executes something |
| attributes | Object | No | An object with attributes that will be added to the html element |
this.datatable = {
// ...
sorting: {
column: 0,
direction: 'asc'
},
// ...
}
| Part | Type | Required | Description |
|---|---|---|---|
| column | Integer | Yes | The column index of the column we want to sort by. |
| direction | String | Yes | The sorting direction. asc for ascending or desc for descending |
this.datatable = {
// ...
columns: [
{
data: 'id',
name: 't00_users.id',
title: '#'
},
// ...
{
data: 'status',
name: 't00_user_status_translations.name',
title: 'form.field.status',
type: 'label'
}
]
// ...
}
| Part | Type | Required | Description |
|---|---|---|---|
| data | String | Yes | The object property name that we want to use with this column |
| name | String | Yes | The field name in database - table_name.field_name |
| title | String | Yes | The translation slug for the column title |
| type | String | No | The column content type. It can be null, label or email |
Now that we know what we need to put in our view-model and how to define a datatable schema, to render a table the only code line you will need to put in your view is the following:
<datatable schema.bind="datatable" listing-id.bind="listingId"></datatable>
| Part | Description |
|---|---|
<datatable></datatable> |
The custom element that represents the plugin |
| schema.bind="datatable" | Binds the datatable variable of the view-model to the plugin variable called schema |
| listing-id.bind="listingId" | Binds the listingId variable of the view-model to the plugin variable called listingId |
When using this feature we can optionally use either one or both.
In order to implement activate/deactivate selected:
optionally in the schema:
activateSelected, show or hide activate selected button, by default is hiddendeactivateSelected, show or hide dactivate selected button, by default is hiddenrequired methods to have in the repository that is binded to the schema:
activateSelected, method that call the backenddeactivateSelected, method that call the backendrepository.js:
/**
* Activate given records
*
* @param data
* @returns {*}
*/
activateSelected(data)
{
return this.httpClient.post('administration/modules/activate', data);
}
api.php
Route::post('modules/activate', ['as' => 'api.administration.modules.activate-selected', 'uses' => 'ModulesController@activateSelected']);
Route::post('modules/deactivate', ['as' => 'api.administration.modules.deactivate-selected', 'uses' => 'ModulesController@deactivateSelected']);
controller.php
Import trait to simplify the work:
use WeMake\Sgi\Core\Http\Controllers\Traits\DefaultStatusAction;
Create the necessary methods:
/**
* Activate the selected resources.
*
* @param UpdateStatusRequest $request
* @param Module $model
*
* @return JsonResponse
*/
public function activateSelected(UpdateStatusRequest $request, Module $model): JsonResponse
{
return $this->defaultActivateSelected($request, $model);
}
/**
* Deactivate the selected resources.
*
* @param UpdateStatusRequest $request
* @param Module $model
*
* @return JsonResponse
*/
public function deactivateSelected(UpdateStatusRequest $request, Module $model): JsonResponse
{
return $this->defaultDeactivateSelected($request, $model);
}