A table directive with extended functionality as column sorting, column customizing, paging and filtering.
Basic principle is the usage of optional parameters and callbacks, which offer a really flexible API for customizing the table to you very own needs.
- Copyright:
- Kiwigrid GmbH 2014-2015
- Source:
Examples
<div data-keta-extended-table
data-rows="rows"
data-current-locale="currentLocale"
data-label-add-column="labelAddColumn"
data-disabled-components="disabledComponents"
data-switchable-columns="switchableColumns"
data-group-by-property="groupByProperty"
data-order-by-property="orderByProperty"
data-visible-columns="visibleColumns"
data-header-label-callback="headerLabelCallback"
data-operations-mode="operationsMode"
data-row-sort-enabled="rowSortEnabled"
data-row-sort-criteria="rowSortCriteria"
data-row-sort-order-ascending="rowSortOrderAscending"
data-unsortable-columns="unsortableColumns"
data-action-list="actionList"
data-cell-renderer="cellRenderer"
data-column-class-callback="columnClassCallback"
data-table-class-callback="tableClassCallback"
data-row-class-callback="rowClassCallback"
data-search-input-width-classes="searchInputWidthClasses"
data-selector-width-classes="selectorWidthClasses"
data-pager="pager"
data-search="search"
data-search-wait-ms="waitTime"
data-search-results="searchResults"></div>
angular.module('exampleApp', ['keta.directives.ExtendedTable', 'keta.services.Device'])
.controller('ExampleController', function(
$scope,
ketaExtendedTableConstants, ketaExtendedTableMessageKeys, ketaDeviceConstants) {
// data as array of objects, keys from first element are taken as headers
$scope.rows = [{
guid: 'guid-1',
idName: 'Device 1',
stateDevice: 'OK',
deviceClass: 'class-1'
}, {
guid: 'guid-2',
idName: 'Device 2',
stateDevice: 'ERROR',
deviceClass: 'class-2'
}, {
guid: 'guid-3',
idName: 'Device 3',
stateDevice: 'FATAL',
deviceClass: 'class-3'
}];
// override default-labels if necessary
// get default labels
$scope.labels = ketaExtendedTableMessageKeys;
// use case 1: overwrite specific key
$scope.labels.de_DE['__keta.directives.ExtendedTable_search'] = 'Finde';
// use case 2: add locale
$scope.labels.fr_FR = {
'__keta.directives.ExtendedTable_search': 'Recherche',
'__keta.directives.ExtendedTable_add_column': 'Ajouter colonne',
'__keta.directives.ExtendedTable_remove_column': 'Retirer la colonne',
'__keta.directives.ExtendedTable_sort': 'Sorte',
'__keta.directives.ExtendedTable_no_entries': 'Pas d’entrées'
};
// array of disabled components (default: everything except the table itself is disabled)
$scope.disabledComponents = [
// the table itself
ketaExtendedTableConstants.COMPONENT.TABLE,
// an input field to search throughout the full dataset
ketaExtendedTableConstants.COMPONENT.FILTER,
// a selector to add columns to table
ketaExtendedTableConstants.COMPONENT.SELECTOR,
// a pager to navigate through paged data
ketaExtendedTableConstants.COMPONENT.PAGER
];
// array of switchable columns (empty by default)
// together with selector component the given columns can be removed from
// table and added to table afterwards
// to support grouping in select field an array of objects is required (match is compared by id property)
$scope.switchableColumns = [{
id: 'deviceClass'
}];
// property to group selector by
$scope.groupByProperty = 'column.deviceName';
// property to order selector by
$scope.orderByProperty = 'tagName';
// array of visible columns (full by default)
// use this property to filter out columns like primary keys
$scope.visibleColumns = ['idName', 'stateDevice', 'deviceClass'];
// callback method to specify header labels (instead of using auto-generated ones)
$scope.headerLabelCallback = function(column) {
var mappings = {
idName: 'Name',
stateDevice: 'State',
deviceClass: 'Device Class'
};
return (angular.isDefined(mappings[column])) ? mappings[column] : column;
};
// operations mode ("view" for frontend or "data" for backend)
// by defining operations mode as "view" the directive itself manages sorting,
// paging and filtering; if you just pass a pre-sorted, pre-paged and pre-filtered
// dataset by querying a backend, you have to use "data"
$scope.operationsMode = ketaExtendedTableConstants.OPERATIONS_MODE.VIEW;
// boolean flag to enable or disable row sorting in frontend by showing appropriate icons
$scope.rowSortEnabled = true;
// criteria to sort for as string
$scope.rowSortCriteria = 'idName';
// boolean flag to determine if sort order is ascending (true by default)
$scope.rowSortOrderAscending = true;
// array of columns (empty by default) that should not be sorted
$scope.unsortableColumns = ['idName'];
// Array of actions to render for each row.
// getLink method will be used to construct a link with the help of the row object,
// getLabel is used as callback to retrieve value for title-tag,
// icon is used as icon-class for visualizing the action.
// runAction is a callback-function that will be executed when the user clicks on
// the corresponding button. To use this functionality it is necessary to provide the type-parameter
// with the value 'action'.
// type can have the values 'link' (a normal link with href-attribute will be rendered) or
// 'action' (a link with ng-click attribute to execute a callback will be rendered).
// For simplicity the type-property can be left out. In this case the directive renders
// a normal link-tag (same as type 'link').
// display is an optional callback to return condition for displaying action item based on given row
$scope.actionList = [{
getLink: function(row) {
return 'edit/' + row.guid;
},
getLabel: function() {
return 'Edit';
},
icon: 'glyphicon glyphicon-pencil',
type: ketaExtendedTableConstants.ACTION_LIST_TYPE.LINK
}, {
runAction: function(row) {
console.log('action called with ', row);
},
getLabel: function() {
return 'Remove';
},
icon: 'glyphicon glyphicon-remove'
type: ketaExtendedTableConstants.ACTION_LIST_TYPE.ACTION,
display: function(row) {
return row.type !== 'EnergyManager';
}
}];
// callback method to render each cell individually
// with the help of this method you can overwrite default cell rendering behavior,
// e.g. suppressing output for stateDevice property
$scope.cellRenderer = function(row, column) {
var value = angular.isDefined(row[column]) ? row[column] : null;
if (column === 'stateDevice') {
value = '';
}
return value;
};
// callback method to return class attribute for each column
// in this example together with cellRenderer the deviceState column is
// expressed as just a table data element with css classes
$scope.columnClassCallback = function(row, column, isHeader) {
var columnClass = '';
if (column === 'stateDevice') {
columnClass = 'state';
if (row.state === ketaDeviceConstants.STATE.OK && !isHeader) {
columnClass+= ' state-success';
}
if (row.state === ketaDeviceConstants.STATE.ERROR && !isHeader) {
columnClass+= ' state-warning';
}
if (row.state === ketaDeviceConstants.STATE.FATAL && !isHeader) {
columnClass+= ' state-danger';
}
}
return columnClass;
};
// callback method to return class attribute for each row
$scope.rowClassCallback = function(row, isHeader) {
var rowClass = 'row-is-selected';
if (isHeader) {
rowClass += ' header-row';
} else if (angular.isDefined(row.connected) && row.connected === true) {
rowClass += ' connected';
}
return rowClass;
};
// callback method to return class array for table
$scope.tableClassCallback = function() {
return ['table-striped'];
};
// bootstrap width classes to define the size of the search input
$scope.searchInputWidthClasses = 'col-xs-12 col-sm-6';
// bootstrap width classes to define the size of the selector dropdown
$scope.selectorWidthClasses = 'col-xs-12 col-sm-6 col-md-6 col-lg-6';
// object for pager configuration (total, limit, offset)
// with this configuration object you are able to manage paging
// total is the total number of rows in the dataset
// limit is the number of rows shown per page
// offset is the index in the dataset to start from
var pager = {};
pager[ketaExtendedTableConstants.PAGER.TOTAL] = $scope.allRows.length;
pager[ketaExtendedTableConstants.PAGER.LIMIT] = 5;
pager[ketaExtendedTableConstants.PAGER.OFFSET] = 0;
$scope.pager = pager;
// search term to filter the table
// as two-way-binded property this variable contains the search string
// typed by the user in the frontend and can therefor be used for querying
// the backend, if watched here additionally
$scope.search = null;
// Minimal wait time in milliseconds after last character typed before search kicks-in.
// updates on blur are instant
// default is 0
$scope.waitTime = 500;
// array of search results e.g. for usage in headlines
// defaults to $scope.rows, typically not set directly by controller
//$scope.searchResults = $scope.rows;
});