diff options
author | Halil İbrahim Kalkan <hikalkan@gmail.com> | 2013-02-13 16:04:34 +0200 |
---|---|---|
committer | Halil İbrahim Kalkan <hikalkan@gmail.com> | 2013-02-13 16:04:34 +0200 |
commit | 6a7148fa53b0fb428c853d01150f2843122fa6d0 (patch) | |
tree | d6e813a899343cf165c3a1da565930890d6b5fd2 /dev/jquery.jtable.dynamiccolumns.js | |
parent | 277c6e18d910accfe145f0b3cacb27aef437d1ac (diff) | |
download | jtable-6a7148fa53b0fb428c853d01150f2843122fa6d0.zip jtable-6a7148fa53b0fb428c853d01150f2843122fa6d0.tar.gz jtable-6a7148fa53b0fb428c853d01150f2843122fa6d0.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/jquery.jtable.dynamiccolumns.js')
-rw-r--r-- | dev/jquery.jtable.dynamiccolumns.js | 990 |
1 files changed, 461 insertions, 529 deletions
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); |