summaryrefslogtreecommitdiffstats
path: root/lib/jquery.jtable.js
diff options
context:
space:
mode:
authorHalil İbrahim Kalkan <hikalkan@gmail.com>2013-01-13 20:47:06 +0200
committerHalil İbrahim Kalkan <hikalkan@gmail.com>2013-01-13 20:47:06 +0200
commit714e396500d8ca31ccf5e0972c8a77b365365f4a (patch)
tree43cae707262293df88553dd6433863a42be04d2a /lib/jquery.jtable.js
parenta08e406f31de23ff7fd8cb766fdd9f7f62fbd82d (diff)
downloadjtable-714e396500d8ca31ccf5e0972c8a77b365365f4a.zip
jtable-714e396500d8ca31ccf5e0972c8a77b365365f4a.tar.gz
jtable-714e396500d8ca31ccf5e0972c8a77b365365f4a.tar.bz2
jTable version 2.0.0
All codebase revised and refactored. All CSS re-written using less css. [#3] Added metro style theme with 10 color options. [#2] Added a basic theme that can be start point who want to create themes to jTable. Added methods: getRowByKey, selectRows. [#8] Added field option: ajaxSettings. Added feature: editing primary key's value. [#34] Added feature: Allow updating a record with server response after updateAction [#66] Added ready-to-use localization scripts. [#67] Fixed some issues. [#25, #29, #42, #46] Set default values for key field as "edit: false" and "create: false" Fixed some other minor bugs. Removed standard theme. Tested with latest jQuery libraries (jQuery v1.8.3 and jQuery UI v1.9.2).
Diffstat (limited to 'lib/jquery.jtable.js')
-rw-r--r--lib/jquery.jtable.js893
1 files changed, 615 insertions, 278 deletions
diff --git a/lib/jquery.jtable.js b/lib/jquery.jtable.js
index 32abaa3..58ae878 100644
--- a/lib/jquery.jtable.js
+++ b/lib/jquery.jtable.js
@@ -1,11 +1,11 @@
/*
-jTable 1.7.2
+jTable 2.0.0
http://www.jtable.org
---------------------------------------------------------------------------
-Copyright (C) 2011-2012 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
+Copyright (C) 2011-2013 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -47,6 +47,11 @@ THE SOFTWARE.
dialogShowEffect: 'fade',
dialogHideEffect: 'fade',
showCloseButton: false,
+ loadingAnimationDelay: 500,
+ ajaxSettings: {
+ type: 'POST',
+ dataType: 'json'
+ },
//Events
closeRequested: function (event, data) { },
@@ -172,25 +177,38 @@ THE SOFTWARE.
/* Creates the main container div.
*************************************************************************/
_createMainContainer: function () {
- this._$mainContainer = $('<div class="jtable-main-container"></div>').appendTo(this.element);
+ this._$mainContainer = $('<div />')
+ .addClass('jtable-main-container')
+ .appendTo(this.element);
},
/* Creates title of the table if a title supplied in options.
*************************************************************************/
_createTableTitle: function () {
var self = this;
+
if (!self.options.title) {
return;
}
- //TODO: May use caption element instead of a seperated div element?
- var $titleDiv = $('<div class="jtable-title"></div>')
+ var $titleDiv = $('<div />')
+ .addClass('jtable-title')
.appendTo(self._$mainContainer);
- $('<div class="jtable-title-text"></div>')
+
+ $('<div />')
+ .addClass('jtable-title-text')
.appendTo($titleDiv)
.append(self.options.title);
+
if (self.options.showCloseButton) {
- $('<button class="jtable-command-button jtable-close-button" title="' + self.options.messages.close + '"><span>' + self.options.messages.close + '</span></button>')
+
+ var $textSpan = $('<span />')
+ .html(self.options.messages.close);
+
+ $('<button></button>')
+ .addClass('jtable-command-button jtable-close-button')
+ .attr('title', self.options.messages.close)
+ .append($textSpan)
.appendTo($titleDiv)
.click(function (e) {
e.preventDefault();
@@ -200,10 +218,13 @@ THE SOFTWARE.
}
},
- /* Creates table.
+ /* Creates the table.
*************************************************************************/
_createTable: function () {
- this._$table = $('<table class="jtable"></table>').appendTo(this._$mainContainer);
+ this._$table = $('<table></table>')
+ .addClass('jtable')
+ .appendTo(this._$mainContainer);
+
this._createTableHead();
this._createTableBody();
},
@@ -211,14 +232,18 @@ THE SOFTWARE.
/* Creates header (all column headers) of the table.
*************************************************************************/
_createTableHead: function () {
- var $thead = $('<thead></thead>').appendTo(this._$table);
+ var $thead = $('<thead></thead>')
+ .appendTo(this._$table);
+
this._addRowToTableHead($thead);
},
/* Adds tr element to given thead element
*************************************************************************/
_addRowToTableHead: function ($thead) {
- var $tr = $('<tr></tr>').appendTo($thead);
+ var $tr = $('<tr></tr>')
+ .appendTo($thead);
+
this._addColumnsToHeaderRow($tr);
},
@@ -228,7 +253,7 @@ THE SOFTWARE.
for (var i = 0; i < this._columnList.length; i++) {
var fieldName = this._columnList[i];
var $headerCell = this._createHeaderCellForField(fieldName, this.options.fields[fieldName]);
- $headerCell.data('fieldName', fieldName).appendTo($tr);
+ $headerCell.appendTo($tr);
}
},
@@ -236,17 +261,31 @@ THE SOFTWARE.
* Returns th jQuery object.
*************************************************************************/
_createHeaderCellForField: function (fieldName, field) {
- field.width = field.width || '10%';
- return $('<th class="jtable-column-header" style="width:' + field.width + '">' +
- '<div class="jtable-column-header-container"><span class="jtable-column-header-text">' + field.title +
- '</span></div></th>')
- .data('fieldName', fieldName);
+ field.width = field.width || '10%'; //default column width: 10%.
+
+ var $headerTextSpan = $('<span />')
+ .addClass('jtable-column-header-text')
+ .html(field.title);
+
+ var $headerContainerDiv = $('<div />')
+ .addClass('jtable-column-header-container')
+ .append($headerTextSpan);
+
+ var $th = $('<th></th>')
+ .addClass('jtable-column-header')
+ .css('width', field.width)
+ .data('fieldName', fieldName)
+ .append($headerContainerDiv);
+
+ return $th;
},
/* Creates an empty header cell that can be used as command column headers.
*************************************************************************/
_createEmptyCommandHeader: function () {
- return $('<th class="jtable-command-column-header" style="width:1%"></th>');
+ return $('<th></th>')
+ .addClass('jtable-command-column-header')
+ .css('width', '1%');
},
/* Creates tbody tag and adds to the table.
@@ -258,16 +297,19 @@ THE SOFTWARE.
/* Creates bottom panel and adds to the page.
*************************************************************************/
_createBottomPanel: function () {
- this._$bottomPanel = $('<div class="jtable-bottom-panel"></div>').appendTo(this._$mainContainer);
- this._$bottomPanel.append('<div class="jtable-left-area"></div>');
- this._$bottomPanel.append('<div class="jtable-right-area"></div>');
+ this._$bottomPanel = $('<div />')
+ .addClass('jtable-bottom-panel')
+ .appendTo(this._$mainContainer);
+
+ $('<div />').addClass('jtable-left-area').appendTo(this._$bottomPanel);
+ $('<div />').addClass('jtable-right-area').appendTo(this._$bottomPanel);
},
/* Creates a div to block UI while jTable is busy.
*************************************************************************/
_createBusyPanel: function () {
- this._$busyMessageDiv = $('<div class="jtable-busy-message"></div>').prependTo(this._$mainContainer);
- this._$busyDiv = $('<div class="jtable-busy-panel-background"></div>').prependTo(this._$mainContainer);
+ this._$busyMessageDiv = $('<div />').addClass('jtable-busy-message').prependTo(this._$mainContainer);
+ this._$busyDiv = $('<div />').addClass('jtable-busy-panel-background').prependTo(this._$mainContainer);
this._hideBusy();
},
@@ -309,6 +351,18 @@ THE SOFTWARE.
this._reloadTable(completeCallback);
},
+ /* Gets a jQuery row object according to given record key
+ *************************************************************************/
+ getRowByKey: function (key) {
+ for (var i = 0; i < this._$tableRows.length; i++) {
+ if (key == this._getKeyValueOfRecord(this._$tableRows[i].data('record'))) {
+ return this._$tableRows[i];
+ }
+ }
+
+ return null;
+ },
+
/* Completely removes the table from it's container.
*************************************************************************/
destroy: function () {
@@ -322,24 +376,23 @@ THE SOFTWARE.
/* LOADING RECORDS *****************************************************/
- /* Performs an AJAX call to specified URL.
+ /* Performs an AJAX call to reload data of the table.
*************************************************************************/
_reloadTable: function (completeCallback) {
var self = this;
//Disable table since it's busy
- self._showBusy(self.options.messages.loadingMessage);
+ self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay);
//Generate URL (with query string parameters) to load records
var loadUrl = self._createRecordLoadUrl();
//Load data from server
self._onLoadingRecords();
- self._performAjaxCall(
- loadUrl,
- self._lastPostData,
- true, //asynchronous
- function (data) { //success
+ self._ajax({
+ url: loadUrl,
+ data: self._lastPostData,
+ success: function (data) {
self._hideBusy();
//Show the error message if server returns error
@@ -359,10 +412,11 @@ THE SOFTWARE.
completeCallback();
}
},
- function () {
+ error: function () {
self._hideBusy();
self._showError(self.options.messages.serverCommunicationError);
- });
+ }
+ });
},
/* Creates URL to load records.
@@ -376,23 +430,30 @@ THE SOFTWARE.
/* Creates a row from given record
*************************************************************************/
_createRowFromRecord: function (record) {
- var $newTableRow = $('<tr></tr>').data('record', record);
- this._addCellsToRowUsingRecord($newTableRow);
- return $newTableRow;
+ var $tr = $('<tr></tr>')
+ .addClass('jtable-data-row')
+ .attr('data-record-key', this._getKeyValueOfRecord(record))
+ .data('record', record);
+
+ this._addCellsToRowUsingRecord($tr);
+ return $tr;
},
/* Adds all cells to given row.
*************************************************************************/
_addCellsToRowUsingRecord: function ($row) {
+ var record = $row.data('record');
for (var i = 0; i < this._columnList.length; i++) {
- this._createCellForRecordField($row.data('record'), this._columnList[i]).appendTo($row);
+ this._createCellForRecordField(record, this._columnList[i])
+ .appendTo($row);
}
},
/* Create a cell for given field.
*************************************************************************/
_createCellForRecordField: function (record, fieldName) {
- return $('<td class="' + this.options.fields[fieldName].listClass + '"></td>')
+ return $('<td></td>')
+ .addClass(this.options.fields[fieldName].listClass)
.append((this._getDisplayTextForRecordField(record, fieldName) || ''));
},
@@ -402,60 +463,76 @@ THE SOFTWARE.
var self = this;
$.each(records, function (index, record) {
- self._addRowToTable(self._createRowFromRecord(record));
+ self._addRow(self._createRowFromRecord(record));
});
self._refreshRowStyles();
},
- /* Adds a single row to a specific index of the table.
- * If no index specified, adds to end of the table.
+ /* Adds a single row to the table.
+ * NOTE: THIS METHOD IS DEPRECATED AND WILL BE REMOVED FROM FEATURE RELEASES.
+ * USE _addRow METHOD.
*************************************************************************/
_addRowToTable: function ($tableRow, index, isNewRow, animationsEnabled) {
- var self = this;
+ var options = {
+ index: this._normalizeNumber(index, 0, this._$tableRows.length, this._$tableRows.length)
+ };
- //set default value
- if (isNewRow != true) {
- isNewRow = false;
+ if (isNewRow == true) {
+ options.isNewRow = true;
}
- if (animationsEnabled != false) {
- animationsEnabled = true;
+ if (animationsEnabled == false) {
+ options.animationsEnabled = false;
}
+ this._addRow($tableRow, options);
+ },
+
+ /* Adds a single row to the table.
+ *************************************************************************/
+ _addRow: function ($row, options) {
+ //Set defaults
+ options = $.extend({
+ index: this._$tableRows.length,
+ isNewRow: false,
+ animationsEnabled: true
+ }, options);
+
//Remove 'no data' row if this is first row
if (this._$tableRows.length <= 0) {
this._removeNoDataRow();
}
//Add new row to the table according to it's index
- index = this._normalizeNumber(index, 0, this._$tableRows.length, this._$tableRows.length);
- if (index == this._$tableRows.length) {
+ options.index = this._normalizeNumber(options.index, 0, this._$tableRows.length, this._$tableRows.length);
+ if (options.index == this._$tableRows.length) {
//add as last row
- this._$tableBody.append($tableRow);
- this._$tableRows.push($tableRow);
- } else if (index == 0) {
+ this._$tableBody.append($row);
+ this._$tableRows.push($row);
+ } else if (options.index == 0) {
//add as first row
- this._$tableBody.prepend($tableRow);
- this._$tableRows.unshift($tableRow);
+ this._$tableBody.prepend($row);
+ this._$tableRows.unshift($row);
} else {
//insert to specified index
- this._$tableRows[index - 1].after($tableRow);
- this._$tableRows.splice(index, 0, $tableRow);
+ this._$tableRows[options.index - 1].after($row);
+ this._$tableRows.splice(options.index, 0, $row);
}
- this._onRowInserted($tableRow, isNewRow);
+ this._onRowInserted($row, options.isNewRow);
//Show animation if needed
- if (isNewRow == true) {
- self._refreshRowStyles();
- if (self.options.animationsEnabled && animationsEnabled) {
- self._showNewRowAnimation($tableRow);
+ if (options.isNewRow) {
+ this._refreshRowStyles();
+ if (this.options.animationsEnabled && options.animationsEnabled) {
+ this._showNewRowAnimation($row);
}
}
},
/* Shows created animation for a table row
+ * TODO: Make this animation cofigurable and changable
*************************************************************************/
_showNewRowAnimation: function ($tableRow) {
$tableRow.addClass('jtable-row-created', 'slow', '', function () {
@@ -508,7 +585,7 @@ THE SOFTWARE.
}
//Select all rows (to pass it on raising _onRowsRemoved event)
- var $rows = this._$tableBody.find('tr');
+ var $rows = this._$tableBody.find('tr.jtable-data-row');
//Remove all rows from DOM and the _$tableRows array
this._$tableBody.empty();
@@ -523,10 +600,15 @@ THE SOFTWARE.
/* Adds "no data available" row to the table.
*************************************************************************/
_addNoDataRow: function () {
- var totalColumnCount = this._$table.find('thead th').length;
- $('<tr class="jtable-no-data-row"></tr>')
- .append('<td colspan="' + totalColumnCount + '">' + this.options.messages.noDataAvailable + '</td>')
+ var $tr = $('<tr></tr>')
+ .addClass('jtable-no-data-row')
.appendTo(this._$tableBody);
+
+ var totalColumnCount = this._$table.find('thead th').length;
+ $('<td></td>')
+ .attr('colspan', totalColumnCount)
+ .html(this.options.messages.noDataAvailable)
+ .appendTo($tr);
},
/* Removes "no data available" row from the table.
@@ -555,6 +637,7 @@ THE SOFTWARE.
var field = this.options.fields[fieldName];
var fieldValue = record[fieldName];
+ //if this is a custom field, call display function
if (field.display) {
return field.display({ record: record });
}
@@ -564,8 +647,7 @@ THE SOFTWARE.
} else if (field.type == 'checkbox') {
return this._getCheckBoxTextForFieldByValue(fieldName, fieldValue);
} else if (field.options) {
- var x = this._getOptionsWithCaching(fieldName)[fieldValue];
- return x;
+ return this._getOptionsWithCaching(fieldName)[fieldValue];
} else {
return fieldValue;
}
@@ -591,14 +673,27 @@ THE SOFTWARE.
*************************************************************************/
_parseDate: function (dateString) {
if (dateString.indexOf('Date') >= 0) { //Format: /Date(1320259705710)/
- return new Date(parseInt(dateString.substr(6)));
+ return new Date(
+ parseInt(dateString.substr(6))
+ );
} 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)));
+ return new Date(
+ parseInt(dateString.substr(0, 4)),
+ parseInt(dateString.substr(5, 2)) - 1,
+ parseInt(dateString.substr(8, 2))
+ );
} 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)));
+ 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))
+ );
} else {
- this._logWarn('Given date is no properly formatted: ' + dateString);
- return new Date(); //Default value!
+ this._logWarn('Given date is not properly formatted: ' + dateString);
+ return 'format error!';
}
},
@@ -613,21 +708,36 @@ THE SOFTWARE.
/* BUSY PANEL ***********************************************************/
/* Shows busy indicator and blocks table UI.
+ * TODO: Make this cofigurable and changable
*************************************************************************/
- _showBusy: function (message) {
- if (!this._$busyMessageDiv.is(':visible')) {
- this._$busyDiv.width(this._$mainContainer.width());
- this._$busyDiv.height(this._$mainContainer.height());
- this._$busyDiv.show();
- this._$busyMessageDiv.show();
- }
+ _setBusyTimer: null, //TODO: Think for a better way!
+ _showBusy: function (message, delay) {
+ var self = this;
+
+ var show = function () {
+ if (!self._$busyMessageDiv.is(':visible')) {
+ self._$busyDiv.width(self._$mainContainer.width());
+ self._$busyDiv.height(self._$mainContainer.height());
+ self._$busyDiv.show();
+ self._$busyMessageDiv.show();
+ }
+
+ self._$busyMessageDiv.html(message);
+ };
- this._$busyMessageDiv.html(message);
+ //TODO: Put an overlay always (without color) to not allow to click the table
+ //TODO: and change it visible when timeout occurs.
+ if (delay) {
+ self._setBusyTimer = setTimeout(show, delay);
+ } else {
+ show();
+ }
},
/* Hides busy indicator and unblocks table UI.
*************************************************************************/
_hideBusy: function () {
+ clearTimeout(this._setBusyTimer);
this._$busyDiv.hide();
this._$busyMessageDiv.html('').hide();
},
@@ -641,33 +751,53 @@ THE SOFTWARE.
/* COMMON METHODS *******************************************************/
/* Performs an AJAX call to specified URL.
+ * THIS METHOD IS DEPRECATED AND WILL BE REMOVED FROM FEATURE RELEASES.
+ * USE _ajax METHOD.
*************************************************************************/
_performAjaxCall: function (url, postData, async, success, error) {
- $.ajax({
+ this._ajax({
url: url,
- type: 'POST',
- dataType: 'json',
data: postData,
async: async,
- success: function (data) {
- success(data);
- },
- error: function () {
- error();
- }
+ success: success,
+ error: error
});
},
- /* Gets a jQuery row object according to given record key
+ /* This method is used to perform AJAX calls in jTable instead of direct
+ * usage of jQuery.ajax method.
*************************************************************************/
- getRowByKey: function (key) {
- for (var i = 0; i < this._$tableRows.length; i++) {
- if (key == this._$tableRows[i].data('record')[this._keyField]) {
- return this._$tableRows[i];
+ _ajax: function (options) {
+ var opts = $.extend({}, this.options.ajaxSettings, options);
+
+ //Override success
+ opts.success = function (data) {
+ if (options.success) {
+ options.success(data);
}
- }
+ };
- return null;
+ //Override error
+ opts.error = function () {
+ if (options.error) {
+ options.error();
+ }
+ };
+
+ //Override complete
+ opts.complete = function () {
+ if (options.complete) {
+ options.complete();
+ }
+ };
+
+ $.ajax(opts);
+ },
+
+ /* Gets value of key field of a record.
+ *************************************************************************/
+ _getKeyValueOfRecord: function (record) {
+ return record[this._keyField];
},
/************************************************************************
@@ -696,7 +826,8 @@ THE SOFTWARE.
});
-} (jQuery));
+}(jQuery));
+
/************************************************************************
* Some UTULITY methods used by jTable *
@@ -720,14 +851,12 @@ THE SOFTWARE.
/* Sets property value of an object recursively.
*************************************************************************/
_setPropertyOfObject: function (obj, propName, value) {
- var self = this;
-
if (propName.indexOf('.') < 0) {
obj[propName] = value;
} else {
var preDot = propName.substring(0, propName.indexOf('.'));
var postDot = propName.substring(propName.indexOf('.') + 1);
- self._setPropertyOfObject(obj[preDot], postDot, value);
+ this._setPropertyOfObject(obj[preDot], postDot, value);
}
},
@@ -834,6 +963,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* FORMS extension for jTable (base for edit/create forms) *
*************************************************************************/
@@ -850,14 +980,21 @@ THE SOFTWARE.
* by extensions.
*************************************************************************/
_submitFormUsingAjax: function (url, formData, success, error) {
- this._performAjaxCall(url, formData, true, success, error);
+ this._ajax({
+ url: url,
+ data: formData,
+ success: success,
+ error: error
+ });
},
/* Creates label for an input element.
*************************************************************************/
_createInputLabelForRecordField: function (fieldName) {
//TODO: May create label tag instead of a div.
- return $('<div class="jtable-input-label">' + this.options.fields[fieldName].title + '</div>');
+ return $('<div />')
+ .addClass('jtable-input-label')
+ .html(this.options.fields[fieldName].title);
},
/* Creates an input element according to field type.
@@ -867,8 +1004,8 @@ THE SOFTWARE.
//Get the field
var field = this.options.fields[fieldName];
- //If value if undefined, use defaultValue of the field
- if (value == undefined) {
+ //If value if not supplied, use defaultValue of the field
+ if (value == undefined || value == null) {
value = field.defaultValue;
}
@@ -877,6 +1014,7 @@ THE SOFTWARE.
var $input = $(field.input({ value: value, record: record }));
//Add id attribute if does not exists
+ //TODO: Check if id is needed?
if (!$input.attr('id')) {
$input.attr('id', 'Edit-' + fieldName);
}
@@ -903,7 +1041,7 @@ THE SOFTWARE.
return this._createTextInputForField(field, fieldName, value);
}
},
-
+
//Creates a hidden input element with given name and value.
_createInputForHidden: function (fieldName, value) {
if (value == undefined || value == null) {
@@ -919,25 +1057,36 @@ THE SOFTWARE.
var $input = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input>');
var displayFormat = field.displayFormat || this.options.defaultDateFormat;
$input.datepicker({ dateFormat: displayFormat });
- return $('<div class="jtable-input jtable-date-input"></div>').append($input);
+ return $('<div />')
+ .addClass('jtable-input jtable-date-input')
+ .append($input);
},
- /* Creates a standart textbox for a field.
+ /* Creates a textarea element for a field.
*************************************************************************/
_createTextAreaForField: function (field, fieldName, value) {
- return $('<div class="jtable-input jtable-textarea-input"><textarea class="' + field.inputClass + '" id="Edit-' + fieldName + '" name="' + fieldName + '">' + (value || '') + '</textarea></div>');
+ var $textArea = $('<textarea class="' + field.inputClass + '" id="Edit-' + fieldName + '" name="' + fieldName + '">' + (value || '') + '</textarea>');
+ return $('<div />')
+ .addClass('jtable-input jtable-textarea-input')
+ .append($textArea);
},
/* Creates a standart textbox for a field.
*************************************************************************/
_createTextInputForField: function (field, fieldName, value) {
- return $('<div class="jtable-input jtable-text-input"><input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input></div>');
+ var $input = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input>');
+ return $('<div />')
+ .addClass('jtable-input jtable-text-input')
+ .append($input);
},
/* Creates a password input for a field.
*************************************************************************/
_createPasswordInputForField: function (field, fieldName, value) {
- return $('<div class="jtable-input jtable-password-input"><input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="password"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input></div>');
+ var $input = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="password"' + (value != undefined ? 'value="' + value + '"' : '') + ' name="' + fieldName + '"></input>');
+ return $('<div />')
+ .addClass('jtable-input jtable-password-input')
+ .append($input);
},
/* Creates a checkboxfor a field.
@@ -947,17 +1096,20 @@ THE SOFTWARE.
//If value is undefined, get unchecked state's value
if (value == undefined) {
- value = value || self._getCheckBoxPropertiesForFieldByState(fieldName, false).Value;
+ value = self._getCheckBoxPropertiesForFieldByState(fieldName, false).Value;
}
//Create a container div
- var $containerDiv = $('<div class="jtable-input jtable-checkbox-input"></div>');
+ var $containerDiv = $('<div />')
+ .addClass('jtable-input jtable-checkbox-input');
//Create checkbox and check if needed
- var $checkBox = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="checkbox" name="' + fieldName + '" value="' + value + '" />').appendTo($containerDiv);
+ var $checkBox = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="checkbox" name="' + fieldName + '" value="' + value + '" />')
+ .appendTo($containerDiv);
//Create display text of checkbox for current state
- var $textSpan = $('<span>' + (field.formText || self._getCheckBoxTextForFieldByValue(fieldName, value)) + '</span>').appendTo($containerDiv);
+ var $textSpan = $('<span>' + (field.formText || self._getCheckBoxTextForFieldByValue(fieldName, value)) + '</span>')
+ .appendTo($containerDiv);
//Check the checkbox if it's value is checked-value
if (self._getIsCheckBoxSelectedForFieldByValue(fieldName, value)) {
@@ -978,16 +1130,17 @@ THE SOFTWARE.
//Change checkbox state when clicked to text
if (field.setOnTextClick != false) {
- $textSpan.addClass('jtable-option-text-clickable');
- $textSpan.click(function () {
- if ($checkBox.is(':checked')) {
- $checkBox.attr('checked', false);
- } else {
- $checkBox.attr('checked', true);
- }
+ $textSpan
+ .addClass('jtable-option-text-clickable')
+ .click(function() {
+ if ($checkBox.is(':checked')) {
+ $checkBox.attr('checked', false);
+ } else {
+ $checkBox.attr('checked', true);
+ }
- refreshCheckBoxValueAndText();
- });
+ refreshCheckBoxValueAndText();
+ });
}
return $containerDiv;
@@ -997,10 +1150,12 @@ THE SOFTWARE.
*************************************************************************/
_createDropDownListForField: function (field, fieldName, value) {
//Create a container div
- var $containerDiv = $('<div class="jtable-input jtable-dropdown-input"></div>');
+ var $containerDiv = $('<div />')
+ .addClass('jtable-input jtable-dropdown-input');
//Create select element
- var $select = $('<select class="' + field.inputClass + '" id="Edit-' + fieldName + '" name=' + fieldName + '></select>').appendTo($containerDiv);
+ var $select = $('<select class="' + field.inputClass + '" id="Edit-' + fieldName + '" name="' + fieldName + '"></select>')
+ .appendTo($containerDiv);
//add options
var options = this._getOptionsWithCaching(fieldName);
@@ -1014,24 +1169,33 @@ THE SOFTWARE.
*************************************************************************/
_createRadioButtonListForField: function (field, fieldName, value) {
//Create a container div
- var $containerDiv = $('<div class="jtable-input jtable-radiobuttonlist-input"></div>');
+ var $containerDiv = $('<div />')
+ .addClass('jtable-input jtable-radiobuttonlist-input');
//create radio buttons
var options = this._getOptionsWithCaching(fieldName);
var radioButtonIndex = 0;
$.each(options, function (propName, propValue) {
- var $radioButtonDiv = $('<div class="jtable-radio-input"></div>').appendTo($containerDiv);
- var $radioButton = $('<input type="radio" id="Edit-' + fieldName + (radioButtonIndex++) + '" class="' + field.inputClass + '" name="' + fieldName + '" value="' + propName + '"' + (propName == value ? ' checked="true"' : '') + ' />').appendTo($radioButtonDiv);
- var $textSpan = $('<span>' + propValue + '</span>').appendTo($radioButtonDiv);
- //Change checkbox state when clicked to text
+ var $radioButtonDiv = $('<div class=""></div>')
+ .addClass('jtable-radio-input')
+ .appendTo($containerDiv);
+
+ var $radioButton = $('<input type="radio" id="Edit-' + fieldName + (radioButtonIndex++) + '" class="' + field.inputClass + '" name="' + fieldName + '" value="' + propName + '"' + ((propName == (value + '')) ? ' checked="true"' : '') + ' />')
+ .appendTo($radioButtonDiv);
+
+ var $textSpan = $('<span></span>')
+ .html(propValue)
+ .appendTo($radioButtonDiv);
+
if (field.setOnTextClick != false) {
- $textSpan.addClass('jtable-option-text-clickable');
- $textSpan.click(function () {
- if (!$radioButton.is(':checked')) {
- $radioButton.attr('checked', true);
- }
- });
+ $textSpan
+ .addClass('jtable-option-text-clickable')
+ .click(function() {
+ if (!$radioButton.is(':checked')) {
+ $radioButton.attr('checked', true);
+ }
+ });
}
});
@@ -1086,6 +1250,7 @@ THE SOFTWARE.
},
/* Gets options from cache if exists, else downloads and caches.
+ * TODO: Allow options to be a function and send record to the function.
*************************************************************************/
_getOptionsWithCaching: function (fieldName) {
var cacheKey = 'options_' + fieldName;
@@ -1111,13 +1276,12 @@ THE SOFTWARE.
*************************************************************************/
_downloadOptions: function (fieldName, url) {
var self = this;
-
var options = {};
- self._performAjaxCall(
- url,
- undefined,
- false,
- function (data) { //success
+
+ self._ajax({
+ url: url,
+ async: false,
+ success: function (data) {
if (data.Result != 'OK') {
self._showError(data.Message);
return;
@@ -1128,10 +1292,11 @@ THE SOFTWARE.
options[data.Options[i].Value] = data.Options[i].DisplayText;
}
},
- function () {
+ error: function () {
var errMessage = self._formatString(self.options.messages.cannotLoadOptionsFor, fieldName);
self._showError(errMessage);
- });
+ }
+ });
return options;
},
@@ -1156,13 +1321,19 @@ THE SOFTWARE.
}
if (enabled != false) {
- $button.removeAttr('disabled').removeClass('ui-state-disabled');
+ $button
+ .removeAttr('disabled')
+ .removeClass('ui-state-disabled');
} else {
- $button.attr('disabled', 'disabled').addClass('ui-state-disabled');
+ $button
+ .attr('disabled', 'disabled')
+ .addClass('ui-state-disabled');
}
if (buttonText) {
- $button.find('span').text(buttonText);
+ $button
+ .find('span')
+ .text(buttonText);
}
}
@@ -1170,6 +1341,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* CREATE RECORD extension for jTable *
*************************************************************************/
@@ -1225,7 +1397,8 @@ THE SOFTWARE.
}
//Create a div for dialog and add to container element
- self._$addRecordDiv = $('<div></div>').appendTo(self._$mainContainer);
+ self._$addRecordDiv = $('<div />')
+ .appendTo(self._$mainContainer);
//Prepare dialog
self._$addRecordDiv.dialog({
@@ -1279,8 +1452,13 @@ THE SOFTWARE.
/* Creates and returns 'add new record' button/link.
*************************************************************************/
_createAddRecordButton: function () {
- return $('<span class="jtable-add-record"><a href="#">' + this.options.messages.addNewRecord + '</a></span>').appendTo(this._$bottomPanel.find('.jtable-right-area'));
- //return $('<button class="jtable-command-button jtable-add-command-button" title="' + this.options.messages.addNewRecord + '"><span>' + this.options.messages.addNewRecord + '</span></button>').appendTo(this._$bottomPanel.find('.jtable-right-area'));
+ var $link = $('<a></a>')
+ .attr('href', '#')
+ .html(this.options.messages.addNewRecord);
+ return $('<span></span>')
+ .addClass('jtable-add-record')
+ .append($link)
+ .appendTo(this._$bottomPanel.find('.jtable-right-area'));
},
/************************************************************************
@@ -1311,7 +1489,12 @@ THE SOFTWARE.
}
if (options.clientOnly) {
- self._addRowToTable(self._createRowFromRecord(options.record), null, true, options.animationsEnabled);
+ self._addRow(
+ self._createRowFromRecord(options.record), {
+ isNewRow: true,
+ animationsEnabled: options.animationsEnabled
+ });
+
options.success();
return;
}
@@ -1320,7 +1503,6 @@ THE SOFTWARE.
options.url,
$.param(options.record),
function (data) {
- //Check for errors
if (data.Result != 'OK') {
self._showError(data.Message);
options.error(data);
@@ -1328,7 +1510,13 @@ THE SOFTWARE.
}
self._onRecordAdded(data);
- self._addRowToTable(self._createRowFromRecord(data.Record), null, true, options.animationsEnabled);
+
+ self._addRow(
+ self._createRowFromRecord(data.Record), {
+ isNewRow: true,
+ animationsEnabled: options.animationsEnabled
+ });
+
options.success(data);
},
function () {
@@ -1352,24 +1540,34 @@ THE SOFTWARE.
//Create input elements
for (var i = 0; i < self._fieldList.length; i++) {
+ var fieldName = self._fieldList[i];
+ var field = self.options.fields[fieldName];
+
+ //Do not create input for fields that is key and not specially marked as editable
+ if (field.key == true && field.edit != true) {
+ continue;
+ }
+
//Do not create input for fields that are not creatable
- if (self.options.fields[self._fieldList[i]].create == false) {
+ if (field.create == false) {
continue;
}
- if (self.options.fields[self._fieldList[i]].type == 'hidden') {
- $addRecordForm.append(self._createInputForHidden(self._fieldList[i], self.options.fields[self._fieldList[i]].defaultValue));
+ if (field.type == 'hidden') {
+ $addRecordForm.append(self._createInputForHidden(fieldName, field.defaultValue));
continue;
}
//Create a container div for this input field and add to form
- var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($addRecordForm);
+ var $fieldContainer = $('<div />')
+ .addClass('jtable-input-field-container')
+ .appendTo($addRecordForm);
//Create a label for input
- $fieldContainer.append(self._createInputLabelForRecordField(self._fieldList[i]));
+ $fieldContainer.append(self._createInputLabelForRecordField(fieldName));
//Create input element
- $fieldContainer.append(self._createInputForRecordField(self._fieldList[i]));
+ $fieldContainer.append(self._createInputForRecordField(fieldName));
}
//Open the form
@@ -1397,7 +1595,10 @@ THE SOFTWARE.
}
self._onRecordAdded(data);
- self._addRowToTable(self._createRowFromRecord(data.Record), null, true);
+ self._addRow(
+ self._createRowFromRecord(data.Record), {
+ isNewRow: true
+ });
self._$addRecordDiv.dialog("close");
},
function () {
@@ -1414,6 +1615,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* EDIT RECORD extension for jTable *
*************************************************************************/
@@ -1468,7 +1670,8 @@ THE SOFTWARE.
var self = this;
//Create a div for dialog and add to container element
- self._$editDiv = $('<div></div>').appendTo(self._$mainContainer);
+ self._$editDiv = $('<div></div>')
+ .appendTo(self._$mainContainer);
//Prepare dialog
self._$editDiv.dialog({
@@ -1523,8 +1726,13 @@ THE SOFTWARE.
error: function () { }
}, options);
- var key = options.record[self._keyField];
- if (!options.record || !key) {
+ if (!options.record) {
+ self._logWarn('options parameter in updateRecord method must contain a record property.');
+ return;
+ }
+
+ var key = self._getKeyValueOfRecord(options.record);
+ if (key == undefined || key == null) {
self._logWarn('options parameter in updateRecord method must contain a record that contains the key field property.');
return;
}
@@ -1538,9 +1746,7 @@ THE SOFTWARE.
if (options.clientOnly) {
$.extend($updatingRow.data('record'), options.record);
self._updateRowTexts($updatingRow);
-
self._onRecordUpdated($updatingRow, null);
-
if (options.animationsEnabled) {
self._showUpdateAnimationForRow($updatingRow);
}
@@ -1553,7 +1759,6 @@ THE SOFTWARE.
options.url,
$.param(options.record),
function (data) {
- //Check for errors
if (data.Result != 'OK') {
self._showError(data.Message);
options.error(data);
@@ -1562,9 +1767,7 @@ THE SOFTWARE.
$.extend($updatingRow.data('record'), options.record);
self._updateRowTexts($updatingRow);
-
self._onRecordUpdated($updatingRow, data);
-
if (options.animationsEnabled) {
self._showUpdateAnimationForRow($updatingRow);
}
@@ -1595,15 +1798,21 @@ THE SOFTWARE.
_addCellsToRowUsingRecord: function ($row) {
var self = this;
base._addCellsToRowUsingRecord.apply(this, arguments);
+
if (self.options.actions.updateAction != undefined) {
- var $editCell = $('<td class="jtable-command-column"></td>').appendTo($row);
- $('<button class="jtable-command-button jtable-edit-command-button" title="' + self.options.messages.editRecord + '"><span>' + self.options.messages.editRecord + '</span></button>')
- .appendTo($editCell)
+ var $span = $('<span></span>').html(self.options.messages.editRecord);
+ var $button = $('<button title="' + self.options.messages.editRecord + '"></button>')
+ .addClass('jtable-command-button jtable-edit-command-button')
+ .append($span)
.click(function (e) {
e.preventDefault();
e.stopPropagation();
self._showEditForm($row);
});
+ $('<td></td>')
+ .addClass('jtable-command-column')
+ .append($button)
+ .appendTo($row);
}
},
@@ -1623,20 +1832,29 @@ THE SOFTWARE.
//Create input fields
for (var i = 0; i < self._fieldList.length; i++) {
- //Create hidden input for 'key' field
- if (self.options.fields[self._fieldList[i]].key == true) {
- $editForm.append(self._createInputForHidden(self._fieldList[i], record[self._fieldList[i]]));
- continue;
+ var fieldName = self._fieldList[i];
+ var field = self.options.fields[fieldName];
+ var fieldValue = record[fieldName];
+
+ if (field.key == true) {
+ if (field.edit != true) {
+ //Create hidden field for key
+ $editForm.append(self._createInputForHidden(fieldName, fieldValue));
+ continue;
+ } else {
+ //Create a special hidden field for key (since key is be editable)
+ $editForm.append(self._createInputForHidden('jtRecordKey', fieldValue));
+ }
}
//Do not create element for non-editable fields
- if (self.options.fields[self._fieldList[i]].edit == false) {
+ if (field.edit == false) {
continue;
}
//Hidden field
- if (self.options.fields[self._fieldList[i]].type == 'hidden') {
- $editForm.append(self._createInputForHidden(self._fieldList[i], record[self._fieldList[i]]));
+ if (field.type == 'hidden') {
+ $editForm.append(self._createInputForHidden(fieldName, fieldValue));
continue;
}
@@ -1644,11 +1862,11 @@ THE SOFTWARE.
var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($editForm);
//Create a label for input
- $fieldContainer.append(self._createInputLabelForRecordField(self._fieldList[i]));
+ $fieldContainer.append(self._createInputLabelForRecordField(fieldName));
//Create input element with it's current value
- var currentValue = self._getValueForRecordField(record, self._fieldList[i]);
- $fieldContainer.append(self._createInputForRecordField(self._fieldList[i], currentValue, record));
+ var currentValue = self._getValueForRecordField(record, fieldName);
+ $fieldContainer.append(self._createInputForRecordField(fieldName, currentValue, record));
}
//Open dialog
@@ -1672,15 +1890,18 @@ THE SOFTWARE.
return;
}
- var $editingRow = self._$editingRow;
-
- self._updateRecordValuesFromEditForm($editingRow.data('record'), $editForm);
- self._updateRowTexts($editingRow);
+ var record = self._$editingRow.data('record');
+
+ self._updateRecordValuesFromEditForm(record, $editForm);
+ self._updateRecordValuesFromServerResponse(record, data);
+ self._updateRowTexts(self._$editingRow);
+
+ self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
- self._onRecordUpdated($editingRow, data);
+ self._onRecordUpdated(self._$editingRow, data);
if (self.options.animationsEnabled) {
- self._showUpdateAnimationForRow($editingRow);
+ self._showUpdateAnimationForRow(self._$editingRow);
}
self._$editDiv.dialog("close");
@@ -1729,6 +1950,18 @@ THE SOFTWARE.
}
},
+
+ /* This method ensures updating of current record with server response,
+ * if server sends a Record object as response to updateAction.
+ *************************************************************************/
+ _updateRecordValuesFromServerResponse: function (record, serverResponse) {
+ if (!serverResponse || !serverResponse.Record) {
+ return;
+ }
+
+ $.extend(true, record, serverResponse.Record);
+ },
+
/* Gets text for a field of a record according to it's type.
*************************************************************************/
_getValueForRecordField: function (record, fieldName) {
@@ -1750,7 +1983,7 @@ THE SOFTWARE.
var displayItem = this._getDisplayTextForRecordField(record, this._columnList[i]);
$columns.eq(this._firstDataColumnOffset + i).html(displayItem || '');
}
-
+
this._onRowUpdated($tableRow);
},
@@ -1778,6 +2011,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* DELETION extension for jTable *
*************************************************************************/
@@ -1888,8 +2122,13 @@ THE SOFTWARE.
deleteRows: function ($rows) {
var self = this;
- //If no rows specified, or jTable is already busy, no action.
- if ($rows.length <= 0 || self._isBusy()) {
+ if ($rows.length <= 0) {
+ self._logWarn('No rows specified to jTable deleteRows method.');
+ return;
+ }
+
+ if (self._isBusy()) {
+ self._logWarn('Can not delete rows since jTable is busy!');
return;
}
@@ -1967,8 +2206,8 @@ THE SOFTWARE.
error: function () { }
}, options);
- if (!options.key) {
- self._logWarn('options parameter in deleteRecord method must contain a record key.');
+ if (options.key == undefined) {
+ self._logWarn('options parameter in deleteRecord method must contain a key property.');
return;
}
@@ -2018,14 +2257,19 @@ THE SOFTWARE.
var self = this;
if (self.options.actions.deleteAction != undefined) {
- var $deleteCell = $('<td class="jtable-command-column"></td>').appendTo($row);
- $('<button class="jtable-command-button jtable-delete-command-button" title="' + self.options.messages.deleteText + '"><span>' + self.options.messages.deleteText + '</span></button>')
- .appendTo($deleteCell)
+ var $span = $('<span></span>').html(self.options.messages.deleteText);
+ var $button = $('<button title="' + self.options.messages.deleteText + '"></button>')
+ .addClass('jtable-command-button jtable-delete-command-button')
+ .append($span)
.click(function (e) {
e.preventDefault();
e.stopPropagation();
self._deleteButtonClickedForRow($row);
});
+ $('<td></td>')
+ .addClass('jtable-command-column')
+ .append($button)
+ .appendTo($row);
}
},
@@ -2102,13 +2346,13 @@ THE SOFTWARE.
$row.data('deleting', true);
var postData = {};
- postData[self._keyField] = $row.data('record')[self._keyField];
- self._performAjaxCall(
- (url || self.options.actions.deleteAction),
- postData,
- true,
- function (data) { //success
- //Check for errors
+ postData[self._keyField] = self._getKeyValueOfRecord($row.data('record'));
+
+ this._ajax({
+ url: (url || self.options.actions.deleteAction),
+ data: postData,
+ success: function (data) {
+
if (data.Result != 'OK') {
$row.data('deleting', false);
if (error) {
@@ -2124,12 +2368,13 @@ THE SOFTWARE.
success(data);
}
},
- function () {
+ error: function () {
$row.data('deleting', false);
if (error) {
error(self.options.messages.serverCommunicationError);
}
- });
+ }
+ });
},
/* Removes a row from table after a 'deleting' animation.
@@ -2155,6 +2400,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* SELECTING extension for jTable *
*************************************************************************/
@@ -2218,19 +2464,21 @@ THE SOFTWARE.
_bindKeyboardEvents: function () {
var self = this;
//Register to events to set _shiftKeyDown value
- $(document).keydown(function (event) {
- switch (event.which) {
- case 16: //shift key
+ $(document)
+ .keydown(function(event) {
+ switch (event.which) {
+ case 16:
self._shiftKeyDown = true;
break;
- }
- }).keyup(function (event) {
- switch (event.which) {
- case 16: //shift key
+ }
+ })
+ .keyup(function(event) {
+ switch (event.which) {
+ case 16:
self._shiftKeyDown = false;
break;
- }
- });
+ }
+ });
},
/************************************************************************
@@ -2242,6 +2490,13 @@ THE SOFTWARE.
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 *
@@ -2304,25 +2559,30 @@ THE SOFTWARE.
_createSelectAllHeader: function () {
var self = this;
- var $columnHeader = $('<th class="jtable-command-column-header jtable-column-header-selecting"></th>');
- var $headerContainer = $('<div class="jtable-column-header-container"></div>').appendTo($columnHeader);
- self._$selectAllCheckbox = $('<input type="checkbox" />').appendTo($headerContainer);
+ var $columnHeader = $('<th class=""></th>')
+ .addClass('jtable-command-column-header jtable-column-header-selecting');
- self._$selectAllCheckbox.click(function () {
- if (self._$tableRows.length <= 0) {
- self._$selectAllCheckbox.attr('checked', false);
- return;
- }
+ var $headerContainer = $('<div />')
+ .addClass('jtable-column-header-container')
+ .appendTo($columnHeader);
- var allRows = self._$tableBody.find('tr');
- if (self._$selectAllCheckbox.is(':checked')) {
- self._selectRows(allRows);
- } else {
- self._deselectRows(allRows);
- }
+ self._$selectAllCheckbox = $('<input type="checkbox" />')
+ .appendTo($headerContainer)
+ .click(function() {
+ if (self._$tableRows.length <= 0) {
+ self._$selectAllCheckbox.attr('checked', false);
+ return;
+ }
- self._onSelectionChanged();
- });
+ 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;
},
@@ -2338,7 +2598,7 @@ THE SOFTWARE.
self._selectedRecordIdsBeforeLoad = [];
self._getSelectedRows().each(function () {
- self._selectedRecordIdsBeforeLoad.push($(this).data('record')[self._keyField]);
+ self._selectedRecordIdsBeforeLoad.push(self._getKeyValueOfRecord($(this).data('record')));
});
},
@@ -2353,7 +2613,8 @@ THE SOFTWARE.
var selectedRowCount = 0;
for (var i = 0; i < self._$tableRows.length; ++i) {
- if ($.inArray(self._$tableRows[i].data('record')[self._keyField], self._selectedRecordIdsBeforeLoad) > -1) {
+ var recordId = self._getKeyValueOfRecord(self._$tableRows[i].data('record'));
+ if ($.inArray(recordId, self._selectedRecordIdsBeforeLoad) > -1) {
self._selectRows(self._$tableRows[i]);
++selectedRowCount;
}
@@ -2370,7 +2631,8 @@ THE SOFTWARE.
/* Gets all selected rows.
*************************************************************************/
_getSelectedRows: function () {
- return this._$tableBody.find('.jtable-row-selected');
+ return this._$tableBody
+ .find('.jtable-row-selected');
},
/* Adds selectable feature to a row.
@@ -2387,9 +2649,10 @@ THE SOFTWARE.
//'select/deselect' checkbox column
if (self.options.selectingCheckboxes) {
- var $cell = $('<td class="jtable-selecting-column"></td>');
- var $selectCheckbox = $('<input type="checkbox" />').appendTo($cell);
-
+ 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);
@@ -2516,6 +2779,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* PAGING extension for jTable *
*************************************************************************/
@@ -2527,6 +2791,7 @@ THE SOFTWARE.
_create: $.hik.jtable.prototype._create,
_createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
_addRowToTable: $.hik.jtable.prototype._addRowToTable,
+ _addRow: $.hik.jtable.prototype._addRow,
_removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable,
_onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded
};
@@ -2572,7 +2837,9 @@ THE SOFTWARE.
return;
}
- this._$pagingListArea = $('<span class="jtable-page-list"></span>').prependTo(this._$bottomPanel.find('.jtable-left-area'));
+ this._$pagingListArea = $('<span></span>')
+ .addClass('jtable-page-list')
+ .prependTo(this._$bottomPanel.find('.jtable-left-area'));
},
/************************************************************************
@@ -2595,6 +2862,8 @@ THE SOFTWARE.
},
/* Overrides _addRowToTable method to re-load table when a new row is created.
+ * NOTE: THIS METHOD IS DEPRECATED AND WILL BE REMOVED FROM FEATURE RELEASES.
+ * USE _addRow METHOD.
*************************************************************************/
_addRowToTable: function($tableRow, index, isNewRow) {
if (isNewRow && this.options.paging) {
@@ -2604,6 +2873,17 @@ THE SOFTWARE.
base._addRowToTable.apply(this, arguments);
},
+
+ /* Overrides _addRow method to re-load table when a new row is created.
+ *************************************************************************/
+ _addRow: function ($row, options) {
+ if (options && options.isNewRow && this.options.paging) {
+ this._reloadTable();
+ return;
+ }
+
+ base._addRow.apply(this, arguments);
+ },
/* Overrides _removeRowsFromTable method to re-load table when a row is removed from table.
*************************************************************************/
@@ -2652,6 +2932,7 @@ THE SOFTWARE.
}
this._$pagingListArea.empty();
+
var pageCount = this._calculatePageCount();
this._createFirstAndPreviousPageButtons();
@@ -2665,10 +2946,14 @@ THE SOFTWARE.
*************************************************************************/
_createFirstAndPreviousPageButtons: function() {
if (this._currentPageNo > 1) {
- $('<span class="jtable-page-number-first">|&lt</span>')
+ $('<span></span>')
+ .addClass('jtable-page-number-first')
+ .html('|&lt')
.data('pageNumber', 1)
.appendTo(this._$pagingListArea);
- $('<span class="jtable-page-number-previous">&lt</span>')
+ $('<span></span>')
+ .addClass('jtable-page-number-previous')
+ .html('&lt')
.data('pageNumber', this._currentPageNo - 1)
.appendTo(this._$pagingListArea);
}
@@ -2678,10 +2963,14 @@ THE SOFTWARE.
*************************************************************************/
_createLastAndNextPageButtons: function(pageCount) {
if (this._currentPageNo < pageCount) {
- $('<span class="jtable-page-number-next">&gt</span>')
+ $('<span></span>')
+ .addClass('jtable-page-number-next')
+ .html('&gt')
.data('pageNumber', this._currentPageNo + 1)
.appendTo(this._$pagingListArea);
- $('<span class="jtable-page-number-last">&gt|</span>')
+ $('<span></span>')
+ .addClass('jtable-page-number-last')
+ .html('&gt|')
.data('pageNumber', pageCount)
.appendTo(this._$pagingListArea);
}
@@ -2694,7 +2983,10 @@ THE SOFTWARE.
for (var i = 0; i < pageNumbers.length; i++) {
//Create "..." between page numbers if needed
if ((pageNumbers[i] - previousNumber) > 1) {
- $('<span class="jtable-page-number-space">...</span>').appendTo(this._$pagingListArea);
+ $('<span></span>')
+ .addClass('jtable-page-number-space')
+ .html('...')
+ .appendTo(this._$pagingListArea);
}
this._createPageNumberButton(pageNumbers[i]);
@@ -2756,7 +3048,10 @@ THE SOFTWARE.
if (endNo >= startNo) {
var pagingInfoMessage = this._formatString(this.options.messages.pagingInfo, startNo, endNo, this._totalRecordCount);
- $('<span class="jtable-page-info">' + pagingInfoMessage + '</span>').appendTo(this._$pagingListArea);
+ $('<span></span>')
+ .addClass('jtable-page-info')
+ .html(pagingInfoMessage)
+ .appendTo(this._$pagingListArea);
}
},
@@ -2778,6 +3073,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* SORTING extension for jTable *
*************************************************************************/
@@ -2855,7 +3151,7 @@ THE SOFTWARE.
//Default sorting?
if (self.options.defaultSorting.indexOf(fieldName) > -1) {
- if (self.options.defaultSorting.indexOf('DESC') > -1) {
+ if (self.options.defaultSorting.indexOf(' DESC') > -1) {
$columnHeader.addClass('jtable-column-header-sorted-desc');
self._lastSorting = fieldName + " DESC";
} else {
@@ -2873,10 +3169,14 @@ THE SOFTWARE.
//Sort ASC or DESC according to current sorting state
if ($columnHeader.hasClass('jtable-column-header-sorted-asc')) {
- $columnHeader.removeClass('jtable-column-header-sorted-asc').addClass('jtable-column-header-sorted-desc');
+ $columnHeader
+ .removeClass('jtable-column-header-sorted-asc')
+ .addClass('jtable-column-header-sorted-desc');
this._lastSorting = $columnHeader.data('fieldName') + " DESC";
} else {
- $columnHeader.removeClass('jtable-column-header-sorted-desc').addClass('jtable-column-header-sorted-asc');
+ $columnHeader
+ .removeClass('jtable-column-header-sorted-desc')
+ .addClass('jtable-column-header-sorted-asc');
this._lastSorting = $columnHeader.data('fieldName') + " ASC";
}
@@ -2898,8 +3198,10 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* DYNAMIC COLUMNS extension for jTable *
+* (Show/hide/resize columns) *
*************************************************************************/
(function ($) {
@@ -3046,11 +3348,11 @@ THE SOFTWARE.
var columnIndexInTable = this._firstDataColumnOffset + columnIndex + 1;
if (field.visibility != 'hidden' && visibility == 'hidden') {
this._$table
- .find('th:nth-child(' + columnIndexInTable + '),td:nth-child(' + columnIndexInTable + ')')
+ .find('>thead >th:nth-child(' + columnIndexInTable + '),>tbody >td:nth-child(' + columnIndexInTable + ')')
.hide();
} else if (field.visibility == 'hidden' && visibility != 'hidden') {
this._$table
- .find('th:nth-child(' + columnIndexInTable + '),td:nth-child(' + columnIndexInTable + ')')
+ .find('>thead >th:nth-child(' + columnIndexInTable + '),>tbody >td:nth-child(' + columnIndexInTable + ')')
.show()
.css('display', 'table-cell');
}
@@ -3064,15 +3366,20 @@ THE SOFTWARE.
var self = this;
//Create a div for dialog and add to container element
- this._$columnSelectionDiv = $('<div class="jtable-column-selection-container"></div>').appendTo(self._$mainContainer);
- this._$table.find('thead').bind('contextmenu', function (e) {
+ 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 class="jtable-contextmenu-overlay"></div>')
+ $('<div />')
+ .addClass('jtable-contextmenu-overlay')
.click(function () {
$(this).remove();
self._$columnSelectionDiv.hide();
@@ -3081,16 +3388,36 @@ THE SOFTWARE.
.appendTo(document.body);
self._fillColumnSelection();
- self._$columnSelectionDiv.css({ left: e.pageX - $(document).scrollLeft(), top: e.pageY - $(document).scrollTop() }).show();
+
+ //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 class="jtable-column-select-list"></ul>');
+ 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];
@@ -3099,7 +3426,8 @@ THE SOFTWARE.
var $columnLi = $('<li></li>').appendTo($columnsUl);
//Create label for the checkbox
- var $label = $('<label for="' + columnName + '"><span>' + (field.title || columnName) + '</span><label>')
+ var $label = $('<label for="' + columnName + '"></label>')
+ .append($('<span>' + (field.title || columnName) + '</span>'))
.appendTo($columnLi);
//Create checkbox
@@ -3133,7 +3461,8 @@ THE SOFTWARE.
/* creates a vertical bar that is shown while resizing columns.
*************************************************************************/
_createColumnResizeBar: function () {
- this._$columnResizeBar = $('<div class="jtable-column-resize-bar" style="position: fixed; top: -100px; left: -100px;"></div>')
+ this._$columnResizeBar = $('<div />')
+ .addClass('jtable-column-resize-bar')
.appendTo(this._$mainContainer)
.hide();
},
@@ -3144,12 +3473,15 @@ THE SOFTWARE.
var self = this;
//Create a handler to handle mouse click event
- $('<div class="jtable-column-resize-handler"></div>')
+ $('<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) {
@@ -3168,13 +3500,13 @@ THE SOFTWARE.
};
//Handle mouse move event to move resizing bar
- var resizeonmouseove = function (moveevent) {
+ 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 + 'px');
+ self._$columnResizeBar.css('left', (resizeBarX - mainContainerOffset.left) + 'px');
};
//Handle mouse up event to finish resizing of the column
@@ -3183,7 +3515,7 @@ THE SOFTWARE.
return;
}
- $(document).unbind('mousemove', resizeonmouseove);
+ $(document).unbind('mousemove', resizeonmousemove);
$(document).unbind('mouseup', resizeonmouseup);
self._$columnResizeBar.hide();
@@ -3218,13 +3550,13 @@ THE SOFTWARE.
self._$columnResizeBar
.show()
.css({
- top: ($columnHeader.offset().top - $(document).scrollTop()) + 'px',
- left: (downevent.pageX - $(document).scrollLeft()) + 'px',
- height: self._$table.height() + 'px'
+ top: ($columnHeader.offset().top - mainContainerOffset.top) + 'px',
+ left: (downevent.pageX - mainContainerOffset.left) + 'px',
+ height: (self._$table.outerHeight()) + 'px'
});
//Bind events
- $(document).bind('mousemove', resizeonmouseove);
+ $(document).bind('mousemove', resizeonmousemove);
$(document).bind('mouseup', resizeonmouseup);
});
},
@@ -3235,12 +3567,12 @@ THE SOFTWARE.
//Set command column width
var commandColumnHeaders = this._$table
- .find('thead th.jtable-command-column-header')
+ .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');
+ var headerCells = this._$table.find('>thead th.jtable-column-header');
//Calculate total width of data columns
var totalWidthInPixel = 0;
@@ -3280,7 +3612,7 @@ THE SOFTWARE.
_saveColumnSettings: function () {
var self = this;
var fieldSettings = '';
- this._$table.find('thead th.jtable-column-header').each(function () {
+ this._$table.find('>thead >th.jtable-column-header').each(function () {
var $cell = $(this);
var fieldName = $cell.data('fieldName');
var columnWidth = $cell.data('width-in-percent');
@@ -3290,7 +3622,6 @@ THE SOFTWARE.
});
this._setCookie('column-settings', fieldSettings.substr(0, fieldSettings.length - 1));
- this._logDebug("saved");
},
/* Loads field settings from cookie that is saved by _saveFieldSettings method.
@@ -3313,7 +3644,7 @@ THE SOFTWARE.
}; ;
});
- var headerCells = this._$table.find('thead th.jtable-column-header');
+ var headerCells = this._$table.find('>thead >th.jtable-column-header');
headerCells.each(function () {
var $cell = $(this);
var fieldName = $cell.data('fieldName');
@@ -3326,7 +3657,6 @@ THE SOFTWARE.
$cell.data('width-in-percent', columnSettings[fieldName].columnWidth).css('width', columnSettings[fieldName].columnWidth + '%');
}
});
- this._logDebug("loaded");
},
/************************************************************************
@@ -3399,6 +3729,7 @@ THE SOFTWARE.
})(jQuery);
+
/************************************************************************
* MASTER/CHILD tables extension for jTable *
*************************************************************************/
@@ -3440,21 +3771,25 @@ THE SOFTWARE.
//If accordion style, close open child table (if it does exists)
if (self.options.openChildAsAccordion) {
- $row.siblings().each(function () {
+ $row.siblings('.jtable-data-row').each(function () {
self.closeChildTable($(this));
});
}
//Close child table for this row and open new one for child table
self.closeChildTable($row, function () {
- var $childRowColumn = self.getChildRow($row).find('td').empty();
- var $childTableContainer = $('<div class="jtable-child-table-container"></div>').appendTo($childRowColumn);
+ var $childRowColumn = self.getChildRow($row).children('td').empty();
+ var $childTableContainer = $('<div />')
+ .addClass('jtable-child-table-container')
+ .appendTo($childRowColumn);
$childRowColumn.data('childTable', $childTableContainer);
$childTableContainer.jtable(tableOptions);
self.openChildRow($row);
$childTableContainer.hide().slideDown('fast', function () {
if (opened) {
- opened({ childTable: $childTableContainer });
+ opened({
+ childTable: $childTableContainer
+ });
}
});
});
@@ -3464,8 +3799,8 @@ THE SOFTWARE.
*************************************************************************/
closeChildTable: function ($row, closed) {
var self = this;
-
- var $childRowColumn = this.getChildRow($row).find('td');
+
+ var $childRowColumn = this.getChildRow($row).children('td');
var $childTable = $childRowColumn.data('childTable');
if (!$childTable) {
if (closed) {
@@ -3548,10 +3883,11 @@ THE SOFTWARE.
/* Creates a child row for a row, hides and returns it.
*************************************************************************/
_createChildRow: function ($row) {
- var index = this._findRowIndex($row);
var totalColumnCount = this._$table.find('thead th').length;
- var $childRow = $('<tr class="jtable-child-row"></tr>').append('<td colspan="' + totalColumnCount + '"></td>');
- this._addRowToTable($childRow, index + 1);
+ var $childRow = $('<tr></tr>')
+ .addClass('jtable-child-row')
+ .append('<td colspan="' + totalColumnCount + '"></td>');
+ $row.after($childRow);
$row.data('childRow', $childRow);
$childRow.hide();
return $childRow;
@@ -3560,3 +3896,4 @@ THE SOFTWARE.
});
})(jQuery);
+