summaryrefslogtreecommitdiffstats
path: root/dev
diff options
context:
space:
mode:
authorHalil İbrahim Kalkan <hikalkan@gmail.com>2013-02-13 16:04:34 +0200
committerHalil İbrahim Kalkan <hikalkan@gmail.com>2013-02-13 16:04:34 +0200
commit6a7148fa53b0fb428c853d01150f2843122fa6d0 (patch)
treed6e813a899343cf165c3a1da565930890d6b5fd2 /dev
parent277c6e18d910accfe145f0b3cacb27aef437d1ac (diff)
downloadjtable-2.2.1.zip
jtable-2.2.1.tar.gz
jtable-2.2.1.tar.bz2
jTable v2.2.1v2.2.1
Support for saving page size preference of user. [#219] Fixed some issues. [#167, #214, #215, #216, #219, #231] Added 'Dutch - The Netherlands' localization. Updated some localization files.
Diffstat (limited to 'dev')
-rw-r--r--dev/jquery.jtable.core.js89
-rw-r--r--dev/jquery.jtable.dynamiccolumns.js990
-rw-r--r--dev/jquery.jtable.header.txt2
-rw-r--r--dev/jquery.jtable.paging.js66
-rw-r--r--dev/jquery.jtable.selecting.js756
5 files changed, 975 insertions, 928 deletions
diff --git a/dev/jquery.jtable.core.js b/dev/jquery.jtable.core.js
index 3e26eee..5a94b6b 100644
--- a/dev/jquery.jtable.core.js
+++ b/dev/jquery.jtable.core.js
@@ -19,6 +19,7 @@
dialogHideEffect: 'fade',
showCloseButton: false,
loadingAnimationDelay: 500,
+ saveUserPreferences: true,
ajaxSettings: {
type: 'POST',
@@ -104,6 +105,8 @@
this._createBusyPanel();
this._createErrorDialogDiv();
this._addNoDataRow();
+
+ this._cookieKeyPrefix = this._generateCookieKeyPrefix();
},
/* Normalizes some options for all fields (sets default values).
@@ -861,22 +864,22 @@
_parseDate: function (dateString) {
if (dateString.indexOf('Date') >= 0) { //Format: /Date(1320259705710)/
return new Date(
- parseInt(dateString.substr(6))
+ parseInt(dateString.substr(6), 10)
);
} else if (dateString.length == 10) { //Format: 2011-01-01
return new Date(
- parseInt(dateString.substr(0, 4)),
- parseInt(dateString.substr(5, 2)) - 1,
- parseInt(dateString.substr(8, 2))
+ parseInt(dateString.substr(0, 4), 10),
+ parseInt(dateString.substr(5, 2), 10) - 1,
+ parseInt(dateString.substr(8, 2), 10)
);
} else if (dateString.length == 19) { //Format: 2011-01-01 20:32:42
return new Date(
- parseInt(dateString.substr(0, 4)),
- parseInt(dateString.substr(5, 2)) - 1,
- parseInt(dateString.substr(8, 2)),
- parseInt(dateString.substr(11, 2)),
- parseInt(dateString.substr(14, 2)),
- parseInt(dateString.substr(17, 2))
+ parseInt(dateString.substr(0, 4), 10),
+ parseInt(dateString.substr(5, 2), 10) - 1,
+ parseInt(dateString.substr(8, 2, 10)),
+ parseInt(dateString.substr(11, 2), 10),
+ parseInt(dateString.substr(14, 2), 10),
+ parseInt(dateString.substr(17, 2), 10)
);
} else {
this._logWarn('Given date is not properly formatted: ' + dateString);
@@ -1069,6 +1072,72 @@
_getKeyValueOfRecord: function (record) {
return record[this._keyField];
},
+
+ /************************************************************************
+ * COOKIE *
+ *************************************************************************/
+
+ /* Sets a cookie with given key.
+ *************************************************************************/
+ _setCookie: function (key, value) {
+ key = this._cookieKeyPrefix + key;
+
+ var expireDate = new Date();
+ expireDate.setDate(expireDate.getDate() + 30);
+ document.cookie = encodeURIComponent(key) + '=' + encodeURIComponent(value) + "; expires=" + expireDate.toUTCString();
+ },
+
+ /* Gets a cookie with given key.
+ *************************************************************************/
+ _getCookie: function (key) {
+ key = this._cookieKeyPrefix + key;
+
+ var equalities = document.cookie.split('; ');
+ for (var i = 0; i < equalities.length; i++) {
+ if (!equalities[i]) {
+ continue;
+ }
+
+ var splitted = equalities[i].split('=');
+ if (splitted.length != 2) {
+ continue;
+ }
+
+ if (decodeURIComponent(splitted[0]) === key) {
+ return decodeURIComponent(splitted[1] || '');
+ }
+ }
+
+ return null;
+ },
+
+ /* Generates a hash key to be prefix for all cookies for this jtable instance.
+ *************************************************************************/
+ _generateCookieKeyPrefix: function () {
+
+ var simpleHash = function (value) {
+ var hash = 0;
+ if (value.length == 0) {
+ return hash;
+ }
+
+ for (var i = 0; i < value.length; i++) {
+ var ch = value.charCodeAt(i);
+ hash = ((hash << 5) - hash) + ch;
+ hash = hash & hash;
+ }
+
+ return hash;
+ };
+
+ var strToHash = '';
+ if (this.options.tableId) {
+ strToHash = strToHash + this.options.tableId + '#';
+ }
+
+ strToHash = strToHash + this._columnList.join('$') + '#c' + this._$table.find('thead th').length;
+ return 'jtable#' + simpleHash(strToHash);
+ },
/************************************************************************
* EVENT RAISING METHODS *
diff --git a/dev/jquery.jtable.dynamiccolumns.js b/dev/jquery.jtable.dynamiccolumns.js
index 88487fe..fefdb58 100644
--- a/dev/jquery.jtable.dynamiccolumns.js
+++ b/dev/jquery.jtable.dynamiccolumns.js
@@ -1,529 +1,461 @@
-/************************************************************************
-* DYNAMIC COLUMNS extension for jTable *
-* (Show/hide/resize columns) *
-*************************************************************************/
-(function ($) {
-
- //Reference to base object members
- var base = {
- _create: $.hik.jtable.prototype._create,
- _normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
- _createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
- _createCellForRecordField: $.hik.jtable.prototype._createCellForRecordField
- };
-
- //extension members
- $.extend(true, $.hik.jtable.prototype, {
-
- /************************************************************************
- * DEFAULT OPTIONS / EVENTS *
- *************************************************************************/
-
- options: {
- tableId: undefined,
- columnResizable: true,
- columnSelectable: true,
- saveUserPreferences: true
- },
-
- /************************************************************************
- * PRIVATE FIELDS *
- *************************************************************************/
-
- _$columnSelectionDiv: null,
- _$columnResizeBar: null,
- _cookieKeyPrefix: null,
- _currentResizeArgs: null,
-
- /************************************************************************
- * OVERRIDED METHODS *
- *************************************************************************/
-
- /* Overrides _addRowToTableHead method.
- *************************************************************************/
-
- _create: function () {
- base._create.apply(this, arguments);
-
- this._createColumnResizeBar();
- this._createColumnSelection();
-
- this._cookieKeyPrefix = this._generateCookieKeyPrefix();
- if (this.options.saveUserPreferences) {
- this._loadColumnSettings();
- }
-
- this._normalizeColumnWidths();
- },
-
- /* Normalizes some options for a field (sets default values).
- *************************************************************************/
- _normalizeFieldOptions: function (fieldName, props) {
- base._normalizeFieldOptions.apply(this, arguments);
-
- //columnResizable
- if (this.options.columnResizable) {
- props.columnResizable = (props.columnResizable != false);
- }
-
- //visibility
- if (!props.visibility) {
- props.visibility = 'visible';
- }
- },
-
- /* Overrides _createHeaderCellForField to make columns dynamic.
- *************************************************************************/
- _createHeaderCellForField: function (fieldName, field) {
- var $headerCell = base._createHeaderCellForField.apply(this, arguments);
-
- //Make data columns resizable except the last one
- if (this.options.columnResizable && field.columnResizable && (fieldName != this._columnList[this._columnList.length - 1])) {
- this._makeColumnResizable($headerCell);
- }
-
- //Hide column if needed
- if (field.visibility == 'hidden') {
- $headerCell.hide();
- }
-
- return $headerCell;
- },
-
- /* Overrides _createHeaderCellForField to decide show or hide a column.
- *************************************************************************/
- _createCellForRecordField: function (record, fieldName) {
- var $column = base._createCellForRecordField.apply(this, arguments);
-
- var field = this.options.fields[fieldName];
- if (field.visibility == 'hidden') {
- $column.hide();
- }
-
- return $column;
- },
-
- /************************************************************************
- * PUBLIC METHODS *
- *************************************************************************/
-
- /* Changes visibility of a column.
- *************************************************************************/
- changeColumnVisibility: function (columnName, visibility) {
- this._changeColumnVisibilityInternal(columnName, visibility);
- this._normalizeColumnWidths();
- if (this.options.saveUserPreferences) {
- this._saveColumnSettings();
- }
- },
-
- /************************************************************************
- * PRIVATE METHODS *
- *************************************************************************/
-
- /* Changes visibility of a column.
- *************************************************************************/
- _changeColumnVisibilityInternal: function (columnName, visibility) {
- //Check if there is a column with given name
- var columnIndex = this._columnList.indexOf(columnName);
- if (columnIndex < 0) {
- this._logWarn('Column "' + columnName + '" does not exist in fields!');
- return;
- }
-
- //Check if visibility value is valid
- if (['visible', 'hidden', 'fixed'].indexOf(visibility) < 0) {
- this._logWarn('Visibility value is not valid: "' + visibility + '"! Options are: visible, hidden, fixed.');
- return;
- }
-
- //Get the field
- var field = this.options.fields[columnName];
- if (field.visibility == visibility) {
- return; //No action if new value is same as old one.
- }
-
- //Hide or show the column if needed
- var columnIndexInTable = this._firstDataColumnOffset + columnIndex + 1;
- if (field.visibility != 'hidden' && visibility == 'hidden') {
- this._$table
- .find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + ')')
- .hide();
- } else if (field.visibility == 'hidden' && visibility != 'hidden') {
- this._$table
- .find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + ')')
- .show()
- .css('display', 'table-cell');
- }
-
- field.visibility = visibility;
- },
-
- /* Prepares dialog to change settings.
- *************************************************************************/
- _createColumnSelection: function () {
- var self = this;
-
- //Create a div for dialog and add to container element
- this._$columnSelectionDiv = $('<div />')
- .addClass('jtable-column-selection-container')
- .appendTo(self._$mainContainer);
-
- this._$table.children('thead').bind('contextmenu', function (e) {
- if (!self.options.columnSelectable) {
- return;
- }
-
- e.preventDefault();
-
- //Make an overlay div to disable page clicks
- $('<div />')
- .addClass('jtable-contextmenu-overlay')
- .click(function () {
- $(this).remove();
- self._$columnSelectionDiv.hide();
- })
- .bind('contextmenu', function () { return false; })
- .appendTo(document.body);
-
- self._fillColumnSelection();
-
- //Calculate position of column selection list and show it
-
- var containerOffset = self._$mainContainer.offset();
- var selectionDivTop = e.pageY - containerOffset.top;
- var selectionDivLeft = e.pageX - containerOffset.left;
-
- var selectionDivMinWidth = 100; //in pixels
- var containerWidth = self._$mainContainer.width();
-
- //If user clicks right area of header of the table, show list at a little left
- if ((containerWidth > selectionDivMinWidth) && (selectionDivLeft > (containerWidth - selectionDivMinWidth))) {
- selectionDivLeft = containerWidth - selectionDivMinWidth;
- }
-
- self._$columnSelectionDiv.css({
- left: selectionDivLeft,
- top: selectionDivTop,
- 'min-width': selectionDivMinWidth + 'px'
- }).show();
- });
- },
-
- /* Prepares content of settings dialog.
- *************************************************************************/
- _fillColumnSelection: function () {
- var self = this;
-
- var $columnsUl = $('<ul></ul>')
- .addClass('jtable-column-select-list');
- for (var i = 0; i < this._columnList.length; i++) {
- var columnName = this._columnList[i];
- var field = this.options.fields[columnName];
-
- //Crete li element
- var $columnLi = $('<li></li>').appendTo($columnsUl);
-
- //Create label for the checkbox
- var $label = $('<label for="' + columnName + '"></label>')
- .append($('<span>' + (field.title || columnName) + '</span>'))
- .appendTo($columnLi);
-
- //Create checkbox
- var $checkbox = $('<input type="checkbox" name="' + columnName + '">')
- .prependTo($label)
- .click(function () {
- var $clickedCheckbox = $(this);
- var clickedColumnName = $clickedCheckbox.attr('name');
- var clickedField = self.options.fields[clickedColumnName];
- if (clickedField.visibility == 'fixed') {
- return;
- }
-
- self.changeColumnVisibility(clickedColumnName, $clickedCheckbox.is(':checked') ? 'visible' : 'hidden');
- });
-
- //Check, if column if shown
- if (field.visibility != 'hidden') {
- $checkbox.attr('checked', 'checked');
- }
-
- //Disable, if column is fixed
- if (field.visibility == 'fixed') {
- $checkbox.attr('disabled', 'disabled');
- }
- }
-
- this._$columnSelectionDiv.html($columnsUl);
- },
-
- /* creates a vertical bar that is shown while resizing columns.
- *************************************************************************/
- _createColumnResizeBar: function () {
- this._$columnResizeBar = $('<div />')
- .addClass('jtable-column-resize-bar')
- .appendTo(this._$mainContainer)
- .hide();
- },
-
- /* Makes a column sortable.
- *************************************************************************/
- _makeColumnResizable: function ($columnHeader) {
- var self = this;
-
- //Create a handler to handle mouse click event
- $('<div />')
- .addClass('jtable-column-resize-handler')
- .appendTo($columnHeader.find('.jtable-column-header-container')) //Append the handler to the column
- .mousedown(function (downevent) { //handle mousedown event for the handler
- downevent.preventDefault();
- downevent.stopPropagation();
-
- var mainContainerOffset = self._$mainContainer.offset();
-
- //Get a reference to the next column
- var $nextColumnHeader = $columnHeader.nextAll('th.jtable-column-header:visible:first');
- if (!$nextColumnHeader.length) {
- return;
- }
-
- //Store some information to be used on resizing
- var minimumColumnWidth = 10; //A column's width can not be smaller than 10 pixel.
- self._currentResizeArgs = {
- currentColumnStartWidth: $columnHeader.outerWidth(),
- minWidth: minimumColumnWidth,
- maxWidth: $columnHeader.outerWidth() + $nextColumnHeader.outerWidth() - minimumColumnWidth,
- mouseStartX: downevent.pageX,
- minResizeX: function () { return this.mouseStartX - (this.currentColumnStartWidth - this.minWidth); },
- maxResizeX: function () { return this.mouseStartX + (this.maxWidth - this.currentColumnStartWidth); }
- };
-
- //Handle mouse move event to move resizing bar
- var resizeonmousemove = function (moveevent) {
- if (!self._currentResizeArgs) {
- return;
- }
-
- var resizeBarX = self._normalizeNumber(moveevent.pageX, self._currentResizeArgs.minResizeX(), self._currentResizeArgs.maxResizeX());
- self._$columnResizeBar.css('left', (resizeBarX - mainContainerOffset.left) + 'px');
- };
-
- //Handle mouse up event to finish resizing of the column
- var resizeonmouseup = function (upevent) {
- if (!self._currentResizeArgs) {
- return;
- }
-
- $(document).unbind('mousemove', resizeonmousemove);
- $(document).unbind('mouseup', resizeonmouseup);
-
- self._$columnResizeBar.hide();
-
- //Calculate new widths in pixels
- var mouseChangeX = upevent.pageX - self._currentResizeArgs.mouseStartX;
- var currentColumnFinalWidth = self._normalizeNumber(self._currentResizeArgs.currentColumnStartWidth + mouseChangeX, self._currentResizeArgs.minWidth, self._currentResizeArgs.maxWidth);
- var nextColumnFinalWidth = $nextColumnHeader.outerWidth() + (self._currentResizeArgs.currentColumnStartWidth - currentColumnFinalWidth);
-
- //Calculate widths as percent
- var pixelToPercentRatio = $columnHeader.data('width-in-percent') / self._currentResizeArgs.currentColumnStartWidth;
- $columnHeader.data('width-in-percent', currentColumnFinalWidth * pixelToPercentRatio);
- $nextColumnHeader.data('width-in-percent', nextColumnFinalWidth * pixelToPercentRatio);
-
- //Set new widths to columns (resize!)
- $columnHeader.css('width', $columnHeader.data('width-in-percent') + '%');
- $nextColumnHeader.css('width', $nextColumnHeader.data('width-in-percent') + '%');
-
- //Normalize all column widths
- self._normalizeColumnWidths();
-
- //Finish resizing
- self._currentResizeArgs = null;
-
- //Save current preferences
- if (self.options.saveUserPreferences) {
- self._saveColumnSettings();
- }
- };
-
- //Show vertical resize bar
- self._$columnResizeBar
- .show()
- .css({
- top: ($columnHeader.offset().top - mainContainerOffset.top) + 'px',
- left: (downevent.pageX - mainContainerOffset.left) + 'px',
- height: (self._$table.outerHeight()) + 'px'
- });
-
- //Bind events
- $(document).bind('mousemove', resizeonmousemove);
- $(document).bind('mouseup', resizeonmouseup);
- });
- },
-
- /* Normalizes column widths as percent for current view.
- *************************************************************************/
- _normalizeColumnWidths: function () {
-
- //Set command column width
- var commandColumnHeaders = this._$table
- .find('>thead th.jtable-command-column-header')
- .data('width-in-percent', 1)
- .css('width', '1%');
-
- //Find data columns
- var headerCells = this._$table.find('>thead th.jtable-column-header');
-
- //Calculate total width of data columns
- var totalWidthInPixel = 0;
- headerCells.each(function () {
- var $cell = $(this);
- if ($cell.is(':visible')) {
- totalWidthInPixel += $cell.outerWidth();
- }
- });
-
- //Calculate width of each column
- var columnWidhts = {};
- var availableWidthInPercent = 100.0 - commandColumnHeaders.length;
- headerCells.each(function () {
- var $cell = $(this);
- if ($cell.is(':visible')) {
- var fieldName = $cell.data('fieldName');
- var widthInPercent = $cell.outerWidth() * availableWidthInPercent / totalWidthInPixel;
- columnWidhts[fieldName] = widthInPercent;
- }
- });
-
- //Set width of each column
- headerCells.each(function () {
- var $cell = $(this);
- if ($cell.is(':visible')) {
- var fieldName = $cell.data('fieldName');
- $cell.data('width-in-percent', columnWidhts[fieldName]).css('width', columnWidhts[fieldName] + '%');
- }
- });
- },
-
- /* Saves field setting to cookie.
- * Saved setting will be a string like that:
- * fieldName1=visible;23|fieldName2=hidden;17|...
- *************************************************************************/
- _saveColumnSettings: function () {
- var self = this;
- var fieldSettings = '';
- this._$table.find('>thead >tr >th.jtable-column-header').each(function () {
- var $cell = $(this);
- var fieldName = $cell.data('fieldName');
- var columnWidth = $cell.data('width-in-percent');
- var fieldVisibility = self.options.fields[fieldName].visibility;
- var fieldSetting = fieldName + "=" + fieldVisibility + ';' + columnWidth;
- fieldSettings = fieldSettings + fieldSetting + '|';
- });
-
- this._setCookie('column-settings', fieldSettings.substr(0, fieldSettings.length - 1));
- },
-
- /* Loads field settings from cookie that is saved by _saveFieldSettings method.
- *************************************************************************/
- _loadColumnSettings: function () {
- var self = this;
- var columnSettingsCookie = this._getCookie('column-settings');
- if (!columnSettingsCookie) {
- return;
- }
-
- var columnSettings = {};
- $.each(columnSettingsCookie.split('|'), function (inx, fieldSetting) {
- var splitted = fieldSetting.split('=');
- var fieldName = splitted[0];
- var settings = splitted[1].split(';');
- columnSettings[fieldName] = {
- columnVisibility: settings[0],
- columnWidth: settings[1]
- }; ;
- });
-
- var headerCells = this._$table.find('>thead >tr >th.jtable-column-header');
- headerCells.each(function () {
- var $cell = $(this);
- var fieldName = $cell.data('fieldName');
- var field = self.options.fields[fieldName];
- if (columnSettings[fieldName]) {
- if (field.visibility != 'fixed') {
- self._changeColumnVisibilityInternal(fieldName, columnSettings[fieldName].columnVisibility);
- }
-
- $cell.data('width-in-percent', columnSettings[fieldName].columnWidth).css('width', columnSettings[fieldName].columnWidth + '%');
- }
- });
- },
-
- /************************************************************************
- * COOKIE *
- *************************************************************************/
-
- /* Sets a cookie with given key.
- *************************************************************************/
- _setCookie: function (key, value) {
- key = this._cookieKeyPrefix + key;
-
- var expireDate = new Date();
- expireDate.setDate(expireDate.getDate() + 30);
- document.cookie = encodeURIComponent(key) + '=' + encodeURIComponent(value) + "; expires=" + expireDate.toUTCString();
- },
-
- /* Gets a cookie with given key.
- *************************************************************************/
- _getCookie: function (key) {
- key = this._cookieKeyPrefix + key;
-
- var equalities = document.cookie.split('; ');
- for (var i = 0; i < equalities.length; i++) {
- if (!equalities[i]) {
- continue;
- }
-
- var splitted = equalities[i].split('=');
- if (splitted.length != 2) {
- continue;
- }
-
- if (decodeURIComponent(splitted[0]) === key) {
- return decodeURIComponent(splitted[1] || '');
- }
- }
-
- return null;
- },
-
- /* Generates a hash key to be prefix for all cookies for this jtable instance.
- *************************************************************************/
- _generateCookieKeyPrefix: function () {
-
- var simpleHash = function (value) {
- var hash = 0;
- if (value.length == 0) {
- return hash;
- }
-
- for (var i = 0; i < value.length; i++) {
- var ch = value.charCodeAt(i);
- hash = ((hash << 5) - hash) + ch;
- hash = hash & hash;
- }
-
- return hash;
- };
-
- var strToHash = '';
- if (this.options.tableId) {
- strToHash = strToHash + this.options.tableId + '#';
- }
-
- strToHash = strToHash + this._columnList.join('$') + '#c' + this._$table.find('thead th').length;
- return 'jtable#' + simpleHash(strToHash);
- }
-
- });
-
-})(jQuery);
+/************************************************************************
+* DYNAMIC COLUMNS extension for jTable *
+* (Show/hide/resize columns) *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
+ _createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
+ _createCellForRecordField: $.hik.jtable.prototype._createCellForRecordField
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+
+ options: {
+ tableId: undefined,
+ columnResizable: true,
+ columnSelectable: true
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _$columnSelectionDiv: null,
+ _$columnResizeBar: null,
+ _cookieKeyPrefix: null,
+ _currentResizeArgs: null,
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides _addRowToTableHead method.
+ *************************************************************************/
+
+ _create: function () {
+ base._create.apply(this, arguments);
+
+ this._createColumnResizeBar();
+ this._createColumnSelection();
+
+ if (this.options.saveUserPreferences) {
+ this._loadColumnSettings();
+ }
+
+ this._normalizeColumnWidths();
+ },
+
+ /* Normalizes some options for a field (sets default values).
+ *************************************************************************/
+ _normalizeFieldOptions: function (fieldName, props) {
+ base._normalizeFieldOptions.apply(this, arguments);
+
+ //columnResizable
+ if (this.options.columnResizable) {
+ props.columnResizable = (props.columnResizable != false);
+ }
+
+ //visibility
+ if (!props.visibility) {
+ props.visibility = 'visible';
+ }
+ },
+
+ /* Overrides _createHeaderCellForField to make columns dynamic.
+ *************************************************************************/
+ _createHeaderCellForField: function (fieldName, field) {
+ var $headerCell = base._createHeaderCellForField.apply(this, arguments);
+
+ //Make data columns resizable except the last one
+ if (this.options.columnResizable && field.columnResizable && (fieldName != this._columnList[this._columnList.length - 1])) {
+ this._makeColumnResizable($headerCell);
+ }
+
+ //Hide column if needed
+ if (field.visibility == 'hidden') {
+ $headerCell.hide();
+ }
+
+ return $headerCell;
+ },
+
+ /* Overrides _createHeaderCellForField to decide show or hide a column.
+ *************************************************************************/
+ _createCellForRecordField: function (record, fieldName) {
+ var $column = base._createCellForRecordField.apply(this, arguments);
+
+ var field = this.options.fields[fieldName];
+ if (field.visibility == 'hidden') {
+ $column.hide();
+ }
+
+ return $column;
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Changes visibility of a column.
+ *************************************************************************/
+ changeColumnVisibility: function (columnName, visibility) {
+ this._changeColumnVisibilityInternal(columnName, visibility);
+ this._normalizeColumnWidths();
+ if (this.options.saveUserPreferences) {
+ this._saveColumnSettings();
+ }
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Changes visibility of a column.
+ *************************************************************************/
+ _changeColumnVisibilityInternal: function (columnName, visibility) {
+ //Check if there is a column with given name
+ var columnIndex = this._columnList.indexOf(columnName);
+ if (columnIndex < 0) {
+ this._logWarn('Column "' + columnName + '" does not exist in fields!');
+ return;
+ }
+
+ //Check if visibility value is valid
+ if (['visible', 'hidden', 'fixed'].indexOf(visibility) < 0) {
+ this._logWarn('Visibility value is not valid: "' + visibility + '"! Options are: visible, hidden, fixed.');
+ return;
+ }
+
+ //Get the field
+ var field = this.options.fields[columnName];
+ if (field.visibility == visibility) {
+ return; //No action if new value is same as old one.
+ }
+
+ //Hide or show the column if needed
+ var columnIndexInTable = this._firstDataColumnOffset + columnIndex + 1;
+ if (field.visibility != 'hidden' && visibility == 'hidden') {
+ this._$table
+ .find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + ')')
+ .hide();
+ } else if (field.visibility == 'hidden' && visibility != 'hidden') {
+ this._$table
+ .find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + ')')
+ .show()
+ .css('display', 'table-cell');
+ }
+
+ field.visibility = visibility;
+ },
+
+ /* Prepares dialog to change settings.
+ *************************************************************************/
+ _createColumnSelection: function () {
+ var self = this;
+
+ //Create a div for dialog and add to container element
+ this._$columnSelectionDiv = $('<div />')
+ .addClass('jtable-column-selection-container')
+ .appendTo(self._$mainContainer);
+
+ this._$table.children('thead').bind('contextmenu', function (e) {
+ if (!self.options.columnSelectable) {
+ return;
+ }
+
+ e.preventDefault();
+
+ //Make an overlay div to disable page clicks
+ $('<div />')
+ .addClass('jtable-contextmenu-overlay')
+ .click(function () {
+ $(this).remove();
+ self._$columnSelectionDiv.hide();
+ })
+ .bind('contextmenu', function () { return false; })
+ .appendTo(document.body);
+
+ self._fillColumnSelection();
+
+ //Calculate position of column selection list and show it
+
+ var containerOffset = self._$mainContainer.offset();
+ var selectionDivTop = e.pageY - containerOffset.top;
+ var selectionDivLeft = e.pageX - containerOffset.left;
+
+ var selectionDivMinWidth = 100; //in pixels
+ var containerWidth = self._$mainContainer.width();
+
+ //If user clicks right area of header of the table, show list at a little left
+ if ((containerWidth > selectionDivMinWidth) && (selectionDivLeft > (containerWidth - selectionDivMinWidth))) {
+ selectionDivLeft = containerWidth - selectionDivMinWidth;
+ }
+
+ self._$columnSelectionDiv.css({
+ left: selectionDivLeft,
+ top: selectionDivTop,
+ 'min-width': selectionDivMinWidth + 'px'
+ }).show();
+ });
+ },
+
+ /* Prepares content of settings dialog.
+ *************************************************************************/
+ _fillColumnSelection: function () {
+ var self = this;
+
+ var $columnsUl = $('<ul></ul>')
+ .addClass('jtable-column-select-list');
+ for (var i = 0; i < this._columnList.length; i++) {
+ var columnName = this._columnList[i];
+ var field = this.options.fields[columnName];
+
+ //Crete li element
+ var $columnLi = $('<li></li>').appendTo($columnsUl);
+
+ //Create label for the checkbox
+ var $label = $('<label for="' + columnName + '"></label>')
+ .append($('<span>' + (field.title || columnName) + '</span>'))
+ .appendTo($columnLi);
+
+ //Create checkbox
+ var $checkbox = $('<input type="checkbox" name="' + columnName + '">')
+ .prependTo($label)
+ .click(function () {
+ var $clickedCheckbox = $(this);
+ var clickedColumnName = $clickedCheckbox.attr('name');
+ var clickedField = self.options.fields[clickedColumnName];
+ if (clickedField.visibility == 'fixed') {
+ return;
+ }
+
+ self.changeColumnVisibility(clickedColumnName, $clickedCheckbox.is(':checked') ? 'visible' : 'hidden');
+ });
+
+ //Check, if column if shown
+ if (field.visibility != 'hidden') {
+ $checkbox.attr('checked', 'checked');
+ }
+
+ //Disable, if column is fixed
+ if (field.visibility == 'fixed') {
+ $checkbox.attr('disabled', 'disabled');
+ }
+ }
+
+ this._$columnSelectionDiv.html($columnsUl);
+ },
+
+ /* creates a vertical bar that is shown while resizing columns.
+ *************************************************************************/
+ _createColumnResizeBar: function () {
+ this._$columnResizeBar = $('<div />')
+ .addClass('jtable-column-resize-bar')
+ .appendTo(this._$mainContainer)
+ .hide();
+ },
+
+ /* Makes a column sortable.
+ *************************************************************************/
+ _makeColumnResizable: function ($columnHeader) {
+ var self = this;
+
+ //Create a handler to handle mouse click event
+ $('<div />')
+ .addClass('jtable-column-resize-handler')
+ .appendTo($columnHeader.find('.jtable-column-header-container')) //Append the handler to the column
+ .mousedown(function (downevent) { //handle mousedown event for the handler
+ downevent.preventDefault();
+ downevent.stopPropagation();
+
+ var mainContainerOffset = self._$mainContainer.offset();
+
+ //Get a reference to the next column
+ var $nextColumnHeader = $columnHeader.nextAll('th.jtable-column-header:visible:first');
+ if (!$nextColumnHeader.length) {
+ return;
+ }
+
+ //Store some information to be used on resizing
+ var minimumColumnWidth = 10; //A column's width can not be smaller than 10 pixel.
+ self._currentResizeArgs = {
+ currentColumnStartWidth: $columnHeader.outerWidth(),
+ minWidth: minimumColumnWidth,
+ maxWidth: $columnHeader.outerWidth() + $nextColumnHeader.outerWidth() - minimumColumnWidth,
+ mouseStartX: downevent.pageX,
+ minResizeX: function () { return this.mouseStartX - (this.currentColumnStartWidth - this.minWidth); },
+ maxResizeX: function () { return this.mouseStartX + (this.maxWidth - this.currentColumnStartWidth); }
+ };
+
+ //Handle mouse move event to move resizing bar
+ var resizeonmousemove = function (moveevent) {
+ if (!self._currentResizeArgs) {
+ return;
+ }
+
+ var resizeBarX = self._normalizeNumber(moveevent.pageX, self._currentResizeArgs.minResizeX(), self._currentResizeArgs.maxResizeX());
+ self._$columnResizeBar.css('left', (resizeBarX - mainContainerOffset.left) + 'px');
+ };
+
+ //Handle mouse up event to finish resizing of the column
+ var resizeonmouseup = function (upevent) {
+ if (!self._currentResizeArgs) {
+ return;
+ }
+
+ $(document).unbind('mousemove', resizeonmousemove);
+ $(document).unbind('mouseup', resizeonmouseup);
+
+ self._$columnResizeBar.hide();
+
+ //Calculate new widths in pixels
+ var mouseChangeX = upevent.pageX - self._currentResizeArgs.mouseStartX;
+ var currentColumnFinalWidth = self._normalizeNumber(self._currentResizeArgs.currentColumnStartWidth + mouseChangeX, self._currentResizeArgs.minWidth, self._currentResizeArgs.maxWidth);
+ var nextColumnFinalWidth = $nextColumnHeader.outerWidth() + (self._currentResizeArgs.currentColumnStartWidth - currentColumnFinalWidth);
+
+ //Calculate widths as percent
+ var pixelToPercentRatio = $columnHeader.data('width-in-percent') / self._currentResizeArgs.currentColumnStartWidth;
+ $columnHeader.data('width-in-percent', currentColumnFinalWidth * pixelToPercentRatio);
+ $nextColumnHeader.data('width-in-percent', nextColumnFinalWidth * pixelToPercentRatio);
+
+ //Set new widths to columns (resize!)
+ $columnHeader.css('width', $columnHeader.data('width-in-percent') + '%');
+ $nextColumnHeader.css('width', $nextColumnHeader.data('width-in-percent') + '%');
+
+ //Normalize all column widths
+ self._normalizeColumnWidths();
+
+ //Finish resizing
+ self._currentResizeArgs = null;
+
+ //Save current preferences
+ if (self.options.saveUserPreferences) {
+ self._saveColumnSettings();
+ }
+ };
+
+ //Show vertical resize bar
+ self._$columnResizeBar
+ .show()
+ .css({
+ top: ($columnHeader.offset().top - mainContainerOffset.top) + 'px',
+ left: (downevent.pageX - mainContainerOffset.left) + 'px',
+ height: (self._$table.outerHeight()) + 'px'
+ });
+
+ //Bind events
+ $(document).bind('mousemove', resizeonmousemove);
+ $(document).bind('mouseup', resizeonmouseup);
+ });
+ },
+
+ /* Normalizes column widths as percent for current view.
+ *************************************************************************/
+ _normalizeColumnWidths: function () {
+
+ //Set command column width
+ var commandColumnHeaders = this._$table
+ .find('>thead th.jtable-command-column-header')
+ .data('width-in-percent', 1)
+ .css('width', '1%');
+
+ //Find data columns
+ var headerCells = this._$table.find('>thead th.jtable-column-header');
+
+ //Calculate total width of data columns
+ var totalWidthInPixel = 0;
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ totalWidthInPixel += $cell.outerWidth();
+ }
+ });
+
+ //Calculate width of each column
+ var columnWidhts = {};
+ var availableWidthInPercent = 100.0 - commandColumnHeaders.length;
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ var fieldName = $cell.data('fieldName');
+ var widthInPercent = $cell.outerWidth() * availableWidthInPercent / totalWidthInPixel;
+ columnWidhts[fieldName] = widthInPercent;
+ }
+ });
+
+ //Set width of each column
+ headerCells.each(function () {
+ var $cell = $(this);
+ if ($cell.is(':visible')) {
+ var fieldName = $cell.data('fieldName');
+ $cell.data('width-in-percent', columnWidhts[fieldName]).css('width', columnWidhts[fieldName] + '%');
+ }
+ });
+ },
+
+ /* Saves field setting to cookie.
+ * Saved setting will be a string like that:
+ * fieldName1=visible;23|fieldName2=hidden;17|...
+ *************************************************************************/
+ _saveColumnSettings: function () {
+ var self = this;
+ var fieldSettings = '';
+ this._$table.find('>thead >tr >th.jtable-column-header').each(function () {
+ var $cell = $(this);
+ var fieldName = $cell.data('fieldName');
+ var columnWidth = $cell.data('width-in-percent');
+ var fieldVisibility = self.options.fields[fieldName].visibility;
+ var fieldSetting = fieldName + "=" + fieldVisibility + ';' + columnWidth;
+ fieldSettings = fieldSettings + fieldSetting + '|';
+ });
+
+ this._setCookie('column-settings', fieldSettings.substr(0, fieldSettings.length - 1));
+ },
+
+ /* Loads field settings from cookie that is saved by _saveFieldSettings method.
+ *************************************************************************/
+ _loadColumnSettings: function () {
+ var self = this;
+ var columnSettingsCookie = this._getCookie('column-settings');
+ if (!columnSettingsCookie) {
+ return;
+ }
+
+ var columnSettings = {};
+ $.each(columnSettingsCookie.split('|'), function (inx, fieldSetting) {
+ var splitted = fieldSetting.split('=');
+ var fieldName = splitted[0];
+ var settings = splitted[1].split(';');
+ columnSettings[fieldName] = {
+ columnVisibility: settings[0],
+ columnWidth: settings[1]
+ };
+ });
+
+ var headerCells = this._$table.find('>thead >tr >th.jtable-column-header');
+ headerCells.each(function () {
+ var $cell = $(this);
+ var fieldName = $cell.data('fieldName');
+ var field = self.options.fields[fieldName];
+ if (columnSettings[fieldName]) {
+ if (field.visibility != 'fixed') {
+ self._changeColumnVisibilityInternal(fieldName, columnSettings[fieldName].columnVisibility);
+ }
+
+ $cell.data('width-in-percent', columnSettings[fieldName].columnWidth).css('width', columnSettings[fieldName].columnWidth + '%');
+ }
+ });
+ }
+
+ });
+
+})(jQuery);
diff --git a/dev/jquery.jtable.header.txt b/dev/jquery.jtable.header.txt
index 68f61eb..48a6458 100644
--- a/dev/jquery.jtable.header.txt
+++ b/dev/jquery.jtable.header.txt
@@ -1,6 +1,6 @@
/*
-jTable 2.2.0
+jTable 2.2.1
http://www.jtable.org
---------------------------------------------------------------------------
diff --git a/dev/jquery.jtable.paging.js b/dev/jquery.jtable.paging.js
index 23af6a8..c8cdada 100644
--- a/dev/jquery.jtable.paging.js
+++ b/dev/jquery.jtable.paging.js
@@ -58,6 +58,7 @@
_create: function () {
base._create.apply(this, arguments);
if (this.options.paging) {
+ this._loadPagingSettings();
this._createBottomPanel();
this._createPageListArea();
this._createGotoPageInput();
@@ -65,6 +66,19 @@
}
},
+ /* Loads user preferences for paging.
+ *************************************************************************/
+ _loadPagingSettings: function () {
+ if (!this.options.saveUserPreferences) {
+ return;
+ }
+
+ var pageSize = this._getCookie('page-size');
+ if (pageSize) {
+ this.options.pageSize = this._normalizeNumber(pageSize, 1, 1000000, this.options.pageSize);
+ }
+ },
+
/* Creates bottom panel and adds to the page.
*************************************************************************/
_createBottomPanel: function () {
@@ -205,7 +219,20 @@
var currentPageCount = this._calculatePageCount();
if (oldPageCount != currentPageCount) {
this._$gotoPageInput.empty();
- for (var i = 1; i <= currentPageCount; i++) {
+
+ //Skip some pages is there are too many pages
+ var pageStep = 1;
+ if (currentPageCount > 10000) {
+ pageStep = 100;
+ } else if (currentPageCount > 5000) {
+ pageStep = 10;
+ } else if (currentPageCount > 2000) {
+ pageStep = 5;
+ } else if (currentPageCount > 1000) {
+ pageStep = 2;
+ }
+
+ for (var i = pageStep; i <= currentPageCount; i += pageStep) {
this._$gotoPageInput.append('<option value="' + i + '">' + i + '</option>');
}
@@ -253,6 +280,9 @@
if (this._currentPageNo > pageCount) {
this._currentPageNo = pageCount;
}
+ if (this._currentPageNo <= 0) {
+ this._currentPageNo = 1;
+ }
//if user sets one of the options on the combobox, then select it.
var $pageSizeChangeCombobox = this._$bottomPanel.find('.jtable-page-size-change select');
@@ -265,9 +295,20 @@
}
}
+ this._savePagingSettings();
this._reloadTable();
},
+ /* Saves user preferences for paging
+ *************************************************************************/
+ _savePagingSettings: function () {
+ if (!this.options.saveUserPreferences) {
+ return;
+ }
+
+ this._setCookie('page-size', this.options.pageSize);
+ },
+
/* Overrides _createRecordLoadUrl method to add paging info to URL.
*************************************************************************/
_createRecordLoadUrl: function () {
@@ -317,10 +358,13 @@
/* Overrides _onRecordsLoaded method to to do paging specific tasks.
*************************************************************************/
_onRecordsLoaded: function (data) {
- this._totalRecordCount = data.TotalRecordCount;
- this._createPagingList();
- this._createPagingInfo();
- this._refreshGotoPageInput();
+ if (this.options.paging) {
+ this._totalRecordCount = data.TotalRecordCount;
+ this._createPagingList();
+ this._createPagingInfo();
+ this._refreshGotoPageInput();
+ }
+
base._onRecordsLoaded.apply(this, arguments);
},
@@ -344,7 +388,7 @@
/* Creates and shows the page list.
*************************************************************************/
_createPagingList: function () {
- if (!this.options.paging || this.options.pageSize <= 0) {
+ if (this.options.pageSize <= 0) {
return;
}
@@ -371,13 +415,13 @@
.html('&lt&lt')
.data('pageNumber', 1)
.appendTo(this._$pagingListArea);
-
+
var $previous = $('<span></span>')
.addClass('jtable-page-number-previous')
.html('&lt')
.data('pageNumber', this._currentPageNo - 1)
.appendTo(this._$pagingListArea);
-
+
if (this._currentPageNo <= 1) {
$first.addClass('jtable-page-number-disabled');
$previous.addClass('jtable-page-number-disabled');
@@ -430,8 +474,8 @@
.html(pageNumber)
.data('pageNumber', pageNumber)
.appendTo(this._$pagingListArea);
-
- if(this._currentPageNo == pageNumber) {
+
+ if (this._currentPageNo == pageNumber) {
$pageNumber.addClass('jtable-page-number-active');
$pageNumber.addClass('jtable-page-number-disabled');
}
@@ -505,7 +549,7 @@
});
},
- /* Changes current page tp given value.
+ /* Changes current page to given value.
*************************************************************************/
_changePage: function (pageNo) {
pageNo = this._normalizeNumber(pageNo, 1, this._calculatePageCount(), 1);
diff --git a/dev/jquery.jtable.selecting.js b/dev/jquery.jtable.selecting.js
index 63c4457..a387e79 100644
--- a/dev/jquery.jtable.selecting.js
+++ b/dev/jquery.jtable.selecting.js
@@ -1,377 +1,379 @@
-/************************************************************************
-* SELECTING extension for jTable *
-*************************************************************************/
-(function ($) {
-
- //Reference to base object members
- var base = {
- _create: $.hik.jtable.prototype._create,
- _addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
- _addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord,
- _onLoadingRecords: $.hik.jtable.prototype._onLoadingRecords,
- _onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded,
- _onRowsRemoved: $.hik.jtable.prototype._onRowsRemoved
- };
-
- //extension members
- $.extend(true, $.hik.jtable.prototype, {
-
- /************************************************************************
- * DEFAULT OPTIONS / EVENTS *
- *************************************************************************/
- options: {
-
- //Options
- selecting: false,
- multiselect: false,
- selectingCheckboxes: false,
- selectOnRowClick: true,
-
- //Events
- selectionChanged: function (event, data) { }
- },
-
- /************************************************************************
- * PRIVATE FIELDS *
- *************************************************************************/
-
- _selectedRecordIdsBeforeLoad: null, //This array is used to store selected row Id's to restore them after a page refresh (string array).
- _$selectAllCheckbox: null, //Reference to the 'select/deselect all' checkbox (jQuery object)
- _shiftKeyDown: false, //True, if shift key is currently down.
-
- /************************************************************************
- * CONSTRUCTOR *
- *************************************************************************/
-
- /* Overrides base method to do selecting-specific constructions.
- *************************************************************************/
- _create: function () {
- if (this.options.selecting && this.options.selectingCheckboxes) {
- ++this._firstDataColumnOffset;
- }
-
- this._bindKeyboardEvents();
-
- //Call base method
- base._create.apply(this, arguments);
- },
-
- /* Registers to keyboard events those are needed for selection
- *************************************************************************/
- _bindKeyboardEvents: function () {
- var self = this;
- //Register to events to set _shiftKeyDown value
- $(document)
- .keydown(function(event) {
- switch (event.which) {
- case 16:
- self._shiftKeyDown = true;
- break;
- }
- })
- .keyup(function(event) {
- switch (event.which) {
- case 16:
- self._shiftKeyDown = false;
- break;
- }
- });
- },
-
- /************************************************************************
- * PUBLIC METHODS *
- *************************************************************************/
-
- /* Gets jQuery selection for currently selected rows.
- *************************************************************************/
- selectedRows: function () {
- return this._getSelectedRows();
- },
-
- /* Makes row/rows 'selected'.
- *************************************************************************/
- selectRows: function ($rows) {
- this._selectRows($rows);
- this._onSelectionChanged(); //TODO: trigger only if selected rows changes?
- },
-
- /************************************************************************
- * OVERRIDED METHODS *
- *************************************************************************/
-
- /* Overrides base method to add a 'select column' to header row.
- *************************************************************************/
- _addColumnsToHeaderRow: function ($tr) {
- if (this.options.selecting && this.options.selectingCheckboxes) {
- if (this.options.multiselect) {
- $tr.append(this._createSelectAllHeader());
- } else {
- $tr.append(this._createEmptyCommandHeader());
- }
- }
-
- base._addColumnsToHeaderRow.apply(this, arguments);
- },
-
- /* Overrides base method to add a 'delete command cell' to a row.
- *************************************************************************/
- _addCellsToRowUsingRecord: function ($row) {
- if (this.options.selecting) {
- this._makeRowSelectable($row);
- }
-
- base._addCellsToRowUsingRecord.apply(this, arguments);
- },
-
- /* Overrides base event to store selection list
- *************************************************************************/
- _onLoadingRecords: function () {
- this._storeSelectionList();
- base._onLoadingRecords.apply(this, arguments);
- },
-
- /* Overrides base event to restore selection list
- *************************************************************************/
- _onRecordsLoaded: function () {
- this._restoreSelectionList();
- base._onRecordsLoaded.apply(this, arguments);
- },
-
- /* Overrides base event to check is any selected row is being removed.
- *************************************************************************/
- _onRowsRemoved: function ($rows, reason) {
- if ((reason != 'reloading') && this.options.selecting && ($rows.filter('.jtable-row-selected').length > 0)) {
- this._onSelectionChanged();
- }
-
- base._onRowsRemoved.apply(this, arguments);
- },
-
- /************************************************************************
- * PRIVATE METHODS *
- *************************************************************************/
-
- /* Creates a header column to select/deselect all rows.
- *************************************************************************/
- _createSelectAllHeader: function () {
- var self = this;
-
- var $columnHeader = $('<th class=""></th>')
- .addClass('jtable-command-column-header jtable-column-header-selecting');
-
- var $headerContainer = $('<div />')
- .addClass('jtable-column-header-container')
- .appendTo($columnHeader);
-
- self._$selectAllCheckbox = $('<input type="checkbox" />')
- .appendTo($headerContainer)
- .click(function() {
- if (self._$tableRows.length <= 0) {
- self._$selectAllCheckbox.attr('checked', false);
- return;
- }
-
- var allRows = self._$tableBody.find('tr.jtable-data-row');
- if (self._$selectAllCheckbox.is(':checked')) {
- self._selectRows(allRows);
- } else {
- self._deselectRows(allRows);
- }
-
- self._onSelectionChanged();
- });
-
- return $columnHeader;
- },
-
- /* Stores Id's of currently selected records to _selectedRecordIdsBeforeLoad.
- *************************************************************************/
- _storeSelectionList: function () {
- var self = this;
-
- if (!self.options.selecting) {
- return;
- }
-
- self._selectedRecordIdsBeforeLoad = [];
- self._getSelectedRows().each(function () {
- self._selectedRecordIdsBeforeLoad.push(self._getKeyValueOfRecord($(this).data('record')));
- });
- },
-
- /* Selects rows whose Id is in _selectedRecordIdsBeforeLoad;
- *************************************************************************/
- _restoreSelectionList: function () {
- var self = this;
-
- if (!self.options.selecting) {
- return;
- }
-
- var selectedRowCount = 0;
- for (var i = 0; i < self._$tableRows.length; ++i) {
- var recordId = self._getKeyValueOfRecord(self._$tableRows[i].data('record'));
- if ($.inArray(recordId, self._selectedRecordIdsBeforeLoad) > -1) {
- self._selectRows(self._$tableRows[i]);
- ++selectedRowCount;
- }
- }
-
- if (self._selectedRecordIdsBeforeLoad.length > 0 && self._selectedRecordIdsBeforeLoad.length != selectedRowCount) {
- self._onSelectionChanged();
- }
-
- self._selectedRecordIdsBeforeLoad = [];
- self._refreshSelectAllCheckboxState();
- },
-
- /* Gets all selected rows.
- *************************************************************************/
- _getSelectedRows: function () {
- return this._$tableBody
- .find('.jtable-row-selected');
- },
-
- /* Adds selectable feature to a row.
- *************************************************************************/
- _makeRowSelectable: function ($row) {
- var self = this;
-
- //Select/deselect on row click
- if (self.options.selectOnRowClick) {
- $row.click(function () {
- self._invertRowSelection($row);
- });
- }
-
- //'select/deselect' checkbox column
- if (self.options.selectingCheckboxes) {
- var $cell = $('<td></td>')
- .addClass('jtable-selecting-column');
- var $selectCheckbox = $('<input type="checkbox" />')
- .appendTo($cell);
- if (!self.options.selectOnRowClick) {
- $selectCheckbox.click(function () {
- self._invertRowSelection($row);
- });
- }
-
- $row.append($cell);
- }
- },
-
- /* Inverts selection state of a single row.
- *************************************************************************/
- _invertRowSelection: function ($row) {
- if ($row.hasClass('jtable-row-selected')) {
- this._deselectRows($row);
- } else {
- //Shift key?
- if (this._shiftKeyDown) {
- var rowIndex = this._findRowIndex($row);
- //try to select row and above rows until first selected row
- var beforeIndex = this._findFirstSelectedRowIndexBeforeIndex(rowIndex) + 1;
- if (beforeIndex > 0 && beforeIndex < rowIndex) {
- this._selectRows(this._$tableBody.find('tr').slice(beforeIndex, rowIndex + 1));
- } else {
- //try to select row and below rows until first selected row
- var afterIndex = this._findFirstSelectedRowIndexAfterIndex(rowIndex) - 1;
- if (afterIndex > rowIndex) {
- this._selectRows(this._$tableBody.find('tr').slice(rowIndex, afterIndex + 1));
- } else {
- //just select this row
- this._selectRows($row);
- }
- }
- } else {
- this._selectRows($row);
- }
- }
-
- this._onSelectionChanged();
- },
-
- /* Search for a selected row (that is before given row index) to up and returns it's index
- *************************************************************************/
- _findFirstSelectedRowIndexBeforeIndex: function (rowIndex) {
- for (var i = rowIndex - 1; i >= 0; --i) {
- if (this._$tableRows[i].hasClass('jtable-row-selected')) {
- return i;
- }
- }
-
- return -1;
- },
-
- /* Search for a selected row (that is after given row index) to down and returns it's index
- *************************************************************************/
- _findFirstSelectedRowIndexAfterIndex: function (rowIndex) {
- for (var i = rowIndex + 1; i < this._$tableRows.length; ++i) {
- if (this._$tableRows[i].hasClass('jtable-row-selected')) {
- return i;
- }
- }
-
- return -1;
- },
-
- /* Makes row/rows 'selected'.
- *************************************************************************/
- _selectRows: function ($rows) {
-
- if (!this.options.multiselect) {
- this._deselectRows(this._getSelectedRows());
- }
-
- $rows.addClass('jtable-row-selected');
- if (this.options.selectingCheckboxes) {
- $rows.find('td.jtable-selecting-column input').attr('checked', true);
- }
-
- this._refreshSelectAllCheckboxState();
- },
-
- /* Makes row/rows 'non selected'.
- *************************************************************************/
- _deselectRows: function ($rows) {
- $rows.removeClass('jtable-row-selected');
- if (this.options.selectingCheckboxes) {
- $rows.find('td.jtable-selecting-column input').removeAttr('checked');
- }
-
- this._refreshSelectAllCheckboxState();
- },
-
- /* Updates state of the 'select/deselect' all checkbox according to count of selected rows.
- *************************************************************************/
- _refreshSelectAllCheckboxState: function () {
- if (!this.options.selectingCheckboxes || !this.options.multiselect) {
- return;
- }
-
- var totalRowCount = this._$tableRows.length;
- var selectedRowCount = this._getSelectedRows().length;
-
- if (selectedRowCount == 0) {
- this._$selectAllCheckbox.prop('indeterminate', false);
- this._$selectAllCheckbox.attr('checked', false);
- } else if (selectedRowCount == totalRowCount) {
- this._$selectAllCheckbox.prop('indeterminate', false);
- this._$selectAllCheckbox.attr('checked', true);
- } else {
- this._$selectAllCheckbox.attr('checked', false);
- this._$selectAllCheckbox.prop('indeterminate', true);
- }
- },
-
- /************************************************************************
- * EVENT RAISING METHODS *
- *************************************************************************/
-
- _onSelectionChanged: function () {
- this._trigger("selectionChanged", null, {});
- }
-
- });
-
-})(jQuery);
+/************************************************************************
+* SELECTING extension for jTable *
+*************************************************************************/
+(function ($) {
+
+ //Reference to base object members
+ var base = {
+ _create: $.hik.jtable.prototype._create,
+ _addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
+ _addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord,
+ _onLoadingRecords: $.hik.jtable.prototype._onLoadingRecords,
+ _onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded,
+ _onRowsRemoved: $.hik.jtable.prototype._onRowsRemoved
+ };
+
+ //extension members
+ $.extend(true, $.hik.jtable.prototype, {
+
+ /************************************************************************
+ * DEFAULT OPTIONS / EVENTS *
+ *************************************************************************/
+ options: {
+
+ //Options
+ selecting: false,
+ multiselect: false,
+ selectingCheckboxes: false,
+ selectOnRowClick: true,
+
+ //Events
+ selectionChanged: function (event, data) { }
+ },
+
+ /************************************************************************
+ * PRIVATE FIELDS *
+ *************************************************************************/
+
+ _selectedRecordIdsBeforeLoad: null, //This array is used to store selected row Id's to restore them after a page refresh (string array).
+ _$selectAllCheckbox: null, //Reference to the 'select/deselect all' checkbox (jQuery object)
+ _shiftKeyDown: false, //True, if shift key is currently down.
+
+ /************************************************************************
+ * CONSTRUCTOR *
+ *************************************************************************/
+
+ /* Overrides base method to do selecting-specific constructions.
+ *************************************************************************/
+ _create: function () {
+ if (this.options.selecting && this.options.selectingCheckboxes) {
+ ++this._firstDataColumnOffset;
+ this._bindKeyboardEvents();
+ }
+
+ //Call base method
+ base._create.apply(this, arguments);
+ },
+
+ /* Registers to keyboard events those are needed for selection
+ *************************************************************************/
+ _bindKeyboardEvents: function () {
+ var self = this;
+ //Register to events to set _shiftKeyDown value
+ $(document)
+ .keydown(function (event) {
+ switch (event.which) {
+ case 16:
+ self._shiftKeyDown = true;
+ break;
+ }
+ })
+ .keyup(function (event) {
+ switch (event.which) {
+ case 16:
+ self._shiftKeyDown = false;
+ break;
+ }
+ });
+ },
+
+ /************************************************************************
+ * PUBLIC METHODS *
+ *************************************************************************/
+
+ /* Gets jQuery selection for currently selected rows.
+ *************************************************************************/
+ selectedRows: function () {
+ return this._getSelectedRows();
+ },
+
+ /* Makes row/rows 'selected'.
+ *************************************************************************/
+ selectRows: function ($rows) {
+ this._selectRows($rows);
+ this._onSelectionChanged(); //TODO: trigger only if selected rows changes?
+ },
+
+ /************************************************************************
+ * OVERRIDED METHODS *
+ *************************************************************************/
+
+ /* Overrides base method to add a 'select column' to header row.
+ *************************************************************************/
+ _addColumnsToHeaderRow: function ($tr) {
+ if (this.options.selecting && this.options.selectingCheckboxes) {
+ if (this.options.multiselect) {
+ $tr.append(this._createSelectAllHeader());
+ } else {
+ $tr.append(this._createEmptyCommandHeader());
+ }
+ }
+
+ base._addColumnsToHeaderRow.apply(this, arguments);
+ },
+
+ /* Overrides base method to add a 'delete command cell' to a row.
+ *************************************************************************/
+ _addCellsToRowUsingRecord: function ($row) {
+ if (this.options.selecting) {
+ this._makeRowSelectable($row);
+ }
+
+ base._addCellsToRowUsingRecord.apply(this, arguments);
+ },
+
+ /* Overrides base event to store selection list
+ *************************************************************************/
+ _onLoadingRecords: function () {
+ if (this.options.selecting) {
+ this._storeSelectionList();
+ }
+
+ base._onLoadingRecords.apply(this, arguments);
+ },
+
+ /* Overrides base event to restore selection list
+ *************************************************************************/
+ _onRecordsLoaded: function () {
+ if (this.options.selecting) {
+ this._restoreSelectionList();
+ }
+
+ base._onRecordsLoaded.apply(this, arguments);
+ },
+
+ /* Overrides base event to check is any selected row is being removed.
+ *************************************************************************/
+ _onRowsRemoved: function ($rows, reason) {
+ if (this.options.selecting && (reason != 'reloading') && ($rows.filter('.jtable-row-selected').length > 0)) {
+ this._onSelectionChanged();
+ }
+
+ base._onRowsRemoved.apply(this, arguments);
+ },
+
+ /************************************************************************
+ * PRIVATE METHODS *
+ *************************************************************************/
+
+ /* Creates a header column to select/deselect all rows.
+ *************************************************************************/
+ _createSelectAllHeader: function () {
+ var self = this;
+
+ var $columnHeader = $('<th class=""></th>')
+ .addClass('jtable-command-column-header jtable-column-header-selecting');
+
+ var $headerContainer = $('<div />')
+ .addClass('jtable-column-header-container')
+ .appendTo($columnHeader);
+
+ self._$selectAllCheckbox = $('<input type="checkbox" />')
+ .appendTo($headerContainer)
+ .click(function () {
+ if (self._$tableRows.length <= 0) {
+ self._$selectAllCheckbox.attr('checked', false);
+ return;
+ }
+
+ var allRows = self._$tableBody.find('>tr.jtable-data-row');
+ if (self._$selectAllCheckbox.is(':checked')) {
+ self._selectRows(allRows);
+ } else {
+ self._deselectRows(allRows);
+ }
+
+ self._onSelectionChanged();
+ });
+
+ return $columnHeader;
+ },
+
+ /* Stores Id's of currently selected records to _selectedRecordIdsBeforeLoad.
+ *************************************************************************/
+ _storeSelectionList: function () {
+ var self = this;
+
+ if (!self.options.selecting) {
+ return;
+ }
+
+ self._selectedRecordIdsBeforeLoad = [];
+ self._getSelectedRows().each(function () {
+ self._selectedRecordIdsBeforeLoad.push(self._getKeyValueOfRecord($(this).data('record')));
+ });
+ },
+
+ /* Selects rows whose Id is in _selectedRecordIdsBeforeLoad;
+ *************************************************************************/
+ _restoreSelectionList: function () {
+ var self = this;
+
+ if (!self.options.selecting) {
+ return;
+ }
+
+ var selectedRowCount = 0;
+ for (var i = 0; i < self._$tableRows.length; ++i) {
+ var recordId = self._getKeyValueOfRecord(self._$tableRows[i].data('record'));
+ if ($.inArray(recordId, self._selectedRecordIdsBeforeLoad) > -1) {
+ self._selectRows(self._$tableRows[i]);
+ ++selectedRowCount;
+ }
+ }
+
+ if (self._selectedRecordIdsBeforeLoad.length > 0 && self._selectedRecordIdsBeforeLoad.length != selectedRowCount) {
+ self._onSelectionChanged();
+ }
+
+ self._selectedRecordIdsBeforeLoad = [];
+ self._refreshSelectAllCheckboxState();
+ },
+
+ /* Gets all selected rows.
+ *************************************************************************/
+ _getSelectedRows: function () {
+ return this._$tableBody
+ .find('>tr.jtable-row-selected');
+ },
+
+ /* Adds selectable feature to a row.
+ *************************************************************************/
+ _makeRowSelectable: function ($row) {
+ var self = this;
+
+ //Select/deselect on row click
+ if (self.options.selectOnRowClick) {
+ $row.click(function () {
+ self._invertRowSelection($row);
+ });
+ }
+
+ //'select/deselect' checkbox column
+ if (self.options.selectingCheckboxes) {
+ var $cell = $('<td></td>').addClass('jtable-selecting-column');
+ var $selectCheckbox = $('<input type="checkbox" />').appendTo($cell);
+ if (!self.options.selectOnRowClick) {
+ $selectCheckbox.click(function () {
+ self._invertRowSelection($row);
+ });
+ }
+
+ $row.append($cell);
+ }
+ },
+
+ /* Inverts selection state of a single row.
+ *************************************************************************/
+ _invertRowSelection: function ($row) {
+ if ($row.hasClass('jtable-row-selected')) {
+ this._deselectRows($row);
+ } else {
+ //Shift key?
+ if (this._shiftKeyDown) {
+ var rowIndex = this._findRowIndex($row);
+ //try to select row and above rows until first selected row
+ var beforeIndex = this._findFirstSelectedRowIndexBeforeIndex(rowIndex) + 1;
+ if (beforeIndex > 0 && beforeIndex < rowIndex) {
+ this._selectRows(this._$tableBody.find('tr').slice(beforeIndex, rowIndex + 1));
+ } else {
+ //try to select row and below rows until first selected row
+ var afterIndex = this._findFirstSelectedRowIndexAfterIndex(rowIndex) - 1;
+ if (afterIndex > rowIndex) {
+ this._selectRows(this._$tableBody.find('tr').slice(rowIndex, afterIndex + 1));
+ } else {
+ //just select this row
+ this._selectRows($row);
+ }
+ }
+ } else {
+ this._selectRows($row);
+ }
+ }
+
+ this._onSelectionChanged();
+ },
+
+ /* Search for a selected row (that is before given row index) to up and returns it's index
+ *************************************************************************/
+ _findFirstSelectedRowIndexBeforeIndex: function (rowIndex) {
+ for (var i = rowIndex - 1; i >= 0; --i) {
+ if (this._$tableRows[i].hasClass('jtable-row-selected')) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /* Search for a selected row (that is after given row index) to down and returns it's index
+ *************************************************************************/
+ _findFirstSelectedRowIndexAfterIndex: function (rowIndex) {
+ for (var i = rowIndex + 1; i < this._$tableRows.length; ++i) {
+ if (this._$tableRows[i].hasClass('jtable-row-selected')) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /* Makes row/rows 'selected'.
+ *************************************************************************/
+ _selectRows: function ($rows) {
+ if (!this.options.multiselect) {
+ this._deselectRows(this._getSelectedRows());
+ }
+
+ $rows.addClass('jtable-row-selected');
+ if (this.options.selectingCheckboxes) {
+ $rows.find('>td.jtable-selecting-column >input').prop('checked', true);
+ }
+
+ this._refreshSelectAllCheckboxState();
+ },
+
+ /* Makes row/rows 'non selected'.
+ *************************************************************************/
+ _deselectRows: function ($rows) {
+ $rows.removeClass('jtable-row-selected');
+ if (this.options.selectingCheckboxes) {
+ $rows.find('>td.jtable-selecting-column >input').prop('checked', false);
+ }
+
+ this._refreshSelectAllCheckboxState();
+ },
+
+ /* Updates state of the 'select/deselect' all checkbox according to count of selected rows.
+ *************************************************************************/
+ _refreshSelectAllCheckboxState: function () {
+ if (!this.options.selectingCheckboxes || !this.options.multiselect) {
+ return;
+ }
+
+ var totalRowCount = this._$tableRows.length;
+ var selectedRowCount = this._getSelectedRows().length;
+
+ if (selectedRowCount == 0) {
+ this._$selectAllCheckbox.prop('indeterminate', false);
+ this._$selectAllCheckbox.attr('checked', false);
+ } else if (selectedRowCount == totalRowCount) {
+ this._$selectAllCheckbox.prop('indeterminate', false);
+ this._$selectAllCheckbox.attr('checked', true);
+ } else {
+ this._$selectAllCheckbox.attr('checked', false);
+ this._$selectAllCheckbox.prop('indeterminate', true);
+ }
+ },
+
+ /************************************************************************
+ * EVENT RAISING METHODS *
+ *************************************************************************/
+
+ _onSelectionChanged: function () {
+ this._trigger("selectionChanged", null, {});
+ }
+
+ });
+
+})(jQuery);