/*
* Gijgo Grid v1.9.13
* http://gijgo.com/grid
*
* Copyright 2014, 2019 gijgo.com
* Released under the MIT license
*/
/* global window alert jQuery gj */
/**
*/
gj.grid = {
plugins: {},
messages: {}
};
gj.grid.config = {
base: {
/** The data source for the grid.
*/
dataSource: undefined,
/** An array that holds the configurations of each column from the grid.
*/
columns: [],
/** Auto generate column for each field in the datasource when set to true.
*/
autoGenerateColumns: false,
/** An object that holds the default configuration settings of each column from the grid.
*/
defaultColumnSettings: {
/** If set to true the column will not be displayed in the grid. By default all columns are displayed.
*/
hidden: false,
/** The width of the column. Numeric values are treated as pixels.
* If the width is undefined the width of the column is not set and depends on the with of the table(grid).
*/
width: undefined,
/** Indicates if the column is sortable.
* If set to true the user can click the column header and sort the grid by the column source field.
*/
sortable: false,
/** Indicates the type of the column.
*/
type: 'text',
/** The caption that is going to be displayed in the header of the grid.
*/
title: undefined,
/** The field name to which the column is bound.
* If the column.title is not defined this value is used as column.title.
*/
field: undefined,
/** This setting control the alignment of the text in the cell.
*/
align: undefined,
/** The name(s) of css class(es) that are going to be applied to all cells inside that column, except the header cell.
*/
cssClass: undefined,
/** The name(s) of css class(es) that are going to be applied to the header cell of that column.
*/
headerCssClass: undefined,
/** The text for the cell tooltip.
*/
tooltip: undefined,
/** Css class for icon that is going to be in use for the cell.
* This setting can be in use only with combination of type icon.
*/
icon: undefined,
/** Configuration object with event names as keys and functions as values that are going to be bind to each cell from the column.
* Each function is going to receive event information as a parameter with info in the 'data' field for id, field name and record data.
*/
events: undefined,
/** Format the date when the type of the column is date.
*/
format: 'mm/dd/yyyy',
/** Number of decimal digits after the decimal point.
*/
decimalDigits: undefined,
/** Template for the content in the column.
* Use curly brackets '{}' to wrap the names of data source columns from server response.
*/
tmpl: undefined,
/** If set to true stop event propagation when event occur.
*/
stopPropagation: false,
/** A renderer is an 'interceptor' function which can be used to transform data (value, appearance, etc.) before it is rendered.
*/
renderer: undefined,
/** Function which can be used to customize filtering with local data (javascript sourced data).
*/
filter: undefined
},
mapping: {
/** The name of the object in the server response, that contains array with records, that needs to be display in the grid.
*/
dataField: 'records',
/** The name of the object in the server response, that contains the number of all records on the server.
*/
totalRecordsField: 'total'
},
params: {},
paramNames: {
/** The name of the parameter that is going to send the name of the column for sorting.
* The "sortable" setting for at least one column should be enabled in order this parameter to be in use.
*/
sortBy: 'sortBy',
/** The name of the parameter that is going to send the direction for sorting.
* The "sortable" setting for at least one column should be enabled in order this parameter to be in use.
*/
direction: 'direction'
},
/** The name of the UI library that is going to be in use. Currently we support Bootstrap 3, Bootstrap 4 and Material Design.
*/
uiLibrary: 'materialdesign',
/** The name of the icons library that is going to be in use. Currently we support Material Icons, Font Awesome and Glyphicons.
*/
iconsLibrary: 'materialicons',
/** The type of the row selection.
* If the type is set to multiple the user will be able to select more then one row from the grid.
*/
selectionType: 'single',
/** The type of the row selection mechanism.
*/
selectionMethod: 'basic',
/** When this setting is enabled the content of the grid will be loaded automatically after the creation of the grid.
*/
autoLoad: true,
/** The text that is going to be displayed if the grid is empty.
*/
notFoundText: undefined,
/** Width of the grid.
*/
width: undefined,
/** Minimum width of the grid.
*/
minWidth: undefined,
/** This configuration option manage the behaviour of the header row height.
* Auto scale if set to to 'autogrow'. All body rows are with the same height if set to 'fixed'.
*/
headerRowHeight: 'fixed',
/** This configuration option manage the behaviour of the body row height.
* Auto scale if set to to 'autogrow'. All body rows are with the same height if set to 'fixed'.
*/
bodyRowHeight: 'autogrow',
/** The size of the font in the grid.
*/
fontSize: undefined,
/** Name of column that contains the record id.
*/
primaryKey: undefined,
/** The language that needs to be in use.
*/
locale: 'en-us',
defaultIconColumnWidth: 70,
defaultCheckBoxColumnWidth: 70,
style: {
wrapper: 'gj-grid-wrapper',
table: 'gj-grid gj-grid-md',
loadingCover: 'gj-grid-loading-cover',
loadingText: 'gj-grid-loading-text',
header: {
cell: undefined,
sortable: 'gj-cursor-pointer gj-unselectable'
},
content: {
rowSelected: 'gj-grid-md-select'
}
},
icons: {
asc: '▲',
desc: '▼'
}
},
bootstrap: {
style: {
wrapper: 'gj-grid-wrapper',
table: 'gj-grid gj-grid-bootstrap gj-grid-bootstrap-3 table table-bordered table-hover',
content: {
rowSelected: 'active'
}
},
iconsLibrary: 'glyphicons',
defaultIconColumnWidth: 34,
defaultCheckBoxColumnWidth: 36
},
bootstrap4: {
style: {
wrapper: 'gj-grid-wrapper',
table: 'gj-grid gj-grid-bootstrap gj-grid-bootstrap-4 table table-bordered table-hover',
content: {
rowSelected: 'active'
}
},
defaultIconColumnWidth: 42,
defaultCheckBoxColumnWidth: 44
},
materialicons: {
icons: {
asc: '',
desc: ''
}
},
fontawesome: {
icons: {
asc: '',
desc: ''
}
},
glyphicons: {
icons: {
asc: '',
desc: ''
}
}
};
/**
*/
gj.grid.events = {
/**
* Event fires before addition of an empty row to the grid.
*/
beforeEmptyRowInsert: function ($grid, $row) {
return $grid.triggerHandler('beforeEmptyRowInsert', [$row]);
},
/**
* Event fired before data binding takes place.
*
*/
dataBinding: function ($grid, records) {
return $grid.triggerHandler('dataBinding', [records]);
},
/**
* Event fires after the loading of the data in the grid.
*
*/
dataBound: function ($grid, records, totalRecords) {
return $grid.triggerHandler('dataBound', [records, totalRecords]);
},
/**
* Event fires after insert of a row in the grid during the loading of the data.
*/
rowDataBound: function ($grid, $row, id, record) {
return $grid.triggerHandler('rowDataBound', [$row, id, record]);
},
/**
* Event fires after insert of a cell in the grid during the loading of the data
*
*/
cellDataBound: function ($grid, $displayEl, id, column, record) {
return $grid.triggerHandler('cellDataBound', [$displayEl, id, column, record]);
},
/**
* Event fires on selection of row
*
*/
rowSelect: function ($grid, $row, id, record) {
return $grid.triggerHandler('rowSelect', [$row, id, record]);
},
/**
* Event fires on un selection of row
*
*/
rowUnselect: function ($grid, $row, id, record) {
return $grid.triggerHandler('rowUnselect', [$row, id, record]);
},
/**
* Event fires before deletion of row in the grid.
*/
rowRemoving: function ($grid, $row, id, record) {
return $grid.triggerHandler('rowRemoving', [$row, id, record]);
},
/**
* Event fires when the grid.destroy method is called.
*
*/
destroying: function ($grid) {
return $grid.triggerHandler('destroying');
},
/**
* Event fires when column is hidding
*
*/
columnHide: function ($grid, column) {
return $grid.triggerHandler('columnHide', [column]);
},
/**
* Event fires when column is showing
*
*/
columnShow: function ($grid, column) {
return $grid.triggerHandler('columnShow', [column]);
},
/**
* Event fires when grid is initialized.
*
*/
initialized: function ($grid) {
return $grid.triggerHandler('initialized');
},
/**
* Event fires when the grid data is filtered.
*
*/
dataFiltered: function ($grid, records) {
return $grid.triggerHandler('dataFiltered', [records]);
}
};
/*global gj $*/
gj.grid.methods = {
init: function (jsConfig) {
gj.widget.prototype.init.call(this, jsConfig, 'grid');
gj.grid.methods.initialize(this);
if (this.data('autoLoad')) {
this.reload();
}
return this;
},
getConfig: function (jsConfig, type) {
var config = gj.widget.prototype.getConfig.call(this, jsConfig, type);
gj.grid.methods.setDefaultColumnConfig(config.columns, config.defaultColumnSettings);
return config;
},
setDefaultColumnConfig: function (columns, defaultColumnSettings) {
var column, i;
if (columns && columns.length) {
for (i = 0; i < columns.length; i++) {
column = $.extend(true, {}, defaultColumnSettings);
$.extend(true, column, columns[i]);
columns[i] = column;
}
}
},
getHTMLConfig: function () {
var result = gj.widget.prototype.getHTMLConfig.call(this);
result.columns = [];
this.find('thead > tr > th').each(function () {
var $el = $(this),
title = $el.text(),
config = gj.widget.prototype.getHTMLConfig.call($el);
config.title = title;
if (!config.field) {
config.field = title;
}
if (config.events) {
config.events = gj.grid.methods.eventsParser(config.events);
}
result.columns.push(config);
});
return result;
},
eventsParser: function (events) {
var result = {}, list, i, key, func, position;
list = events.split(',');
for (i = 0; i < list.length; i++) {
position = list[i].indexOf(':');
if (position > 0) {
key = $.trim(list[i].substr(0, position));
func = $.trim(list[i].substr(position + 1, list[i].length));
result[key] = eval('window.' + func); //window[func]; //TODO: eveluate functions from string
}
}
return result;
},
initialize: function ($grid) {
var data = $grid.data(),
$wrapper = $grid.parent('div[data-role="wrapper"]');
gj.grid.methods.localization(data);
if ($wrapper.length === 0) {
$wrapper = $('
').addClass(data.style.wrapper); //The css class needs to be added before the wrapping, otherwise doesn't work.
$grid.wrap($wrapper);
} else {
$wrapper.addClass(data.style.wrapper);
}
if (data.width) {
$grid.parent().css('width', data.width);
}
if (data.minWidth) {
$grid.css('min-width', data.minWidth);
}
if (data.fontSize) {
$grid.css('font-size', data.fontSize);
}
if (data.headerRowHeight === 'autogrow') {
$grid.addClass('autogrow-header-row');
}
if (data.bodyRowHeight === 'fixed') {
$grid.addClass('fixed-body-rows');
}
$grid.addClass(data.style.table);
if ('checkbox' === data.selectionMethod) {
data.columns.splice(gj.grid.methods.getColumnPositionNotInRole($grid), 0, {
title: '',
width: data.defaultCheckBoxColumnWidth,
align: 'center',
type: 'checkbox',
role: 'selectRow',
events: {
click: function (e) {
gj.grid.methods.setSelected($grid, e.data.id, $(this).closest('tr'));
}
},
headerCssClass: 'gj-grid-select-all',
stopPropagation: true
});
}
if ($grid.children('tbody').length === 0) {
$grid.append($(''));
}
gj.grid.methods.renderHeader($grid);
gj.grid.methods.appendEmptyRow($grid, ' ');
gj.grid.events.initialized($grid);
},
localization: function (data) {
if (!data.notFoundText) {
data.notFoundText = gj.grid.messages[data.locale].NoRecordsFound;
}
},
renderHeader: function ($grid) {
var data, columns, style, $thead, $row, $cell, $title, i, $checkAllBoxes;
data = $grid.data();
columns = data.columns;
style = data.style.header;
$thead = $grid.children('thead');
if ($thead.length === 0) {
$thead = $('');
$grid.prepend($thead);
}
$row = $('
');
for (i = 0; i < columns.length; i += 1) {
$cell = $('
');
if (columns[i].width) {
$cell.attr('width', columns[i].width);
} else if (columns[i].type === 'checkbox') {
$cell.attr('width', data.defaultIconColumnWidth);
}
$cell.addClass(style.cell);
if (columns[i].headerCssClass) {
$cell.addClass(columns[i].headerCssClass);
}
$cell.css('text-align', columns[i].align || 'left');
if ('checkbox' === data.selectionMethod && 'multiple' === data.selectionType &&
'checkbox' === columns[i].type && 'selectRow' === columns[i].role) {
$checkAllBoxes = $cell.find('input[data-role="selectAll"]');
if ($checkAllBoxes.length === 0) {
$checkAllBoxes = $('');
$cell.append($checkAllBoxes);
$checkAllBoxes.checkbox({ uiLibrary: data.uiLibrary });
}
$checkAllBoxes.off('click').on('click', function () {
if (this.checked) {
$grid.selectAll();
} else {
$grid.unSelectAll();
}
});
} else {
$title = $('').html(typeof (columns[i].title) === 'undefined' ? columns[i].field : columns[i].title);
$cell.append($title);
if (columns[i].sortable) {
$title.addClass(style.sortable);
$title.on('click', gj.grid.methods.createSortHandler($grid, columns[i]));
}
}
if (columns[i].hidden) {
$cell.hide();
}
$row.append($cell);
}
$thead.empty().append($row);
},
createSortHandler: function ($grid, column) {
return function () {
var data, params = {};
if ($grid.count() > 0) {
data = $grid.data();
params[data.paramNames.sortBy] = column.field;
column.direction = (column.direction === 'asc' ? 'desc' : 'asc');
params[data.paramNames.direction] = column.direction;
$grid.reload(params);
}
};
},
updateHeader: function ($grid) {
var $sortIcon, $cellTitle,
data = $grid.data(),
sortBy = data.params[data.paramNames.sortBy],
direction = data.params[data.paramNames.direction];
$grid.find('thead tr th [data-role="sorticon"]').remove();
if (sortBy) {
position = gj.grid.methods.getColumnPosition($grid.data('columns'), sortBy);
if (position > -1) {
$cellTitle = $grid.find('thead tr th:eq(' + position + ') div[data-role="title"]');
$sortIcon = $('').append(('desc' === direction) ? data.icons.desc : data.icons.asc);
$cellTitle.after($sortIcon);
}
}
},
useHtmlDataSource: function ($grid, data) {
var dataSource = [], i, j, $cells, record,
$rows = $grid.find('tbody tr[data-role != "empty"]');
for (i = 0; i < $rows.length; i++) {
$cells = $($rows[i]).find('td');
record = {};
for (j = 0; j < $cells.length; j++) {
record[data.columns[j].field] = $($cells[j]).html();
}
dataSource.push(record);
}
data.dataSource = dataSource;
},
startLoading: function ($grid) {
var $tbody, $cover, $loading, width, height, top, data;
gj.grid.methods.stopLoading($grid);
data = $grid.data();
if (0 === $grid.outerHeight()) {
return;
}
$tbody = $grid.children('tbody');
width = $tbody.outerWidth(false);
height = $tbody.outerHeight(false);
top = Math.abs($grid.parent().offset().top - $tbody.offset().top);
$cover = $('').addClass(data.style.loadingCover).css({
width: width,
height: height,
top: top
});
$loading = $('
' + gj.grid.messages[data.locale].Loading + '
').addClass(data.style.loadingText);
$loading.insertAfter($grid);
$cover.insertAfter($grid);
$loading.css({
top: top + (height / 2) - ($loading.outerHeight(false) / 2),
left: (width / 2) - ($loading.outerWidth(false) / 2)
});
},
stopLoading: function ($grid) {
$grid.parent().find('div[data-role="loading-cover"]').remove();
$grid.parent().find('div[data-role="loading-text"]').remove();
},
appendEmptyRow: function ($grid, caption) {
var data, $row, $cell, $wrapper;
data = $grid.data();
$row = $('
');
$cell = $('
').css({ width: '100%', 'text-align': 'center' });
$cell.attr('colspan', gj.grid.methods.countVisibleColumns($grid));
$wrapper = $('').html(caption || data.notFoundText);
$cell.append($wrapper);
$row.append($cell);
gj.grid.events.beforeEmptyRowInsert($grid, $row);
$grid.append($row);
},
autoGenerateColumns: function ($grid, records) {
var names, value, type, i, data = $grid.data();
data.columns = [];
if (records.length > 0) {
names = Object.getOwnPropertyNames(records[0]);
for (i = 0; i < names.length; i++) {
value = records[0][names[i]];
type = 'text';
if (value) {
if (typeof value === 'number') {
type = 'number';
} else if (value.indexOf('/Date(') > -1) {
type = 'date';
}
}
data.columns.push({ field: names[i], type: type });
}
gj.grid.methods.setDefaultColumnConfig(data.columns, data.defaultColumnSettings);
}
gj.grid.methods.renderHeader($grid);
},
loadData: function ($grid) {
var data, records, i, recLen, rowCount, $tbody, $rows, $row;
data = $grid.data();
records = $grid.getAll();
gj.grid.events.dataBinding($grid, records);
recLen = records.length;
gj.grid.methods.stopLoading($grid);
if (data.autoGenerateColumns) {
gj.grid.methods.autoGenerateColumns($grid, records);
}
$tbody = $grid.children('tbody');
if ('checkbox' === data.selectionMethod && 'multiple' === data.selectionType) {
$grid.find('thead input[data-role="selectAll"]').prop('checked', false);
}
$tbody.children('tr').not('[data-role="row"]').remove();
if (0 === recLen) {
$tbody.empty();
gj.grid.methods.appendEmptyRow($grid);
}
$rows = $tbody.children('tr');
rowCount = $rows.length;
for (i = 0; i < rowCount; i++) {
if (i < recLen) {
$row = $rows.eq(i);
gj.grid.methods.renderRow($grid, $row, records[i], i);
} else {
$tbody.find('tr[data-role="row"]:gt(' + (i - 1) + ')').remove();
break;
}
}
for (i = rowCount; i < recLen; i++) {
gj.grid.methods.renderRow($grid, null, records[i], i);
}
gj.grid.events.dataBound($grid, records, data.totalRecords);
},
getId: function (record, primaryKey, position) {
return (primaryKey && record[primaryKey]) ? record[primaryKey] : position;
},
renderRow: function ($grid, $row, record, position) {
var id, $cell, i, data, mode;
data = $grid.data();
if (!$row || $row.length === 0) {
mode = 'create';
$row = $('
');
$grid.children('tbody').append($row);
} else {
mode = 'update';
$row.removeClass(data.style.content.rowSelected).removeAttr('data-selected').off('click');
}
id = gj.grid.methods.getId(record, data.primaryKey, (position + 1));
$row.attr('data-position', position + 1);
if (data.selectionMethod !== 'checkbox') {
$row.on('click', gj.grid.methods.createRowClickHandler($grid, id));
}
for (i = 0; i < data.columns.length; i++) {
if (mode === 'update') {
$cell = $row.find('td:eq(' + i + ')');
gj.grid.methods.renderCell($grid, $cell, data.columns[i], record, id);
} else {
$cell = gj.grid.methods.renderCell($grid, null, data.columns[i], record, id);
$row.append($cell);
}
}
gj.grid.events.rowDataBound($grid, $row, id, record);
},
renderCell: function ($grid, $cell, column, record, id, mode) {
var $displayEl, key;
if (!$cell || $cell.length === 0) {
$cell = $('
');
$displayEl = $('');
column.align && $cell.css('text-align', column.align);
column.cssClass && $cell.addClass(column.cssClass);
$cell.append($displayEl);
mode = 'create';
} else {
$displayEl = $cell.find('div[data-role="display"]');
mode = 'update';
}
gj.grid.methods.renderDisplayElement($grid, $displayEl, column, record, id, mode);
//remove all event handlers
if ('update' === mode) {
$cell.off();
$displayEl.off();
}
if (column.events) {
for (key in column.events) {
if (column.events.hasOwnProperty(key)) {
$cell.on(key, { id: id, field: column.field, record: record }, gj.grid.methods.createCellEventHandler(column, column.events[key]));
}
}
}
if (column.hidden) {
$cell.hide();
}
gj.grid.events.cellDataBound($grid, $displayEl, id, column, record);
return $cell;
},
createCellEventHandler: function (column, func) {
return function (e) {
if (column.stopPropagation) {
e.stopPropagation();
}
func.call(this, e);
};
},
renderDisplayElement: function ($grid, $displayEl, column, record, id, mode) {
var text, $checkbox;
if ('checkbox' === column.type && gj.checkbox) {
if ('create' === mode) {
$checkbox = $('').val(id).prop('checked', (record[column.field] ? true : false));
column.role && $checkbox.attr('data-role', column.role);
$displayEl.append($checkbox);
$checkbox.checkbox({ uiLibrary: $grid.data('uiLibrary') });
if (column.role === 'selectRow') {
$checkbox.on('click', function () { return false; });
} else {
$checkbox.prop('disabled', true);
}
} else {
$displayEl.find('input[type="checkbox"]').val(id).prop('checked', (record[column.field] ? true : false));
}
} else if ('icon' === column.type) {
if ('create' === mode) {
$displayEl.append($('').addClass(column.icon).css({ cursor: 'pointer' }));
$grid.data().uiLibrary === 'bootstrap' && $displayEl.children('span').addClass('glyphicon');
column.stopPropagation = true;
}
} else if (column.tmpl) {
text = column.tmpl;
column.tmpl.replace(/\{(.+?)\}/g, function ($0, $1) {
text = text.replace($0, gj.grid.methods.formatText(record[$1], column));
});
$displayEl.html(text);
} else if (column.renderer && typeof (column.renderer) === 'function') {
text = column.renderer(record[column.field], record, $displayEl.parent(), $displayEl, id, $grid);
if (text) {
$displayEl.html(text);
}
} else {
record[column.field] = gj.grid.methods.formatText(record[column.field], column);
if (!column.tooltip && record[column.field]) {
$displayEl.attr('title', record[column.field]);
}
$displayEl.html(record[column.field]);
}
if (column.tooltip && 'create' === mode) {
$displayEl.attr('title', column.tooltip);
}
},
formatText: function (text, column) {
if (text && ['date', 'time', 'datetime'].indexOf(column.type) > -1) {
text = gj.core.formatDate(gj.core.parseDate(text, column.format), column.format);
} else {
text = (typeof (text) === 'undefined' || text === null) ? '' : text.toString();
}
if (column.decimalDigits && text) {
text = parseFloat(text).toFixed(column.decimalDigits);
}
return text;
},
setRecordsData: function ($grid, response) {
var records = [],
totalRecords = 0,
data = $grid.data();
if ($.isArray(response)) {
records = response;
totalRecords = response.length;
} else if (data && data.mapping && $.isArray(response[data.mapping.dataField])) {
records = response[data.mapping.dataField];
totalRecords = response[data.mapping.totalRecordsField];
if (!totalRecords || isNaN(totalRecords)) {
totalRecords = 0;
}
}
$grid.data('records', records);
$grid.data('totalRecords', totalRecords);
return records;
},
createRowClickHandler: function ($grid, id) {
return function () {
gj.grid.methods.setSelected($grid, id, $(this));
};
},
selectRow: function ($grid, data, $row, id) {
var $checkbox;
$row.addClass(data.style.content.rowSelected);
$row.attr('data-selected', 'true');
if ('checkbox' === data.selectionMethod) {
$checkbox = $row.find('input[type="checkbox"][data-role="selectRow"]');
$checkbox.length && !$checkbox.prop('checked') && $checkbox.prop('checked', true);
if ('multiple' === data.selectionType && $grid.getSelections().length === $grid.count(false)) {
$grid.find('thead input[data-role="selectAll"]').prop('checked', true);
}
}
return gj.grid.events.rowSelect($grid, $row, id, $grid.getById(id));
},
unselectRow: function ($grid, data, $row, id) {
var $checkbox;
if ($row.attr('data-selected') === 'true') {
$row.removeClass(data.style.content.rowSelected);
if ('checkbox' === data.selectionMethod) {
$checkbox = $row.find('td input[type="checkbox"][data-role="selectRow"]');
$checkbox.length && $checkbox.prop('checked') && $checkbox.prop('checked', false);
if ('multiple' === data.selectionType) {
$grid.find('thead input[data-role="selectAll"]').prop('checked', false);
}
}
$row.removeAttr('data-selected');
return gj.grid.events.rowUnselect($grid, $row, id, $grid.getById(id));
}
},
setSelected: function ($grid, id, $row) {
var data = $grid.data();
if (!$row || !$row.length) {
$row = gj.grid.methods.getRowById($grid, id);
}
if ($row) {
if ($row.attr('data-selected') === 'true') {
gj.grid.methods.unselectRow($grid, data, $row, id);
} else {
if ('single' === data.selectionType) {
$row.siblings('[data-selected="true"]').each(function () {
var $row = $(this),
id = gj.grid.methods.getId($row, data.primaryKey, $row.data('position'));
gj.grid.methods.unselectRow($grid, data, $row, id);
});
}
gj.grid.methods.selectRow($grid, data, $row, id);
}
}
return $grid;
},
selectAll: function ($grid) {
var data = $grid.data();
$grid.find('tbody tr[data-role="row"]').each(function () {
var $row = $(this),
position = $row.data('position'),
record = $grid.get(position),
id = gj.grid.methods.getId(record, data.primaryKey, position);
gj.grid.methods.selectRow($grid, data, $row, id);
});
$grid.find('thead input[data-role="selectAll"]').prop('checked', true);
return $grid;
},
unSelectAll: function ($grid) {
var data = $grid.data();
$grid.find('tbody tr').each(function () {
var $row = $(this),
position = $row.data('position'),
record = $grid.get(position),
id = gj.grid.methods.getId(record, data.primaryKey, position);
gj.grid.methods.unselectRow($grid, data, $row, id);
$row.find('input[type="checkbox"][data-role="selectRow"]').prop('checked', false);
});
$grid.find('thead input[data-role="selectAll"]').prop('checked', false);
return $grid;
},
getSelected: function ($grid) {
var result = null, selections, record, position;
selections = $grid.find('tbody>tr[data-selected="true"]');
if (selections.length > 0) {
position = $(selections[0]).data('position');
record = $grid.get(position);
result = gj.grid.methods.getId(record, $grid.data().primaryKey, position);
}
return result;
},
getSelectedRows: function ($grid) {
var data = $grid.data();
return $grid.find('tbody>tr[data-selected="true"]');
},
getSelections: function ($grid) {
var result = [], position, record,
data = $grid.data(),
$selections = gj.grid.methods.getSelectedRows($grid);
if (0 < $selections.length) {
$selections.each(function () {
position = $(this).data('position');
record = $grid.get(position);
result.push(gj.grid.methods.getId(record, data.primaryKey, position));
});
}
return result;
},
getById: function ($grid, id) {
var result = null, i, primaryKey = $grid.data('primaryKey'), records = $grid.data('records');
if (primaryKey) {
for (i = 0; i < records.length; i++) {
if (records[i][primaryKey] == id) {
result = records[i];
break;
}
}
} else {
result = $grid.get(id);
}
return result;
},
getRecVPosById: function ($grid, id) {
var result = id, i, data = $grid.data();
if (data.primaryKey) {
for (i = 0; i < data.dataSource.length; i++) {
if (data.dataSource[i][data.primaryKey] == id) {
result = i;
break;
}
}
}
return result;
},
getRowById: function ($grid, id) {
var records = $grid.getAll(false),
primaryKey = $grid.data('primaryKey'),
$result = undefined,
position,
i;
if (primaryKey) {
for (i = 0; i < records.length; i++) {
if (records[i][primaryKey] == id) {
position = i + 1;
break;
}
}
} else {
position = id;
}
if (position) {
$result = $grid.children('tbody').children('tr[data-position="' + position + '"]');
}
return $result;
},
getByPosition: function ($grid, position) {
return $grid.getAll(false)[position - 1];
},
getColumnPosition: function (columns, field) {
var position = -1, i;
for (i = 0; i < columns.length; i++) {
if (columns[i].field === field) {
position = i;
break;
}
}
return position;
},
getColumnInfo: function ($grid, field) {
var i, result = {}, data = $grid.data();
for (i = 0; i < data.columns.length; i += 1) {
if (data.columns[i].field === field) {
result = data.columns[i];
break;
}
}
return result;
},
getCell: function ($grid, id, field) {
var position, $row, $result = null;
position = gj.grid.methods.getColumnPosition($grid.data('columns'), field);
if (position > -1) {
$row = gj.grid.methods.getRowById($grid, id);
$result = $row.find('td:eq(' + position + ') div[data-role="display"]');
}
return $result;
},
setCellContent: function ($grid, id, field, value) {
var column, $displayEl = gj.grid.methods.getCell($grid, id, field);
if ($displayEl) {
$displayEl.empty();
if (typeof (value) === 'object') {
$displayEl.append(value);
} else {
column = gj.grid.methods.getColumnInfo($grid, field);
gj.grid.methods.renderDisplayElement($grid, $displayEl, column, $grid.getById(id), id, 'update');
}
}
},
clone: function (source) {
var target = [];
$.each(source, function () {
target.push(this.clone());
});
return target;
},
getAll: function ($grid) {
return $grid.data('records');
},
countVisibleColumns: function ($grid) {
var columns, count, i;
columns = $grid.data().columns;
count = 0;
for (i = 0; i < columns.length; i++) {
if (columns[i].hidden !== true) {
count++;
}
}
return count;
},
clear: function ($grid, showNotFoundText) {
var data = $grid.data();
$grid.xhr && $grid.xhr.abort();
$grid.children('tbody').empty();
data.records = [];
gj.grid.methods.stopLoading($grid);
gj.grid.methods.appendEmptyRow($grid, showNotFoundText ? data.notFoundText : ' ');
gj.grid.events.dataBound($grid, [], 0);
return $grid;
},
render: function ($grid, response) {
if (response) {
gj.grid.methods.setRecordsData($grid, response);
gj.grid.methods.updateHeader($grid);
gj.grid.methods.loadData($grid);
}
return $grid;
},
filter: function ($grid) {
var field, column,
data = $grid.data(),
records = data.dataSource.slice();
if (data.params[data.paramNames.sortBy]) {
column = gj.grid.methods.getColumnInfo($grid, data.params[data.paramNames.sortBy]);
records.sort(column.sortable.sorter ? column.sortable.sorter(column.direction, column) : gj.grid.methods.createDefaultSorter(column.direction, column.field));
}
for (field in data.params) {
if (data.params[field] && !data.paramNames[field]) {
column = gj.grid.methods.getColumnInfo($grid, field);
records = $.grep(records, function (record) {
var value = record[field] || '',
searchStr = data.params[field] || '';
return column && typeof (column.filter) === 'function' ? column.filter(value, searchStr) : (value.toUpperCase().indexOf(searchStr.toUpperCase()) > -1);
});
}
}
gj.grid.events.dataFiltered($grid, records);
return records;
},
createDefaultSorter: function (direction, field) {
return function (recordA, recordB) {
var a = (recordA[field] || '').toString(),
b = (recordB[field] || '').toString();
return (direction === 'asc') ? a.localeCompare(b) : b.localeCompare(a);
};
},
destroy: function ($grid, keepTableTag, keepWrapperTag) {
var data = $grid.data();
if (data) {
gj.grid.events.destroying($grid);
gj.grid.methods.stopLoading($grid);
$grid.xhr && $grid.xhr.abort();
$grid.off();
if (keepWrapperTag === false && $grid.parent('div[data-role="wrapper"]').length > 0) {
$grid.unwrap();
}
$grid.removeData();
if (keepTableTag === false) {
$grid.remove();
} else {
$grid.removeClass().empty();
}
$grid.removeAttr('data-type');
}
return $grid;
},
showColumn: function ($grid, field) {
var data = $grid.data(),
position = gj.grid.methods.getColumnPosition(data.columns, field),
$cells;
if (position > -1) {
$grid.find('thead>tr').each(function() {
$(this).children('th').eq(position).show();
});
$.each($grid.find('tbody>tr'), function () {
$(this).children('td').eq(position).show();
});
data.columns[position].hidden = false;
$cells = $grid.find('tbody > tr[data-role="empty"] > td');
if ($cells && $cells.length) {
$cells.attr('colspan', gj.grid.methods.countVisibleColumns($grid));
}
gj.grid.events.columnShow($grid, data.columns[position]);
}
return $grid;
},
hideColumn: function ($grid, field) {
var data = $grid.data(),
position = gj.grid.methods.getColumnPosition(data.columns, field),
$cells;
if (position > -1) {
$grid.find('thead>tr').each(function () {
$(this).children('th').eq(position).hide();
});
$.each($grid.find('tbody>tr'), function () {
$(this).children('td').eq(position).hide();
});
data.columns[position].hidden = true;
$cells = $grid.find('tbody > tr[data-role="empty"] > td');
if ($cells && $cells.length) {
$cells.attr('colspan', gj.grid.methods.countVisibleColumns($grid));
}
gj.grid.events.columnHide($grid, data.columns[position]);
}
return $grid;
},
isLastRecordVisible: function () {
return true;
},
addRow: function ($grid, record) {
var data = $grid.data();
data.totalRecords = $grid.data('totalRecords') + 1;
gj.grid.events.dataBinding($grid, [record]);
data.records.push(record);
if ($.isArray(data.dataSource)) {
data.dataSource.push(record);
}
if (data.totalRecords === 1) {
$grid.children('tbody').empty();
}
if (gj.grid.methods.isLastRecordVisible($grid)) {
gj.grid.methods.renderRow($grid, null, record, $grid.count() - 1);
}
gj.grid.events.dataBound($grid, [record], data.totalRecords);
return $grid;
},
updateRow: function ($grid, id, record) {
var $row = gj.grid.methods.getRowById($grid, id),
data = $grid.data(), position;
data.records[$row.data('position') - 1] = record;
if ($.isArray(data.dataSource)) {
position = gj.grid.methods.getRecVPosById($grid, id);
data.dataSource[position] = record;
}
gj.grid.methods.renderRow($grid, $row, record, $row.index());
return $grid;
},
removeRow: function ($grid, id) {
var position,
data = $grid.data(),
$row = gj.grid.methods.getRowById($grid, id);
gj.grid.events.rowRemoving($grid, $row, id, $grid.getById(id));
if ($.isArray(data.dataSource)) {
position = gj.grid.methods.getRecVPosById($grid, id);
data.dataSource.splice(position, 1);
}
$grid.reload();
return $grid;
},
count: function ($grid, includeAllRecords) {
return includeAllRecords ? $grid.data().totalRecords : $grid.getAll().length;
},
getColumnPositionByRole: function ($grid, role) {
var i, result, columns = $grid.data('columns');
for (i = 0; i < columns.length; i++) {
if (columns[i].role === role) {
result = i;
break;
}
}
return result;
},
getColumnPositionNotInRole: function ($grid) {
var i, result = 0, columns = $grid.data('columns');
for (i = 0; i < columns.length; i++) {
if (!columns[i].role) {
result = i;
break;
}
}
return result;
}
};
/**
*/
gj.grid.widget = function ($grid, jsConfig) {
var self = this,
methods = gj.grid.methods;
/**
* Reload the data in the grid from a data source.
*/
self.reload = function (params) {
methods.startLoading(this);
return gj.widget.prototype.reload.call(this, params);
};
/**
* Clear the content in the grid.
*/
self.clear = function (showNotFoundText) {
return methods.clear(this, showNotFoundText);
};
/**
* Return the number of records in the grid. By default return only the records that are visible in the grid.
*/
self.count = function (includeAllRecords) {
return methods.count(this, includeAllRecords);
};
/**
* Render data in the grid
*/
self.render = function (response) {
return methods.render($grid, response);
};
/**
* Destroy the grid. This method remove all data from the grid and all events attached to the grid.
*/
self.destroy = function (keepTableTag, keepWrapperTag) {
return methods.destroy(this, keepTableTag, keepWrapperTag);
};
/**
* Select a row from the grid based on id parameter.
*/
self.setSelected = function (id) {
return methods.setSelected(this, id);
};
/**
* Return the id of the selected record.
* If the multiple selection method is one this method is going to return only the id of the first selected record.
*/
self.getSelected = function () {
return methods.getSelected(this);
};
/**
* Return an array with the ids of the selected record.
*/
self.getSelections = function () {
return methods.getSelections(this);
};
/**
* Select all records from the grid.
*/
self.selectAll = function () {
return methods.selectAll(this);
};
/**
* Unselect all records from the grid.
*/
self.unSelectAll = function () {
return methods.unSelectAll(this);
};
/**
* Return record by id of the record.
*/
self.getById = function (id) {
return methods.getById(this, id);
};
/**
* Return record from the grid based on position.
*/
self.get = function (position) {
return methods.getByPosition(this, position);
};
/**
* Return an array with all records presented in the grid.
*/
self.getAll = function (includeAllRecords) {
return methods.getAll(this, includeAllRecords);
};
/**
* Show hidden column.
*/
self.showColumn = function (field) {
return methods.showColumn(this, field);
};
/**
* Hide column from the grid.
*/
self.hideColumn = function (field) {
return methods.hideColumn(this, field);
};
/**
* Add new row to the grid.
*/
self.addRow = function (record) {
return methods.addRow(this, record);
};
/**
* Update row data.
*/
self.updateRow = function (id, record) {
return methods.updateRow(this, id, record);
};
//TODO: needs to be removed
self.setCellContent = function (id, index, value) {
methods.setCellContent(this, id, index, value);
};
/**
* Remove row from the grid
*/
self.removeRow = function (id) {
return methods.removeRow(this, id);
};
$.extend($grid, self);
if ('grid' !== $grid.attr('data-type')) {
methods.init.call($grid, jsConfig);
}
return $grid;
}
gj.grid.widget.prototype = new gj.widget();
gj.grid.widget.constructor = gj.grid.widget;
gj.grid.widget.prototype.getConfig = gj.grid.methods.getConfig;
gj.grid.widget.prototype.getHTMLConfig = gj.grid.methods.getHTMLConfig;
(function ($) {
$.fn.grid = function (method) {
var $widget;
if (this && this.length) {
if (typeof method === 'object' || !method) {
return new gj.grid.widget(this, method);
} else {
$widget = new gj.grid.widget(this, null);
if ($widget[method]) {
return $widget[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else {
throw 'Method ' + method + ' does not exist.';
}
}
}
};
})(jQuery);
/**
*/
gj.grid.plugins.fixedHeader = {
config: {
base: {
/** If set to true, add scroll to the table body
*/
fixedHeader: false,
height: 300
}
},
private: {
init: function ($grid) {
var data = $grid.data(),
$tbody = $grid.children('tbody'),
$thead = $grid.children('thead'),
bodyHeight = data.height - $thead.outerHeight() - ($grid.children('tfoot').outerHeight() || 0);
$grid.addClass('gj-grid-scrollable');
$tbody.css('width', $thead.outerWidth());
$tbody.height(bodyHeight);
},
refresh: function ($grid) {
var i, width,
data = $grid.data(),
$tbody = $grid.children('tbody'),
$thead = $grid.children('thead'),
$tbodyCells = $grid.find('tbody tr[data-role="row"] td'),
$theadCells = $grid.find('thead tr[data-role="caption"] th');
if ($grid.children('tbody').height() < gj.grid.plugins.fixedHeader.private.getRowsHeight($grid)) {
$tbody.css('width', $thead.outerWidth() + gj.grid.plugins.fixedHeader.private.getScrollBarWidth() + (navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ? 1 : 0));
} else {
$tbody.css('width', $thead.outerWidth());
}
for (i = 0; i < $theadCells.length; i++) {
width = $($theadCells[i]).outerWidth();
if (i === 0 && gj.core.isIE()) {
width = width - 1;
}
$($tbodyCells[i]).attr('width', width);
}
},
getRowsHeight: function ($grid) {
var total = 0;
$grid.find('tbody tr').each(function () {
total += $(this).height();
});
return total;
},
getScrollBarWidth: function () {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild(outer);
return (w1 - w2);
}
},
public: {
},
events: {
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.fixedHeader.public);
var data = $grid.data();
if (clientConfig.fixedHeader) {
$grid.on('initialized', function () {
gj.grid.plugins.fixedHeader.private.init($grid);
});
$grid.on('dataBound', function () {
gj.grid.plugins.fixedHeader.private.refresh($grid);
});
$grid.on('resize', function () {
gj.grid.plugins.fixedHeader.private.refresh($grid);
});
}
}
};
/**
*/
gj.grid.plugins.expandCollapseRows = {
config: {
base: {
/** Template for the content in the detail section of the row.
* Automatically add expand collapse column as a first column in the grid during initialization.
*/
detailTemplate: undefined,
/** If set try to persist the state of expanded rows.
* You need to specify primaryKey on the initialization of the grid in order to enable this feature.
*/
keepExpandedRows: true,
expandedRows: [],
icons: {
/** Expand row icon definition.
*/
expandRow: '',
/** Collapse row icon definition.
*/
collapseRow: ''
}
},
fontawesome: {
icons: {
expandRow: '',
collapseRow: ''
}
},
glyphicons: {
icons: {
expandRow: '',
collapseRow: ''
}
}
},
'private': {
expandDetail: function ($grid, $cell, id) {
var $contentRow = $cell.closest('tr'),
$detailsRow = $('
'),
$detailsCell = $('
'),
$detailsWrapper = $(''),
data = $grid.data(),
position = $contentRow.data('position'),
record = $grid.get(position),
plugin = gj.grid.plugins.expandCollapseRows;
if (typeof (id) === undefined) {
id = gj.grid.methods.getId(record, data.primaryKey, record);
}
$detailsRow.append($detailsCell.append($detailsWrapper.append($contentRow.data('details'))));
$detailsRow.insertAfter($contentRow);
$cell.children('div[data-role="display"]').empty().append(data.icons.collapseRow);
$grid.updateDetails($contentRow);
plugin.private.keepSelection($grid, id);
plugin.events.detailExpand($grid, $detailsRow.find('td>div'), id);
},
collapseDetail: function ($grid, $cell, id) {
var $contentRow = $cell.closest('tr'),
$detailsRow = $contentRow.next('tr[data-role="details"]'),
data = $grid.data(),
plugin = gj.grid.plugins.expandCollapseRows;
if (typeof (id) === undefined) {
id = gj.grid.methods.getId(record, data.primaryKey, record);
}
$detailsRow.remove();
$cell.children('div[data-role="display"]').empty().append(data.icons.expandRow);
plugin.private.removeSelection($grid, id);
plugin.events.detailCollapse($grid, $detailsRow.find('td>div'), id);
},
keepSelection: function($grid, id) {
var data = $grid.data();
if (data.keepExpandedRows) {
if ($.isArray(data.expandedRows)) {
if (data.expandedRows.indexOf(id) == -1) {
data.expandedRows.push(id);
}
} else {
data.expandedRows = [id];
}
}
},
removeSelection: function ($grid, id) {
var data = $grid.data();
if (data.keepExpandedRows && $.isArray(data.expandedRows) && data.expandedRows.indexOf(id) > -1) {
data.expandedRows.splice(data.expandedRows.indexOf(id), 1);
}
},
updateDetailsColSpan: function ($grid) {
var $cells = $grid.find('tbody > tr[data-role="details"] > td');
if ($cells && $cells.length) {
$cells.attr('colspan', gj.grid.methods.countVisibleColumns($grid));
}
}
},
'public': {
/**
* Collapse all grid rows.
*/
collapseAll: function () {
var $grid = this, data = $grid.data(), position;
if (typeof (data.detailTemplate) !== 'undefined') {
position = gj.grid.methods.getColumnPositionByRole($grid, 'expander');
$grid.find('tbody tr[data-role="row"]').each(function () {
gj.grid.plugins.expandCollapseRows.private.collapseDetail($grid, $(this).find('td:eq(' + position + ')'));
});
}
if (typeof (data.grouping) !== 'undefined') {
$grid.find('tbody tr[role="group"]').each(function () {
gj.grid.plugins.grouping.private.collapseGroup(data, $(this).find('td:eq(0)'));
});
}
return $grid;
},
/**
* Expand all grid rows.
*/
expandAll: function () {
var $grid = this, data = $grid.data(), position;
if (typeof (data.detailTemplate) !== 'undefined') {
position = gj.grid.methods.getColumnPositionByRole($grid, 'expander');
$grid.find('tbody tr[data-role="row"]').each(function () {
gj.grid.plugins.expandCollapseRows.private.expandDetail($grid, $(this).find('td:eq(' + position + ')'));
});
}
if (typeof (data.grouping) !== 'undefined') {
$grid.find('tbody tr[role="group"]').each(function () {
gj.grid.plugins.grouping.private.expandGroup(data, $(this).find('td:eq(0)'));
});
}
return $grid;
},
//TODO: add documentation
updateDetails: function ($contentRow) {
var $grid = this,
$detailWrapper = $contentRow.data('details'),
content = $detailWrapper.html(),
record = $grid.get($contentRow.data('position'));
if (record && content) {
$detailWrapper.html().replace(/\{(.+?)\}/g, function ($0, $1) {
var column = gj.grid.methods.getColumnInfo($grid, $1);
content = content.replace($0, gj.grid.methods.formatText(record[$1], column));
});
$detailWrapper.html(content);
}
return $grid;
}
},
'events': {
/**
* Event fires when detail row is showing
*
*/
detailExpand: function ($grid, $detailWrapper, id) {
$grid.triggerHandler('detailExpand', [$detailWrapper, id]);
},
/**
* Event fires when detail row is hiding
*
*/
detailCollapse: function ($grid, $detailWrapper, id) {
$grid.triggerHandler('detailCollapse', [$detailWrapper, id]);
}
},
'configure': function ($grid) {
var column, data = $grid.data();
$.extend(true, $grid, gj.grid.plugins.expandCollapseRows.public);
if (typeof (data.detailTemplate) !== 'undefined') {
column = {
title: '',
width: data.defaultIconColumnWidth,
align: 'center',
stopPropagation: true,
cssClass: 'gj-cursor-pointer gj-unselectable',
tmpl: data.icons.expandRow,
role: 'expander',
events: {
'click': function (e) {
var $cell = $(this), methods = gj.grid.plugins.expandCollapseRows.private;
if ($cell.closest('tr').next().attr('data-role') === 'details') {
methods.collapseDetail($grid, $cell, e.data.id);
} else {
methods.expandDetail($grid, $(this), e.data.id);
}
}
}
};
data.columns = [column].concat(data.columns);
$grid.on('rowDataBound', function (e, $row, id, record) {
$row.data('details', $(data.detailTemplate));
});
$grid.on('columnShow', function (e, column) {
gj.grid.plugins.expandCollapseRows.private.updateDetailsColSpan($grid);
});
$grid.on('columnHide', function (e, column) {
gj.grid.plugins.expandCollapseRows.private.updateDetailsColSpan($grid);
});
$grid.on('rowRemoving', function (e, $row, id, record) {
gj.grid.plugins.expandCollapseRows.private.collapseDetail($grid, $row.children('td').first(), id);
});
$grid.on('dataBinding', function () {
$grid.collapseAll();
});
$grid.on('pageChanging', function () {
$grid.collapseAll();
});
$grid.on('dataBound', function () {
var i, $cell, $row, position, data = $grid.data();
if (data.keepExpandedRows && $.isArray(data.expandedRows)) {
for (i = 0; i < data.expandedRows.length; i++) {
$row = gj.grid.methods.getRowById($grid, data.expandedRows[i]);
if ($row && $row.length) {
position = gj.grid.methods.getColumnPositionByRole($grid, 'expander');
$cell = $row.children('td:eq(' + position + ')');
if ($cell && $cell.length) {
gj.grid.plugins.expandCollapseRows.private.expandDetail($grid, $cell);
}
}
}
}
});
}
}
};
/**
*/
gj.grid.plugins.inlineEditing = {
renderers: {
editManager: function (value, record, $cell, $displayEl, id, $grid) {
var data = $grid.data(),
$edit = $(data.inlineEditing.editButton).attr('key', id),
$delete = $(data.inlineEditing.deleteButton).attr('key', id),
$update = $(data.inlineEditing.updateButton).attr('key', id).hide(),
$cancel = $(data.inlineEditing.cancelButton).attr('key', id).hide();
$edit.on('click', function (e) {
$grid.edit($(this).attr('key'));
});
$delete.on('click', function (e) {
$grid.removeRow($(this).attr('key'));
});
$update.on('click', function (e) {
$grid.update($(this).attr('key'));
});
$cancel.on('click', function (e) {
$grid.cancel($(this).attr('key'));
});
$displayEl.empty().append($edit).append($delete).append($update).append($cancel);
}
}
};
gj.grid.plugins.inlineEditing.config = {
base: {
defaultColumnSettings: {
/** Provides a way to set an editing UI for the column.
*/
editor: undefined,
/** The name of the field in the grid data where the grid is going to set the new value.
*/
editField: undefined,
/** Provides a way to specify a display mode for the column.
*/
mode: 'readEdit'
},
inlineEditing: {
/** Inline editing mode.
*/
mode: 'click',
/** If set to true, add column with buttons for edit, delete, update and cancel at the end of the grid.
*/
managementColumn: true,
managementColumnConfig: { width: 300, role: 'managementColumn', align: 'center', renderer: gj.grid.plugins.inlineEditing.renderers.editManager, cssClass: 'gj-grid-management-column' }
}
},
bootstrap: {
inlineEditing: {
managementColumnConfig: { width: 200, role: 'managementColumn', align: 'center', renderer: gj.grid.plugins.inlineEditing.renderers.editManager, cssClass: 'gj-grid-management-column' }
}
},
bootstrap4: {
inlineEditing: {
managementColumnConfig: { width: 280, role: 'managementColumn', align: 'center', renderer: gj.grid.plugins.inlineEditing.renderers.editManager, cssClass: 'gj-grid-management-column' }
}
}
};
gj.grid.plugins.inlineEditing.private = {
localization: function (data) {
if (data.uiLibrary === 'bootstrap') {
data.inlineEditing.editButton = '';
data.inlineEditing.deleteButton = '';
data.inlineEditing.updateButton = '';
data.inlineEditing.cancelButton = '';
} else {
data.inlineEditing.editButton = '';
data.inlineEditing.deleteButton = '';
data.inlineEditing.updateButton = '';
data.inlineEditing.cancelButton = '';
}
},
editMode: function ($grid, $cell, column, record) {
var $displayContainer, $editorContainer, $editorField, value, config, data = $grid.data();
if ($cell.attr('data-mode') !== 'edit') {
if (column.editor) {
gj.grid.plugins.inlineEditing.private.updateOtherCells($grid, column.mode);
$displayContainer = $cell.find('div[data-role="display"]').hide();
$editorContainer = $cell.find('div[data-role="edit"]').show();
if ($editorContainer.length === 0) {
$editorContainer = $('');
$cell.append($editorContainer);
}
value = record[column.editField || column.field];
$editorField = $editorContainer.find('input, select, textarea').first();
if ($editorField.length) {
switch (column.type) {
case 'checkbox':
$editorField.prop('checked', value);
break;
case 'dropdown':
$editorField = $editorField.dropdown('value', value);
break;
default:
$editorField.val(value);
}
} else {
if (typeof (column.editor) === 'function') {
column.editor($editorContainer, value, record);
$editorField = $editorContainer.find('input, select, textarea').first();
} else {
config = typeof column.editor === "object" ? column.editor : {};
config.uiLibrary = data.uiLibrary;
config.iconsLibrary = data.iconsLibrary;
config.fontSize = $grid.css('font-size');
config.showOnFocus = false;
if ('checkbox' === column.type && gj.checkbox) {
$editorField = $('').prop('checked', value);
$editorContainer.append($editorField);
$editorField.checkbox(config);
} else if (('date' === column.type && gj.datepicker) || ('time' === column.type && gj.timepicker) || ('datetime' === column.type && gj.datetimepicker)) {
$editorField = $('');
$editorContainer.append($editorField);
if (column.format) {
config.format = column.format;
}
switch (column.type) {
case 'date':
$editorField = $editorField.datepicker(config);
break;
case 'time':
$editorField = $editorField.timepicker(config);
break;
case 'datetime':
$editorField = $editorField.datetimepicker(config);
break;
}
if ($editorField.value) {
$editorField.value($displayContainer.html());
}
} else if ('dropdown' === column.type && gj.dropdown) {
$editorField = $('');
$editorContainer.append($editorField);
config.dataBound = function (e) {
var $dropdown = $(this).dropdown();
if (column.editField) {
$dropdown.value(record[column.editField]);
} else {
$dropdown.value(record[column.field]);
}
};
$editorField = $editorField.dropdown(config);
} else {
$editorField = $('');
if (data.uiLibrary === 'materialdesign') {
$editorField.addClass('gj-textbox-md').css('font-size', $grid.css('font-size'));
}
$editorContainer.append($editorField);
}
}
if (data.inlineEditing.mode !== 'command' && column.mode !== 'editOnly') {
$editorField = $editorContainer.find('input, select, textarea').first();
$editorField.on('keyup', function (e) {
if (e.keyCode === 13 || e.keyCode === 27) {
gj.grid.plugins.inlineEditing.private.displayMode($grid, $cell, column);
}
});
}
}
if ($editorField.prop('tagName').toUpperCase() === "INPUT" && $editorField.prop('type').toUpperCase() === 'TEXT') {
gj.core.setCaretAtEnd($editorField[0]);
} else {
$editorField.focus();
}
$cell.attr('data-mode', 'edit');
} else if (column.role === 'managementColumn') {
$cell.find('[role="edit"]').hide();
$cell.find('[role="delete"]').hide();
$cell.find('[role="update"]').show();
$cell.find('[role="cancel"]').show();
}
}
},
displayMode: function ($grid, $cell, column, cancel) {
var $editorContainer, $displayContainer, $ele, newValue, newEditFieldValue, record, position, style = '';
if (column.mode !== 'editOnly') {
if ($cell.attr('data-mode') === 'edit') {
$editorContainer = $cell.find('div[data-role="edit"]');
$displayContainer = $cell.find('div[data-role="display"]');
$ele = $editorContainer.find('input, select, textarea').first();
if ($ele[0].tagName.toUpperCase() === "SELECT" && $ele[0].selectedIndex > -1) {
newValue = $ele[0].options[$ele[0].selectedIndex].innerHTML;
newEditFieldValue = $ele[0].value;
} else if ($ele[0].tagName.toUpperCase() === "INPUT" && $ele[0].type.toUpperCase() === "CHECKBOX") {
newValue = $ele[0].checked;
} else {
newValue = $ele.val();
}
position = $cell.parent().data('position');
record = $grid.get(position);
if (cancel !== true && newValue !== record[column.field]) {
record[column.field] = column.type === 'date' ? gj.core.parseDate(newValue, column.format) : newValue;
if (column.editField) {
record[column.editField] = newEditFieldValue || newValue;
}
if (column.mode !== 'editOnly') {
gj.grid.methods.renderDisplayElement($grid, $displayContainer, column, record, gj.grid.methods.getId(record, $grid.data('primaryKey'), position), 'update');
if ($cell.find('span.gj-dirty').length === 0) {
$cell.prepend($(''));
}
}
gj.grid.plugins.inlineEditing.events.cellDataChanged($grid, $cell, column, record, newValue);
gj.grid.plugins.inlineEditing.private.updateChanges($grid, column, record, newValue);
}
$editorContainer.hide();
$displayContainer.show();
$cell.attr('data-mode', 'display');
}
if (column.role === 'managementColumn') {
$cell.find('[role="update"]').hide();
$cell.find('[role="cancel"]').hide();
$cell.find('[role="edit"]').show();
$cell.find('[role="delete"]').show();
}
}
},
updateOtherCells: function($grid, mode) {
var data = $grid.data();
if (data.inlineEditing.mode !== 'command' && mode !== 'editOnly') {
$grid.find('div[data-role="edit"]:visible').parent('td').each(function () {
var $cell = $(this),
column = data.columns[$cell.index()];
gj.grid.plugins.inlineEditing.private.displayMode($grid, $cell, column);
});
}
},
updateChanges: function ($grid, column, sourceRecord, newValue) {
var targetRecords, filterResult, newRecord, data = $grid.data();
if (!data.guid) {
data.guid = gj.grid.plugins.inlineEditing.private.generateGUID();
}
if (data.primaryKey) {
targetRecords = JSON.parse(sessionStorage.getItem('gj.grid.' + data.guid));
if (targetRecords) {
filterResult = targetRecords.filter(function (record) {
return record[data.primaryKey] === sourceRecord[data.primaryKey];
});
} else {
targetRecords = [];
}
if (filterResult && filterResult.length === 1) {
filterResult[0][column.field] = newValue;
} else {
newRecord = {};
newRecord[data.primaryKey] = sourceRecord[data.primaryKey];
if (data.primaryKey !== column.field) {
newRecord[column.field] = newValue;
}
targetRecords.push(newRecord);
}
sessionStorage.setItem('gj.grid.' + data.guid, JSON.stringify(targetRecords));
}
},
generateGUID: function () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
};
gj.grid.plugins.inlineEditing.public = {
/**
* Return array with all changes
*/
getChanges: function () {
return JSON.parse(sessionStorage.getItem('gj.grid.' + this.data().guid));
},
/**
* Enable edit mode for all editable cells within a row.
*/
edit: function (id) {
var i, record = this.getById(id),
$cells = gj.grid.methods.getRowById(this, id).children('td'),
columns = this.data('columns');
for (i = 0; i < $cells.length; i++) {
gj.grid.plugins.inlineEditing.private.editMode(this, $($cells[i]), columns[i], record);
}
return this;
},
/**
* Update all editable cells within a row, when the row is in edit mode.
*/
update: function (id) {
var i, record = this.getById(id),
$cells = gj.grid.methods.getRowById(this, id).children('td'),
columns = this.data('columns');
for (i = 0; i < $cells.length; i++) {
gj.grid.plugins.inlineEditing.private.displayMode(this, $($cells[i]), columns[i], false);
}
gj.grid.plugins.inlineEditing.events.rowDataChanged(this, id, record);
return this;
},
/**
* Cancel the edition of all editable cells, when the row is in edit mode.
*/
cancel: function (id) {
var i, record = this.getById(id),
$cells = gj.grid.methods.getRowById(this, id).children('td'),
columns = this.data('columns');
for (i = 0; i < $cells.length; i++) {
gj.grid.plugins.inlineEditing.private.displayMode(this, $($cells[i]), columns[i], true);
}
return this;
}
};
gj.grid.plugins.inlineEditing.events = {
/**
* Event fires after inline edit of a cell in the grid.
*
*/
cellDataChanged: function ($grid, $cell, column, record, oldValue, newValue) {
$grid.triggerHandler('cellDataChanged', [$cell, column, record, oldValue, newValue]);
},
/**
* Event fires after inline edit of a row in the grid.
*
*/
rowDataChanged: function ($grid, id, record) {
$grid.triggerHandler('rowDataChanged', [id, record]);
}
};
gj.grid.plugins.inlineEditing.configure = function ($grid, fullConfig, clientConfig) {
var data = $grid.data();
$.extend(true, $grid, gj.grid.plugins.inlineEditing.public);
if (clientConfig.inlineEditing) {
$grid.on('dataBound', function () {
$grid.find('span.gj-dirty').remove();
});
$grid.on('rowDataBound', function (e, $row, id, record) {
$grid.cancel(id);
});
}
if (data.inlineEditing.mode === 'command') {
gj.grid.plugins.inlineEditing.private.localization(data);
if (fullConfig.inlineEditing.managementColumn) {
data.columns.push(fullConfig.inlineEditing.managementColumnConfig);
}
} else {
$grid.on('cellDataBound', function (e, $displayEl, id, column, record) {
if (column.editor) {
if (column.mode === 'editOnly') {
gj.grid.plugins.inlineEditing.private.editMode($grid, $displayEl.parent(), column, record);
} else {
$displayEl.parent('td').on(data.inlineEditing.mode === 'dblclick' ? 'dblclick' : 'click', function () {
gj.grid.plugins.inlineEditing.private.editMode($grid, $displayEl.parent(), column, record);
});
}
}
});
}
};
/**
*/
gj.grid.plugins.optimisticPersistence = {
config: {
base: {
optimisticPersistence: {
/** Array that contains a list with param names that needs to be saved in the localStorage. You need to specify guid on the initialization of the grid in order to enable this feature.
*/
localStorage: undefined,
/** Array that contains a list with param names that needs to be saved in the sessionStorage. You need to specify guid on the initialization of the grid in order to enable this feature.
*/
sessionStorage: undefined
}
}
},
private: {
applyParams: function ($grid) {
var data = $grid.data(),
params = {}, storage;
storage = JSON.parse(sessionStorage.getItem('gj.grid.' + data.guid));
if (storage && storage.optimisticPersistence) {
$.extend(params, storage.optimisticPersistence);
}
storage = JSON.parse(localStorage.getItem('gj.grid.' + data.guid));
if (storage && storage.optimisticPersistence) {
$.extend(params, storage.optimisticPersistence);
}
$.extend(data.params, params);
},
saveParams: function ($grid) {
var i, param,
data = $grid.data(),
storage = { optimisticPersistence: {} };
if (data.optimisticPersistence.sessionStorage) {
for (i = 0; i < data.optimisticPersistence.sessionStorage.length; i++) {
param = data.optimisticPersistence.sessionStorage[i];
storage.optimisticPersistence[param] = data.params[param];
}
storage = $.extend(true, JSON.parse(sessionStorage.getItem('gj.grid.' + data.guid)), storage);
sessionStorage.setItem('gj.grid.' + data.guid, JSON.stringify(storage));
}
if (data.optimisticPersistence.localStorage) {
storage = { optimisticPersistence: {} };
for (i = 0; i < data.optimisticPersistence.localStorage.length; i++) {
param = data.optimisticPersistence.localStorage[i];
storage.optimisticPersistence[param] = data.params[param];
}
storage = $.extend(true, JSON.parse(localStorage.getItem('gj.grid.' + data.guid)), storage);
localStorage.setItem('gj.grid.' + data.guid, JSON.stringify(storage));
}
}
},
configure: function ($grid, fullConfig, clientConfig) {
if (fullConfig.guid) {
if (fullConfig.optimisticPersistence.localStorage || fullConfig.optimisticPersistence.sessionStorage) {
gj.grid.plugins.optimisticPersistence.private.applyParams($grid);
$grid.on('dataBound', function (e) {
gj.grid.plugins.optimisticPersistence.private.saveParams($grid);
});
}
}
}
};
/**
*/
gj.grid.plugins.pagination = {
config: {
base: {
style: {
pager: {
panel: '',
stateDisabled: '',
activeButton: ''
}
},
paramNames: {
/** The name of the parameter that is going to send the number of the page.
* The pager should be enabled in order this parameter to be in use.
*/
page: 'page',
/** The name of the parameter that is going to send the maximum number of records per page.
* The pager should be enabled in order this parameter to be in use.
*/
limit: 'limit'
},
pager: {
/** The maximum number of records that can be show by page.
*/
limit: 10,
/** Array that contains the possible page sizes of the grid.
* When this setting is set, then a drop down with the options for each page size is visualized in the pager.
*/
sizes: [5, 10, 20, 100],
/** Array that contains a list with jquery objects that are going to be used on the left side of the pager.
*/
leftControls: undefined,
/** Array that contains a list with jquery objects that are going to be used on the right side of the pager.
*/
rightControls: undefined
}
},
bootstrap: {
style: {
pager: {
panel: '',
stateDisabled: ''
}
}
},
bootstrap4: {
style: {
pager: {
panel: 'btn-toolbar',
stateDisabled: ''
}
}
},
glyphicons: {
icons: {
first: '',
previous: '',
next: '',
last: '',
refresh: ''
}
},
materialicons: {
icons: {
first: '',
previous: '',
next: '',
last: '',
refresh: ''
}
},
fontawesome: {
icons: {
first: '',
previous: '',
next: '',
last: '',
refresh: ''
}
}
},
private: {
init: function ($grid) {
var $row, $cell, data, controls, $leftPanel, $rightPanel, $tfoot, leftControls, rightControls, i;
data = $grid.data();
if (data.pager) {
if (!data.params[data.paramNames.page]) {
data.params[data.paramNames.page] = 1;
}
if (!data.params[data.paramNames.limit]) {
data.params[data.paramNames.limit] = data.pager.limit;
}
gj.grid.plugins.pagination.private.localization(data);
$row = $('
');
$cell = $('
');
$row.append($cell);
$leftPanel = $('').addClass(data.style.pager.panel).css({ 'float': 'left' });
$rightPanel = $('').addClass(data.style.pager.panel).css({ 'float': 'right' });
$cell.append($leftPanel).append($rightPanel);
$tfoot = $('').append($row);
$grid.append($tfoot);
gj.grid.plugins.pagination.private.updatePagerColSpan($grid);
leftControls = gj.grid.methods.clone(data.pager.leftControls); //clone array
$.each(leftControls, function () {
$leftPanel.append(this);
});
rightControls = gj.grid.methods.clone(data.pager.rightControls); //clone array
$.each(rightControls, function () {
$rightPanel.append(this);
});
controls = $grid.find('tfoot [data-role]');
for (i = 0; i < controls.length; i++) {
gj.grid.plugins.pagination.private.initPagerControl($(controls[i]), $grid);
}
}
},
localization: function (data) {
if (data.uiLibrary === 'bootstrap') {
gj.grid.plugins.pagination.private.localizationBootstrap(data);
} else if (data.uiLibrary === 'bootstrap4') {
gj.grid.plugins.pagination.private.localizationBootstrap4(data);
} else {
gj.grid.plugins.pagination.private.localizationMaterialDesign(data);
}
},
localizationBootstrap: function (data) {
var msg = gj.grid.messages[data.locale];
if (typeof (data.pager.leftControls) === 'undefined') {
data.pager.leftControls = [
$('').attr('title', msg.FirstPageTooltip).attr('data-role', 'page-first'),
$('').attr('title', msg.PreviousPageTooltip).attr('data-role', 'page-previous'),
$('
')
];
}
},
localizationMaterialDesign: function (data) {
var msg = gj.grid.messages[data.locale];
if (typeof (data.pager.leftControls) === 'undefined') {
data.pager.leftControls = [];
}
if (typeof (data.pager.rightControls) === 'undefined') {
data.pager.rightControls = [
$('' + msg.RowsPerPage + ''),
$(''),
$(''),
$('0'),
$('-'),
$('0'),
$('' + msg.Of + ''),
$('0'),
$(''),
$('').attr('title', msg.PreviousPageTooltip).attr('data-role', 'page-previous').addClass(data.icons.first ? 'gj-button-md-icon' : ''),
$(''),
$('').attr('title', msg.NextPageTooltip).attr('data-role', 'page-next').addClass(data.icons.first ? 'gj-button-md-icon' : '')
];
}
},
initPagerControl: function ($control, $grid) {
var data = $grid.data();
switch ($control.data('role')) {
case 'page-size':
if (data.pager.sizes && 0 < data.pager.sizes.length) {
$control.show();
$.each(data.pager.sizes, function () {
$control.append($('').attr('value', this.toString()).text(this.toString()));
});
$control.change(function () {
var newSize = parseInt(this.value, 10);
data.params[data.paramNames.limit] = newSize;
gj.grid.plugins.pagination.private.changePage($grid, 1);
gj.grid.plugins.pagination.events.pageSizeChange($grid, newSize);
});
$control.val(data.params[data.paramNames.limit]);
if (gj.dropdown) {
$control.dropdown({
uiLibrary: data.uiLibrary,
iconsLibrary: data.iconsLibrary,
fontSize: $control.css('font-size'),
style: {
presenter: 'btn btn-default btn-sm'
}
});
}
} else {
$control.hide();
}
break;
case 'page-refresh':
$control.on('click', function () { $grid.reload(); });
break;
}
},
reloadPager: function ($grid, totalRecords) {
var page, limit, lastPage, firstRecord, lastRecord, data, controls, i;
data = $grid.data();
if (data.pager) {
page = (0 === totalRecords) ? 0 : parseInt(data.params[data.paramNames.page], 10);
limit = parseInt(data.params[data.paramNames.limit], 10);
lastPage = Math.ceil(totalRecords / limit);
firstRecord = (0 === page) ? 0 : (limit * (page - 1)) + 1;
lastRecord = (firstRecord + limit) > totalRecords ? totalRecords : (firstRecord + limit) - 1;
controls = $grid.find('TFOOT [data-role]');
for (i = 0; i < controls.length; i++) {
gj.grid.plugins.pagination.private.reloadPagerControl($(controls[i]), $grid, page, lastPage, firstRecord, lastRecord, totalRecords);
}
gj.grid.plugins.pagination.private.updatePagerColSpan($grid);
}
},
reloadPagerControl: function ($control, $grid, page, lastPage, firstRecord, lastRecord, totalRecords) {
var newPage;
switch ($control.data('role')) {
case 'page-first':
gj.grid.plugins.pagination.private.assignPageHandler($grid, $control, 1, page < 2);
break;
case 'page-previous':
gj.grid.plugins.pagination.private.assignPageHandler($grid, $control, page - 1, page < 2);
break;
case 'page-number':
$control.val(page).off('change').on('change', gj.grid.plugins.pagination.private.createChangePageHandler($grid, page));
break;
case 'page-label-last':
$control.text(lastPage);
break;
case 'page-next':
gj.grid.plugins.pagination.private.assignPageHandler($grid, $control, page + 1, lastPage === page);
break;
case 'page-last':
gj.grid.plugins.pagination.private.assignPageHandler($grid, $control, lastPage, lastPage === page);
break;
case 'page-button-one':
newPage = (page === 1) ? 1 : ((page == lastPage) ? (page - 2) : (page - 1));
gj.grid.plugins.pagination.private.assignButtonHandler($grid, $control, page, newPage, lastPage);
break;
case 'page-button-two':
newPage = (page === 1) ? 2 : ((page == lastPage) ? lastPage - 1 : page);
gj.grid.plugins.pagination.private.assignButtonHandler($grid, $control, page, newPage, lastPage);
break;
case 'page-button-three':
newPage = (page === 1) ? page + 2 : ((page == lastPage) ? page : (page + 1));
gj.grid.plugins.pagination.private.assignButtonHandler($grid, $control, page, newPage, lastPage);
break;
case 'record-first':
$control.text(firstRecord);
break;
case 'record-last':
$control.text(lastRecord);
break;
case 'record-total':
$control.text(totalRecords);
break;
}
},
assignPageHandler: function ($grid, $control, newPage, disabled) {
var style = $grid.data().style.pager;
if (disabled) {
$control.addClass(style.stateDisabled).prop('disabled', true).off('click');
} else {
$control.removeClass(style.stateDisabled).prop('disabled', false).off('click').on('click', function () {
gj.grid.plugins.pagination.private.changePage($grid, newPage);
});
}
},
assignButtonHandler: function ($grid, $control, page, newPage, lastPage) {
var style = $grid.data().style.pager;
if (newPage < 1 || newPage > lastPage) {
$control.hide();
} else {
$control.show().off('click').text(newPage);
if (newPage === page) {
$control.addClass(style.activeButton);
} else {
$control.removeClass(style.activeButton).on('click', function () {
gj.grid.plugins.pagination.private.changePage($grid, newPage);
});
}
}
},
createChangePageHandler: function ($grid, currentPage) {
return function () {
var data = $grid.data(),
newPage = parseInt(this.value, 10);
gj.grid.plugins.pagination.private.changePage($grid, newPage);
};
},
changePage: function ($grid, newPage) {
var data = $grid.data();
if (gj.grid.plugins.pagination.events.pageChanging($grid, newPage) !== false && !isNaN(newPage)) {
$grid.find('TFOOT [data-role="page-number"]').val(newPage);
data.params[data.paramNames.page] = newPage;
}
$grid.reload();
},
updatePagerColSpan: function ($grid) {
var $cell = $grid.find('tfoot > tr[data-role="pager"] > th');
if ($cell && $cell.length) {
$cell.attr('colspan', gj.grid.methods.countVisibleColumns($grid));
}
},
isLastRecordVisible: function ($grid) {
var result = true,
data = $grid.data(),
limit = parseInt(data.params[data.paramNames.limit], 10),
page = parseInt(data.params[data.paramNames.page], 10),
count = $grid.count();
if (limit && page) {
result = ((page - 1) * limit) + count === data.totalRecords;
}
return result;
}
},
public: {
getAll: function (includeAllRecords) {
var limit, page, start, data = this.data();
if ($.isArray(data.dataSource)) {
if (includeAllRecords) {
return data.dataSource;
} else if (data.params[data.paramNames.limit] && data.params[data.paramNames.page]) {
limit = parseInt(data.params[data.paramNames.limit], 10);
page = parseInt(data.params[data.paramNames.page], 10);
start = (page - 1) * limit;
return data.records.slice(start, start + limit);
} else {
return data.records;
}
} else {
return data.records;
}
}
},
events: {
/**
* Triggered when the page size is changed.
*
*/
pageSizeChange: function ($grid, newSize) {
$grid.triggerHandler('pageSizeChange', [newSize]);
},
/**
* Triggered before the change of the page.
*
*/
pageChanging: function ($grid, newSize) {
$grid.triggerHandler('pageChanging', [newSize]);
}
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.pagination.public);
var data = $grid.data();
if (clientConfig.pager) {
gj.grid.methods.isLastRecordVisible = gj.grid.plugins.pagination.private.isLastRecordVisible;
$grid.on('initialized', function () {
gj.grid.plugins.pagination.private.init($grid);
});
$grid.on('dataBound', function (e, records, totalRecords) {
gj.grid.plugins.pagination.private.reloadPager($grid, totalRecords);
});
$grid.on('columnShow', function () {
gj.grid.plugins.pagination.private.updatePagerColSpan($grid);
});
$grid.on('columnHide', function () {
gj.grid.plugins.pagination.private.updatePagerColSpan($grid);
});
}
}
};
/**
*/
gj.grid.plugins.responsiveDesign = {
config: {
base: {
/** The interval in milliseconds for checking if the grid is resizing.
* This setting is in use only if the resizeMonitoring setting is set to true.
*/
resizeCheckInterval: 500,
/** This setting enables responsive behaviour of the grid where some column are invisible when there is not enough space on the screen for them.
* The visibility of the columns in this mode is driven by the column minWidth and priority settings.
* The columns without priority setting are always visible and can't hide in small screen resolutions.
*/
responsive: false,
/** Automatically adds hidden columns to the details section of the row.
* This setting works only if the responsive setting is set to true and the detailTemplate is set.
* You need to set priority and minWidth on the colums, that needs to be hidden in smaller screens.
*/
showHiddenColumnsAsDetails: false,
defaultColumn: {
/** The priority of the column compared to other columns in the grid.
* The columns are hiding based on the priorities.
* This setting is working only when the responsive setting is set to true.
*/
priority: undefined,
/** The minimum width of the column.
* The column is getting invisible when there is not enough space in the grid for this minimum width.
* This setting is working only when the responsive setting is set to true and the column priority setting is set.
*/
minWidth: 250
},
style: {
rowDetailItem: ''
}
},
bootstrap: {
style: {
rowDetailItem: 'col-lg-4'
}
}
},
'private': {
orderColumns: function (config) {
var result = [];
if (config.columns && config.columns.length) {
for (i = 0; i < config.columns.length; i++) {
result.push({
position: i,
field: config.columns[i].field,
minWidth: config.columns[i].width || config.columns[i].minWidth || config.defaultColumn.minWidth,
priority: config.columns[i].priority || 0
});
}
result.sort(function (a, b) {
var result = 0;
if (a.priority < b.priority) {
result = -1;
} else if (a.priority > b.priority) {
result = 1;
}
return result;
});
}
return result;
},
updateDetails: function ($grid) {
var rows, data, i, j, $row, details, $placeholder, column, tmp;
rows = $grid.find('tbody > tr[data-role="row"]');
data = $grid.data();
for (i = 0; i < rows.length; i++) {
$row = $(rows[i]);
details = $row.data('details');
for (j = 0; j < data.columns.length; j++) {
column = data.columns[j];
$placeholder = details && details.find('div[data-id="' + column.field + '"]');
if (data.columns[j].hidden) {
tmp = '' + (column.title || column.field) + ': {' + column.field + '}';
if (!$placeholder || !$placeholder.length) {
$placeholder = $('').html(tmp);
$placeholder.addClass(data.style.rowDetailItem);
if (!details || !details.length) {
details = $('');
}
details.append($placeholder);
} else {
$placeholder.empty().html(tmp);
}
} else if ($placeholder && $placeholder.length) {
$placeholder.remove();
}
}
$grid.updateDetails($row);
}
}
},
'public': {
oldWidth: undefined,
resizeCheckIntervalId: undefined,
/**
* Make the grid responsive based on the available space.
* Show column if the space for the grid is expanding and hide columns when the space for the grid is decreasing.
*/
makeResponsive: function () {
var i, $column,
extraWidth = 0,
config = this.data(),
columns = gj.grid.plugins.responsiveDesign.private.orderColumns(config);
//calculate extra width
for (i = 0; i < columns.length; i++) {
$column = this.find('thead>tr>th:eq(' + columns[i].position + ')');
if ($column.is(':visible') && columns[i].minWidth < $column.width()) {
extraWidth += $column.width() - columns[i].minWidth;
}
}
//show columns
if (extraWidth) {
for (i = 0; i < columns.length; i++) {
$column = this.find('thead>tr>th:eq(' + columns[i].position + ')');
if (!$column.is(':visible') && columns[i].minWidth <= extraWidth) {
this.showColumn(columns[i].field);
extraWidth -= $column.width();
}
}
}
//hide columns
for (i = (columns.length - 1); i >= 0; i--) {
$column = this.find('thead>tr>th:eq(' + columns[i].position + ')');
if ($column.is(':visible') && columns[i].priority && columns[i].minWidth > $column.outerWidth()) {
this.hideColumn(columns[i].field);
}
}
return this;
},
},
'events': {
/**
* Event fires when the grid width is changed. The "responsive" configuration setting should be set to true in order this event to fire.
*
*/
resize: function ($grid, newWidth, oldWidth) {
$grid.triggerHandler('resize', [newWidth, oldWidth]);
}
},
'configure': function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.responsiveDesign.public);
if (fullConfig.responsive) {
$grid.on('initialized', function () {
$grid.makeResponsive();
$grid.oldWidth = $grid.width();
$grid.resizeCheckIntervalId = setInterval(function () {
var newWidth = $grid.width();
if (newWidth !== $grid.oldWidth) {
gj.grid.plugins.responsiveDesign.events.resize($grid, newWidth, $grid.oldWidth);
}
$grid.oldWidth = newWidth;
}, fullConfig.resizeCheckInterval);
});
$grid.on('destroy', function () {
if ($grid.resizeCheckIntervalId) {
clearInterval($grid.resizeCheckIntervalId);
}
});
$grid.on('resize', function () {
$grid.makeResponsive();
});
}
if (fullConfig.showHiddenColumnsAsDetails && gj.grid.plugins.expandCollapseRows) {
$grid.on('dataBound', function () {
gj.grid.plugins.responsiveDesign.private.updateDetails($grid);
});
$grid.on('columnHide', function () {
gj.grid.plugins.responsiveDesign.private.updateDetails($grid);
});
$grid.on('columnShow', function () {
gj.grid.plugins.responsiveDesign.private.updateDetails($grid);
});
$grid.on('rowDataBound', function () {
gj.grid.plugins.responsiveDesign.private.updateDetails($grid);
});
}
}
};
/**
*/
gj.grid.plugins.toolbar = {
config: {
base: {
/** Template for the content in the toolbar. Appears in a separate row on top of the grid.
*/
toolbarTemplate: undefined,
/** The title of the grid. Appears in a separate row on top of the grid.
*/
title: undefined,
style: {
toolbar: 'gj-grid-md-toolbar'
}
},
bootstrap: {
style: {
toolbar: 'gj-grid-bootstrap-toolbar'
}
},
bootstrap4: {
style: {
toolbar: 'gj-grid-bootstrap-4-toolbar'
}
}
},
private: {
init: function ($grid) {
var data, $toolbar, $title;
data = $grid.data();
$toolbar = $grid.prev('div[data-role="toolbar"]');
if (typeof (data.toolbarTemplate) !== 'undefined' || typeof (data.title) !== 'undefined' || $toolbar.length > 0) {
if ($toolbar.length === 0) {
$toolbar = $('');
$grid.before($toolbar);
}
$toolbar.addClass(data.style.toolbar);
if ($toolbar.children().length === 0 && data.toolbarTemplate) {
$toolbar.append(data.toolbarTemplate);
}
$title = $toolbar.find('[data-role="title"]');
if ($title.length === 0) {
$title = $('');
$toolbar.prepend($title);
}
if (data.title) {
$title.text(data.title);
}
if (data.minWidth) {
$toolbar.css('min-width', data.minWidth);
}
}
}
},
public: {
/**
* Get or set grid title.
*/
title: function (text) {
var $titleEl = this.parent().find('div[data-role="toolbar"] [data-role="title"]');
if (typeof (text) !== 'undefined') {
$titleEl.text(text);
return this;
} else {
return $titleEl.text();
}
}
},
configure: function ($grid) {
$.extend(true, $grid, gj.grid.plugins.toolbar.public);
$grid.on('initialized', function () {
gj.grid.plugins.toolbar.private.init($grid);
});
$grid.on('destroying', function () {
$grid.prev('[data-role="toolbar"]').remove();
});
}
};
/**
*/
gj.grid.plugins.resizableColumns = {
config: {
base: {
/** If set to true, users can resize columns by dragging the edges (resize handles) of their header cells.
*/
resizableColumns: false
}
},
private: {
init: function ($grid, config) {
var $columns, $column, i, $wrapper, $resizer, marginRight;
$columns = $grid.find('thead tr[data-role="caption"] th');
if ($columns.length) {
for (i = 0; i < $columns.length - 1; i++) {
$column = $($columns[i]);
$wrapper = $('');
marginRight = parseInt($column.css('padding-right'), 10) + 3;
$resizer = $('').css('margin-right', '-' + marginRight + 'px');
$resizer.draggable({
start: function () {
$grid.addClass('gj-unselectable');
$grid.addClass('gj-grid-resize-cursor');
},
stop: function () {
$grid.removeClass('gj-unselectable');
$grid.removeClass('gj-grid-resize-cursor');
this.style.removeProperty('top');
this.style.removeProperty('left');
this.style.removeProperty('position');
},
drag: gj.grid.plugins.resizableColumns.private.createResizeHandle($grid, $column, config.columns[i])
});
$column.append($wrapper.append($resizer));
}
for (i = 0; i < $columns.length; i++) {
$column = $($columns[i]);
if (!$column.attr('width')) {
$column.attr('width', $column.outerWidth());
}
}
}
},
createResizeHandle: function ($grid, $column, column) {
var data = $grid.data();
return function (e, newPosition) {
var i, index, rows, cell, newWidth, nextWidth,
currentWidth = parseInt($column.attr('width'), 10),
position = gj.core.position(this),
offset = { top: newPosition.top - position.top, left: newPosition.left - position.left };
if (!currentWidth) {
currentWidth = $column.outerWidth();
}
if (offset.left) {
newWidth = currentWidth + offset.left;
column.width = newWidth;
$column.attr('width', newWidth);
index = $column[0].cellIndex;
cell = $column[0].parentElement.children[index + 1];
nextWidth = parseInt($(cell).attr('width'), 10) - offset.left;
cell.setAttribute('width', nextWidth);
if (data.resizableColumns) {
rows = $grid[0].tBodies[0].children;
for (i = 0; i < rows.length; i++) {
rows[i].cells[index].setAttribute('width', newWidth);
cell = rows[i].cells[index + 1];
cell.setAttribute('width', nextWidth);
}
}
}
};
}
},
public: {
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.resizableColumns.public);
if (fullConfig.resizableColumns && gj.draggable) {
$grid.on('initialized', function () {
gj.grid.plugins.resizableColumns.private.init($grid, fullConfig);
});
}
}
};
/**
*/
gj.grid.plugins.rowReorder = {
config: {
base: {
/** If set to true, enable row reordering with drag and drop.
*/
rowReorder: false,
/** If set, enable row reordering only when you try to drag cell from the configured column.
* Accept only field names of columns.
*/
rowReorderColumn: undefined,
/** If set, update the value in the field for all records. Accept only field names of columns.
*/
orderNumberField: undefined,
style: {
targetRowIndicatorTop: 'gj-grid-row-reorder-indicator-top',
targetRowIndicatorBottom: 'gj-grid-row-reorder-indicator-bottom'
}
}
},
private: {
init: function ($grid) {
var i, columnPosition, $row,
$rows = $grid.find('tbody tr[data-role="row"]');
if ($grid.data('rowReorderColumn')) {
columnPosition = gj.grid.methods.getColumnPosition($grid.data('columns'), $grid.data('rowReorderColumn'));
}
for (i = 0; i < $rows.length; i++) {
$row = $($rows[i]);
if (typeof (columnPosition) !== 'undefined') {
$row.find('td:eq(' + columnPosition + ')').on('mousedown', gj.grid.plugins.rowReorder.private.createRowMouseDownHandler($grid, $row));
} else {
$row.on('mousedown', gj.grid.plugins.rowReorder.private.createRowMouseDownHandler($grid, $row));
}
}
},
createRowMouseDownHandler: function ($grid, $trSource) {
return function (e) {
var $dragEl = $grid.clone(),
columns = $grid.data('columns'),
i, $cells;
$grid.addClass('gj-unselectable');
$('body').append($dragEl);
$dragEl.attr('data-role', 'draggable-clone').css('cursor', 'move');
$dragEl.children('thead').remove().children('tfoot').remove();
$dragEl.find('tbody tr:not([data-position="' + $trSource.data('position') + '"])').remove();
$cells = $dragEl.find('tbody tr td');
for (i = 0; i < $cells.length; i++) {
if (columns[i].width) {
$cells[i].setAttribute('width', columns[i].width);
}
}
$dragEl.draggable({
stop: gj.grid.plugins.rowReorder.private.createDragStopHandler($grid, $trSource)
});
$dragEl.css({
position: 'absolute', top: $trSource.offset().top, left: $trSource.offset().left, width: $trSource.width(), zIndex: 1
});
if ($trSource.attr('data-droppable') === 'true') {
$trSource.droppable('destroy');
}
$trSource.siblings('tr[data-role="row"]').each(function () {
var $dropEl = $(this);
if ($dropEl.attr('data-droppable') === 'true') {
$dropEl.droppable('destroy');
}
$dropEl.droppable({
over: gj.grid.plugins.rowReorder.private.createDroppableOverHandler($trSource),
out: gj.grid.plugins.rowReorder.private.droppableOut
});
});
$dragEl.trigger('mousedown');
};
},
createDragStopHandler: function ($grid, $trSource) {
return function (e, mousePosition) {
$('table[data-role="draggable-clone"]').draggable('destroy').remove();
$grid.removeClass('gj-unselectable');
$trSource.siblings('tr[data-role="row"]').each(function () {
var $trTarget = $(this),
targetPosition = $trTarget.data('position'),
sourcePosition = $trSource.data('position'),
data = $grid.data(),
$rows, $row, i, record, id;
if ($trTarget.droppable('isOver', mousePosition)) {
if (targetPosition < sourcePosition) {
$trTarget.before($trSource);
} else {
$trTarget.after($trSource);
}
data.records.splice(targetPosition - 1, 0, data.records.splice(sourcePosition - 1, 1)[0]);
$rows = $trTarget.parent().find('tr[data-role="row"]');
for (i = 0; i < $rows.length; i++) {
$($rows[i]).attr('data-position', i + 1);
}
if (data.orderNumberField) {
for (i = 0; i < data.records.length; i++) {
data.records[i][data.orderNumberField] = i + 1;
}
for (i = 0; i < $rows.length; i++) {
$row = $($rows[i]);
id = gj.grid.methods.getId($row, data.primaryKey, $row.attr('data-position'));
record = gj.grid.methods.getByPosition($grid, $row.attr('data-position'));
$grid.setCellContent(id, data.orderNumberField, record[data.orderNumberField]);
}
}
}
$trTarget.removeClass('gj-grid-top-border');
$trTarget.removeClass('gj-grid-bottom-border');
$trTarget.droppable('destroy');
});
}
},
createDroppableOverHandler: function ($trSource) {
return function (e) {
var $trTarget = $(this),
targetPosition = $trTarget.data('position'),
sourcePosition = $trSource.data('position');
if (targetPosition < sourcePosition) {
$trTarget.addClass('gj-grid-top-border');
} else {
$trTarget.addClass('gj-grid-bottom-border');
}
};
},
droppableOut: function () {
$(this).removeClass('gj-grid-top-border');
$(this).removeClass('gj-grid-bottom-border');
}
},
public: {
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.rowReorder.public);
if (fullConfig.rowReorder && gj.draggable && gj.droppable) {
$grid.on('dataBound', function () {
gj.grid.plugins.rowReorder.private.init($grid);
});
}
}
};
/**
*/
gj.grid.plugins.export = {
config: { base: {} },
public: {
/**
* Get grid data in Comma Separated Values (CSV) format.
*/
getCSV: function (includeAllRecords) {
var i, j, line = '', str = '',
columns = this.data().columns,
records = this.getAll(includeAllRecords);
if (records.length) {
for (i = 0; i < columns.length; i++) {
if (gj.grid.plugins.export.public.isColumnApplicable(columns[i])) {
line += '"' + (columns[i].title || columns[i].field).replace(/<[^>]+>/g, ' ') + '",';
}
}
str += line.slice(0, line.length - 1) + '\r\n';
for (i = 0; i < records.length; i++) {
line = '';
for (j = 0; j < columns.length; j++) {
if (gj.grid.plugins.export.public.isColumnApplicable(columns[j])) {
line += '"' + records[i][columns[j].field] + '",';
}
}
str += line.slice(0, line.length - 1) + '\r\n';
}
}
return str;
},
/**
* Download grid data in Comma Separated Values (CSV) format.
*/
downloadCSV: function (filename, includeAllRecords) {
var link = document.createElement('a');
document.body.appendChild(link);
link.download = filename || 'griddata.csv';
if (window.navigator.userAgent.indexOf("Edge") > -1) {
link.href = URL.createObjectURL(new Blob([this.getCSV(includeAllRecords)], { type: 'text/csv;charset=utf-8;' }));
} else {
link.href = 'data:text/csv;charset=utf-8,' + escape(this.getCSV(includeAllRecords));
}
link.click();
document.body.removeChild(link);
return this;
},
isColumnApplicable: function (column) {
return column.hidden !== true && !column.role;
}
},
configure: function ($grid) {
$.extend(true, $grid, gj.grid.plugins.export.public);
}
};
/**
*/
gj.grid.plugins.columnReorder = {
config: {
base: {
/** If set to true, enable column reordering with drag and drop.
*/
columnReorder: false,
dragReady: false,
style: {
targetRowIndicatorTop: 'gj-grid-row-reorder-indicator-top',
targetRowIndicatorBottom: 'gj-grid-row-reorder-indicator-bottom'
}
}
},
private: {
init: function ($grid) {
var i, $cell,
$cells = $grid.find('thead tr th');
for (i = 0; i < $cells.length; i++) {
$cell = $($cells[i]);
$cell.on('mousedown', gj.grid.plugins.columnReorder.private.createMouseDownHandler($grid, $cell));
$cell.on('mousemove', gj.grid.plugins.columnReorder.private.createMouseMoveHandler($grid, $cell));
$cell.on('mouseup', gj.grid.plugins.columnReorder.private.createMouseUpHandler($grid, $cell));
}
},
createMouseDownHandler: function ($grid) {
return function (e) {
$grid.timeout = setTimeout(function () {
$grid.data('dragReady', true);
}, 100);
}
},
createMouseUpHandler: function ($grid) {
return function (e) {
clearTimeout($grid.timeout);
$grid.data('dragReady', false);
}
},
createMouseMoveHandler: function ($grid, $thSource) {
return function (e) {
var $dragEl, srcIndex;
if ($grid.data('dragReady')) {
$grid.data('dragReady', false);
$dragEl = $grid.clone();
srcIndex = $thSource.index();
$grid.addClass('gj-unselectable');
$('body').append($dragEl);
$dragEl.attr('data-role', 'draggable-clone').css('cursor', 'move');
$dragEl.find('thead tr th:eq(' + srcIndex + ')').siblings().remove();
$dragEl.find('tbody tr[data-role != "row"]').remove();
$dragEl.find('tbody tr td:nth-child(' + (srcIndex + 1) + ')').siblings().remove();
$dragEl.find('tfoot').remove();
$dragEl.draggable({
stop: gj.grid.plugins.columnReorder.private.createDragStopHandler($grid, $thSource)
});
$dragEl.css({
position: 'absolute', top: $thSource.offset().top, left: $thSource.offset().left, width: $thSource.width(), zIndex: 1
});
if ($thSource.attr('data-droppable') === 'true') {
$thSource.droppable('destroy');
}
$thSource.siblings('th').each(function () {
var $dropEl = $(this);
if ($dropEl.attr('data-droppable') === 'true') {
$dropEl.droppable('destroy');
}
$dropEl.droppable({
over: gj.grid.plugins.columnReorder.private.createDroppableOverHandler($grid, $thSource),
out: gj.grid.plugins.columnReorder.private.droppableOut
});
});
$dragEl.trigger('mousedown');
}
};
},
createDragStopHandler: function ($grid, $thSource) {
return function (e, mousePosition) {
$('table[data-role="draggable-clone"]').draggable('destroy').remove();
$grid.removeClass('gj-unselectable');
$thSource.siblings('th').each(function () {
var $thTarget = $(this),
data = $grid.data(),
targetPosition = gj.grid.methods.getColumnPosition(data.columns, $thTarget.data('field')),
sourcePosition = gj.grid.methods.getColumnPosition(data.columns, $thSource.data('field'));
$thTarget.removeClass('gj-grid-left-border').removeClass('gj-grid-right-border');
$thTarget.closest('table').find('tbody tr[data-role="row"] td:nth-child(' + ($thTarget.index() + 1) + ')').removeClass('gj-grid-left-border').removeClass('gj-grid-right-border');
if ($thTarget.droppable('isOver', mousePosition)) {
if (targetPosition < sourcePosition) {
$thTarget.before($thSource);
} else {
$thTarget.after($thSource);
}
gj.grid.plugins.columnReorder.private.moveRowCells($grid, sourcePosition, targetPosition);
data.columns.splice(targetPosition, 0, data.columns.splice(sourcePosition, 1)[0]);
}
$thTarget.droppable('destroy');
});
}
},
moveRowCells: function ($grid, sourcePosition, targetPosition) {
var i, $row, $rows = $grid.find('tbody tr[data-role="row"]');
for (i = 0; i < $rows.length; i++) {
$row = $($rows[i]);
if (targetPosition < sourcePosition) {
$row.find('td:eq(' + targetPosition + ')').before($row.find('td:eq(' + sourcePosition + ')'));
} else {
$row.find('td:eq(' + targetPosition + ')').after($row.find('td:eq(' + sourcePosition + ')'));
}
}
},
createDroppableOverHandler: function ($grid, $thSource) {
return function (e) {
var $thTarget = $(this),
data = $grid.data(),
targetPosition = gj.grid.methods.getColumnPosition(data.columns, $thTarget.data('field')),
sourcePosition = gj.grid.methods.getColumnPosition(data.columns, $thSource.data('field'));
if (targetPosition < sourcePosition) {
$thTarget.addClass('gj-grid-left-border');
$grid.find('tbody tr[data-role="row"] td:nth-child(' + ($thTarget.index() + 1) + ')').addClass('gj-grid-left-border');
} else {
$thTarget.addClass('gj-grid-right-border');
$grid.find('tbody tr[data-role="row"] td:nth-child(' + ($thTarget.index() + 1) + ')').addClass('gj-grid-right-border');
}
};
},
droppableOut: function () {
var $thTarget = $(this);
$thTarget.removeClass('gj-grid-left-border').removeClass('gj-grid-right-border');
$thTarget.closest('table').find('tbody tr[data-role="row"] td:nth-child(' + ($thTarget.index() + 1) + ')').removeClass('gj-grid-left-border').removeClass('gj-grid-right-border');
}
},
public: {
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.columnReorder.public);
if (fullConfig.columnReorder) {
$grid.on('initialized', function () {
gj.grid.plugins.columnReorder.private.init($grid);
});
}
}
};
/**
*/
gj.grid.plugins.headerFilter = {
config: {
base: {
defaultColumnSettings: {
/** Indicates if the column is sortable. If set to false the header filter is hidden.
*/
filterable: true
},
/** If set to true, add filters for each column
*/
headerFilter: {
/** Type of the header filter
*/
type: 'onenterkeypress'
}
}
},
private: {
init: function ($grid) {
var i, $th, $ctrl, data = $grid.data(),
$filterTr = $('
');
for (i = 0; i < data.columns.length; i++) {
$th = $('
');
if (data.columns[i].filterable) {
$ctrl = $('');
if ('onchange' === data.headerFilter.type) {
$ctrl.on('input propertychange', function (e) {
gj.grid.plugins.headerFilter.private.reload($grid, $(this));
});
} else {
$ctrl.on('keypress', function (e) {
if (e.which == 13) {
gj.grid.plugins.headerFilter.private.reload($grid, $(this));
}
});
$ctrl.on('blur', function (e) {
gj.grid.plugins.headerFilter.private.reload($grid, $(this));
});
}
$th.append($ctrl);
}
if (data.columns[i].hidden) {
$th.hide();
}
$filterTr.append($th);
}
$grid.children('thead').append($filterTr);
},
reload: function ($grid, $ctrl) {
var params = {};
params[$ctrl.data('field')] = $ctrl.val();
$grid.reload(params);
}
},
public: {
},
events: {
},
configure: function ($grid, fullConfig, clientConfig) {
$.extend(true, $grid, gj.grid.plugins.headerFilter.public);
var data = $grid.data();
if (clientConfig.headerFilter) {
$grid.on('initialized', function () {
gj.grid.plugins.headerFilter.private.init($grid);
});
}
}
};
/**
*/
gj.grid.plugins.grouping = {
config: {
base: {
paramNames: {
/** The name of the parameter that is going to send the name of the column for grouping.
* The grouping should be enabled in order this parameter to be in use.
*/
groupBy: 'groupBy',
/** The name of the parameter that is going to send the direction for grouping.
* The grouping should be enabled in order this parameter to be in use.
*/
groupByDirection: 'groupByDirection'
},
grouping: {
/** The name of the field that needs to be in use for grouping.
*/
groupBy: undefined,
direction: 'asc'
},
icons: {
/** Expand row icon definition.
*/
expandGroup: '',
/** Collapse row icon definition.
*/
collapseGroup: ''
}
},
fontawesome: {
icons: {
expandGroup: '',
collapseGroup: ''
}
},
glyphicons: {
icons: {
expandGroup: '',
collapseGroup: ''
}
}
},
private: {
init: function ($grid) {
var previousValue, data = $grid.data();
previousValue = undefined;
$grid.on('rowDataBound', function (e, $row, id, record) {
if (previousValue !== record[data.grouping.groupBy] || $row[0].rowIndex === 1) {
var colspan = gj.grid.methods.countVisibleColumns($grid) - 1,
$groupRow = $('