mirror of
https://github.com/tuxis-ie/nsedit.git
synced 2025-07-22 19:33:34 +03:00
Merge commit '8997d5b1ff
' as 'jtable'
This commit is contained in:
commit
d90fb0d2a6
155 changed files with 22323 additions and 0 deletions
BIN
jtable/dev/build/JTableBuilder-source.zip
Normal file
BIN
jtable/dev/build/JTableBuilder-source.zip
Normal file
Binary file not shown.
6
jtable/dev/build/README.md
Normal file
6
jtable/dev/build/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
jtable builder
|
||||
======
|
||||
|
||||
Although you can manually merge all javascript files in order in jquery.jtable.build.txt file, you can use this tool to merge all javascript files and build jquery.jtable.js. Just run jTableBuilder-build.bat.
|
||||
|
||||
NOTE: It's a C# (.NET 4.0) application.
|
1
jtable/dev/build/jTableBuilder-build.bat
Normal file
1
jtable/dev/build/jTableBuilder-build.bat
Normal file
|
@ -0,0 +1 @@
|
|||
jTableBuilder.exe ..\jquery.jtable.build.txt
|
BIN
jtable/dev/build/jTableBuilder.exe
Normal file
BIN
jtable/dev/build/jTableBuilder.exe
Normal file
Binary file not shown.
13
jtable/dev/jquery.jtable.build.txt
Normal file
13
jtable/dev/jquery.jtable.build.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
create ..\jquery.jtable.js
|
||||
add jquery.jtable.header.txt
|
||||
add jquery.jtable.core.js
|
||||
add jquery.jtable.utils.js
|
||||
add jquery.jtable.forms.js
|
||||
add jquery.jtable.creation.js
|
||||
add jquery.jtable.editing.js
|
||||
add jquery.jtable.deletion.js
|
||||
add jquery.jtable.selecting.js
|
||||
add jquery.jtable.paging.js
|
||||
add jquery.jtable.sorting.js
|
||||
add jquery.jtable.dynamiccolumns.js
|
||||
add jquery.jtable.masterchild.js
|
1290
jtable/dev/jquery.jtable.core.js
Normal file
1290
jtable/dev/jquery.jtable.core.js
Normal file
File diff suppressed because it is too large
Load diff
348
jtable/dev/jquery.jtable.creation.js
Normal file
348
jtable/dev/jquery.jtable.creation.js
Normal file
|
@ -0,0 +1,348 @@
|
|||
/************************************************************************
|
||||
* CREATE RECORD extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_create: $.hik.jtable.prototype._create
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
|
||||
//Events
|
||||
recordAdded: function (event, data) { },
|
||||
|
||||
//Localization
|
||||
messages: {
|
||||
addNewRecord: 'Add new record'
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_$addRecordDiv: null, //Reference to the adding new record dialog div (jQuery object)
|
||||
|
||||
/************************************************************************
|
||||
* CONSTRUCTOR *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to do create-specific constructions.
|
||||
*************************************************************************/
|
||||
_create: function () {
|
||||
base._create.apply(this, arguments);
|
||||
|
||||
if (!this.options.actions.createAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._createAddRecordDialogDiv();
|
||||
},
|
||||
|
||||
/* Creates and prepares add new record dialog div
|
||||
*************************************************************************/
|
||||
_createAddRecordDialogDiv: function () {
|
||||
var self = this;
|
||||
|
||||
//Create a div for dialog and add to container element
|
||||
self._$addRecordDiv = $('<div />')
|
||||
.appendTo(self._$mainContainer);
|
||||
|
||||
//Prepare dialog
|
||||
self._$addRecordDiv.dialog({
|
||||
autoOpen: false,
|
||||
show: self.options.dialogShowEffect,
|
||||
hide: self.options.dialogHideEffect,
|
||||
width: 'auto',
|
||||
minWidth: '300',
|
||||
modal: true,
|
||||
title: self.options.messages.addNewRecord,
|
||||
buttons:
|
||||
[{ //Cancel button
|
||||
text: self.options.messages.cancel,
|
||||
click: function () {
|
||||
self._$addRecordDiv.dialog('close');
|
||||
}
|
||||
}, { //Save button
|
||||
id: 'AddRecordDialogSaveButton',
|
||||
text: self.options.messages.save,
|
||||
click: function () {
|
||||
self._onSaveClickedOnCreateForm();
|
||||
}
|
||||
}],
|
||||
close: function () {
|
||||
var $addRecordForm = self._$addRecordDiv.find('form').first();
|
||||
var $saveButton = self._$addRecordDiv.parent().find('#AddRecordDialogSaveButton');
|
||||
self._trigger("formClosed", null, { form: $addRecordForm, formType: 'create' });
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
$addRecordForm.remove();
|
||||
}
|
||||
});
|
||||
|
||||
if (self.options.addRecordButton) {
|
||||
//If user supplied a button, bind the click event to show dialog form
|
||||
self.options.addRecordButton.click(function (e) {
|
||||
e.preventDefault();
|
||||
self._showAddRecordForm();
|
||||
});
|
||||
} else {
|
||||
//If user did not supplied a button, create a 'add record button' toolbar item.
|
||||
self._addToolBarItem({
|
||||
icon: true,
|
||||
cssClass: 'jtable-toolbar-item-add-record',
|
||||
text: self.options.messages.addNewRecord,
|
||||
click: function () {
|
||||
self._showAddRecordForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onSaveClickedOnCreateForm: function () {
|
||||
var self = this;
|
||||
|
||||
var $saveButton = self._$addRecordDiv.parent().find('#AddRecordDialogSaveButton');
|
||||
var $addRecordForm = self._$addRecordDiv.find('form');
|
||||
|
||||
if (self._trigger("formSubmitting", null, { form: $addRecordForm, formType: 'create' }) != false) {
|
||||
self._setEnabledOfDialogButton($saveButton, false, self.options.messages.saving);
|
||||
self._saveAddRecordForm($addRecordForm, $saveButton);
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PUBLIC METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Shows add new record dialog form.
|
||||
*************************************************************************/
|
||||
showCreateForm: function () {
|
||||
this._showAddRecordForm();
|
||||
},
|
||||
|
||||
/* Adds a new record to the table (optionally to the server also)
|
||||
*************************************************************************/
|
||||
addRecord: function (options) {
|
||||
var self = this;
|
||||
options = $.extend({
|
||||
clientOnly: false,
|
||||
animationsEnabled: self.options.animationsEnabled,
|
||||
success: function () { },
|
||||
error: function () { }
|
||||
}, options);
|
||||
|
||||
if (!options.record) {
|
||||
self._logWarn('options parameter in addRecord method must contain a record property.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.clientOnly) {
|
||||
self._addRow(
|
||||
self._createRowFromRecord(options.record), {
|
||||
isNewRow: true,
|
||||
animationsEnabled: options.animationsEnabled
|
||||
});
|
||||
|
||||
options.success();
|
||||
return;
|
||||
}
|
||||
|
||||
var completeAddRecord = function (data) {
|
||||
if (data.Result != 'OK') {
|
||||
self._showError(data.Message);
|
||||
options.error(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.Record) {
|
||||
self._logError('Server must return the created Record object.');
|
||||
options.error(data);
|
||||
return;
|
||||
}
|
||||
|
||||
self._onRecordAdded(data);
|
||||
self._addRow(
|
||||
self._createRowFromRecord(data.Record), {
|
||||
isNewRow: true,
|
||||
animationsEnabled: options.animationsEnabled
|
||||
});
|
||||
|
||||
options.success(data);
|
||||
};
|
||||
|
||||
//createAction may be a function, check if it is
|
||||
if (!options.url && $.isFunction(self.options.actions.createAction)) {
|
||||
|
||||
//Execute the function
|
||||
var funcResult = self.options.actions.createAction($.param(options.record));
|
||||
|
||||
//Check if result is a jQuery Deferred object
|
||||
if (self._isDeferredObject(funcResult)) {
|
||||
//Wait promise
|
||||
funcResult.done(function (data) {
|
||||
completeAddRecord(data);
|
||||
}).fail(function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
options.error();
|
||||
});
|
||||
} else { //assume it returned the creation result
|
||||
completeAddRecord(funcResult);
|
||||
}
|
||||
|
||||
} else { //Assume it's a URL string
|
||||
|
||||
//Make an Ajax call to create record
|
||||
self._submitFormUsingAjax(
|
||||
options.url || self.options.actions.createAction,
|
||||
$.param(options.record),
|
||||
function (data) {
|
||||
completeAddRecord(data);
|
||||
},
|
||||
function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
options.error();
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Shows add new record dialog form.
|
||||
*************************************************************************/
|
||||
_showAddRecordForm: function () {
|
||||
var self = this;
|
||||
|
||||
//Create add new record form
|
||||
var $addRecordForm = $('<form id="jtable-create-form" class="jtable-dialog-form jtable-create-form"></form>');
|
||||
|
||||
//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 creatable
|
||||
if (field.key == true && field.create != true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Do not create input for fields that are not creatable
|
||||
if (field.create == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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 />')
|
||||
.addClass('jtable-input-field-container')
|
||||
.appendTo($addRecordForm);
|
||||
|
||||
//Create a label for input
|
||||
$fieldContainer.append(self._createInputLabelForRecordField(fieldName));
|
||||
|
||||
//Create input element
|
||||
$fieldContainer.append(
|
||||
self._createInputForRecordField({
|
||||
fieldName: fieldName,
|
||||
formType: 'create',
|
||||
form: $addRecordForm
|
||||
}));
|
||||
}
|
||||
|
||||
self._makeCascadeDropDowns($addRecordForm, undefined, 'create');
|
||||
|
||||
$addRecordForm.submit(function () {
|
||||
self._onSaveClickedOnCreateForm();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Open the form
|
||||
self._$addRecordDiv.append($addRecordForm).dialog('open');
|
||||
self._trigger("formCreated", null, { form: $addRecordForm, formType: 'create' });
|
||||
},
|
||||
|
||||
/* Saves new added record to the server and updates table.
|
||||
*************************************************************************/
|
||||
_saveAddRecordForm: function ($addRecordForm, $saveButton) {
|
||||
var self = this;
|
||||
|
||||
var completeAddRecord = function (data) {
|
||||
if (data.Result != 'OK') {
|
||||
self._showError(data.Message);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.Record) {
|
||||
self._logError('Server must return the created Record object.');
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
return;
|
||||
}
|
||||
|
||||
self._onRecordAdded(data);
|
||||
self._addRow(
|
||||
self._createRowFromRecord(data.Record), {
|
||||
isNewRow: true
|
||||
});
|
||||
self._$addRecordDiv.dialog("close");
|
||||
};
|
||||
|
||||
$addRecordForm.data('submitting', true); //TODO: Why it's used, can remove? Check it.
|
||||
|
||||
//createAction may be a function, check if it is
|
||||
if ($.isFunction(self.options.actions.createAction)) {
|
||||
|
||||
//Execute the function
|
||||
var funcResult = self.options.actions.createAction($addRecordForm.serialize());
|
||||
|
||||
//Check if result is a jQuery Deferred object
|
||||
if (self._isDeferredObject(funcResult)) {
|
||||
//Wait promise
|
||||
funcResult.done(function (data) {
|
||||
completeAddRecord(data);
|
||||
}).fail(function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
});
|
||||
} else { //assume it returned the creation result
|
||||
completeAddRecord(funcResult);
|
||||
}
|
||||
|
||||
} else { //Assume it's a URL string
|
||||
|
||||
//Make an Ajax call to create record
|
||||
self._submitFormUsingAjax(
|
||||
self.options.actions.createAction,
|
||||
$addRecordForm.serialize(),
|
||||
function (data) {
|
||||
completeAddRecord(data);
|
||||
},
|
||||
function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onRecordAdded: function (data) {
|
||||
this._trigger("recordAdded", null, { record: data.Record, serverResponse: data });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
432
jtable/dev/jquery.jtable.deletion.js
Normal file
432
jtable/dev/jquery.jtable.deletion.js
Normal file
|
@ -0,0 +1,432 @@
|
|||
/************************************************************************
|
||||
* DELETION extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_create: $.hik.jtable.prototype._create,
|
||||
_addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
|
||||
_addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
|
||||
//Options
|
||||
deleteConfirmation: true,
|
||||
|
||||
//Events
|
||||
recordDeleted: function (event, data) { },
|
||||
|
||||
//Localization
|
||||
messages: {
|
||||
deleteConfirmation: 'This record will be deleted. Are you sure?',
|
||||
deleteText: 'Delete',
|
||||
deleting: 'Deleting',
|
||||
canNotDeletedRecords: 'Can not delete {0} of {1} records!',
|
||||
deleteProggress: 'Deleting {0} of {1} records, processing...'
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_$deleteRecordDiv: null, //Reference to the adding new record dialog div (jQuery object)
|
||||
_$deletingRow: null, //Reference to currently deleting row (jQuery object)
|
||||
|
||||
/************************************************************************
|
||||
* CONSTRUCTOR *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to do deletion-specific constructions.
|
||||
*************************************************************************/
|
||||
_create: function () {
|
||||
base._create.apply(this, arguments);
|
||||
this._createDeleteDialogDiv();
|
||||
},
|
||||
|
||||
/* Creates and prepares delete record confirmation dialog div.
|
||||
*************************************************************************/
|
||||
_createDeleteDialogDiv: function () {
|
||||
var self = this;
|
||||
|
||||
//Check if deleteAction is supplied
|
||||
if (!self.options.actions.deleteAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Create div element for delete confirmation dialog
|
||||
self._$deleteRecordDiv = $('<div><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span><span class="jtable-delete-confirm-message"></span></p></div>').appendTo(self._$mainContainer);
|
||||
|
||||
//Prepare dialog
|
||||
self._$deleteRecordDiv.dialog({
|
||||
autoOpen: false,
|
||||
show: self.options.dialogShowEffect,
|
||||
hide: self.options.dialogHideEffect,
|
||||
modal: true,
|
||||
title: self.options.messages.areYouSure,
|
||||
buttons:
|
||||
[{ //cancel button
|
||||
text: self.options.messages.cancel,
|
||||
click: function () {
|
||||
self._$deleteRecordDiv.dialog("close");
|
||||
}
|
||||
}, {//delete button
|
||||
id: 'DeleteDialogButton',
|
||||
text: self.options.messages.deleteText,
|
||||
click: function () {
|
||||
|
||||
//row maybe removed by another source, if so, do nothing
|
||||
if (self._$deletingRow.hasClass('jtable-row-removed')) {
|
||||
self._$deleteRecordDiv.dialog('close');
|
||||
return;
|
||||
}
|
||||
|
||||
var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
|
||||
self._setEnabledOfDialogButton($deleteButton, false, self.options.messages.deleting);
|
||||
self._deleteRecordFromServer(
|
||||
self._$deletingRow,
|
||||
function () {
|
||||
self._removeRowsFromTableWithAnimation(self._$deletingRow);
|
||||
self._$deleteRecordDiv.dialog('close');
|
||||
},
|
||||
function (message) { //error
|
||||
self._showError(message);
|
||||
self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
|
||||
}
|
||||
);
|
||||
}
|
||||
}],
|
||||
close: function () {
|
||||
var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
|
||||
self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PUBLIC METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* This method is used to delete one or more rows from server and the table.
|
||||
*************************************************************************/
|
||||
deleteRows: function ($rows) {
|
||||
var self = this;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//Deleting just one row
|
||||
if ($rows.length == 1) {
|
||||
self._deleteRecordFromServer(
|
||||
$rows,
|
||||
function () { //success
|
||||
self._removeRowsFromTableWithAnimation($rows);
|
||||
},
|
||||
function (message) { //error
|
||||
self._showError(message);
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Deleting multiple rows
|
||||
self._showBusy(self._formatString(self.options.messages.deleteProggress, 0, $rows.length));
|
||||
|
||||
//This method checks if deleting of all records is completed
|
||||
var completedCount = 0;
|
||||
var isCompleted = function () {
|
||||
return (completedCount >= $rows.length);
|
||||
};
|
||||
|
||||
//This method is called when deleting of all records completed
|
||||
var completed = function () {
|
||||
var $deletedRows = $rows.filter('.jtable-row-ready-to-remove');
|
||||
if ($deletedRows.length < $rows.length) {
|
||||
self._showError(self._formatString(self.options.messages.canNotDeletedRecords, $rows.length - $deletedRows.length, $rows.length));
|
||||
}
|
||||
|
||||
if ($deletedRows.length > 0) {
|
||||
self._removeRowsFromTableWithAnimation($deletedRows);
|
||||
}
|
||||
|
||||
self._hideBusy();
|
||||
};
|
||||
|
||||
//Delete all rows
|
||||
var deletedCount = 0;
|
||||
$rows.each(function () {
|
||||
var $row = $(this);
|
||||
self._deleteRecordFromServer(
|
||||
$row,
|
||||
function () { //success
|
||||
++deletedCount; ++completedCount;
|
||||
$row.addClass('jtable-row-ready-to-remove');
|
||||
self._showBusy(self._formatString(self.options.messages.deleteProggress, deletedCount, $rows.length));
|
||||
if (isCompleted()) {
|
||||
completed();
|
||||
}
|
||||
},
|
||||
function () { //error
|
||||
++completedCount;
|
||||
if (isCompleted()) {
|
||||
completed();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
/* Deletes a record from the table (optionally from the server also).
|
||||
*************************************************************************/
|
||||
deleteRecord: function (options) {
|
||||
var self = this;
|
||||
options = $.extend({
|
||||
clientOnly: false,
|
||||
animationsEnabled: self.options.animationsEnabled,
|
||||
url: self.options.actions.deleteAction,
|
||||
success: function () { },
|
||||
error: function () { }
|
||||
}, options);
|
||||
|
||||
if (options.key == undefined) {
|
||||
self._logWarn('options parameter in deleteRecord method must contain a key property.');
|
||||
return;
|
||||
}
|
||||
|
||||
var $deletingRow = self.getRowByKey(options.key);
|
||||
if ($deletingRow == null) {
|
||||
self._logWarn('Can not found any row by key: ' + options.key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.clientOnly) {
|
||||
self._removeRowsFromTableWithAnimation($deletingRow, options.animationsEnabled);
|
||||
options.success();
|
||||
return;
|
||||
}
|
||||
|
||||
self._deleteRecordFromServer(
|
||||
$deletingRow,
|
||||
function (data) { //success
|
||||
self._removeRowsFromTableWithAnimation($deletingRow, options.animationsEnabled);
|
||||
options.success(data);
|
||||
},
|
||||
function (message) { //error
|
||||
self._showError(message);
|
||||
options.error(message);
|
||||
},
|
||||
options.url
|
||||
);
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to add a 'deletion column cell' to header row.
|
||||
*************************************************************************/
|
||||
_addColumnsToHeaderRow: function ($tr) {
|
||||
base._addColumnsToHeaderRow.apply(this, arguments);
|
||||
if (this.options.actions.deleteAction != undefined) {
|
||||
$tr.append(this._createEmptyCommandHeader());
|
||||
}
|
||||
},
|
||||
|
||||
/* Overrides base method to add a 'delete command cell' to a row.
|
||||
*************************************************************************/
|
||||
_addCellsToRowUsingRecord: function ($row) {
|
||||
base._addCellsToRowUsingRecord.apply(this, arguments);
|
||||
|
||||
var self = this;
|
||||
if (self.options.actions.deleteAction != undefined) {
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* This method is called when user clicks delete button on a row.
|
||||
*************************************************************************/
|
||||
_deleteButtonClickedForRow: function ($row) {
|
||||
var self = this;
|
||||
|
||||
var deleteConfirm;
|
||||
var deleteConfirmMessage = self.options.messages.deleteConfirmation;
|
||||
|
||||
//If options.deleteConfirmation is function then call it
|
||||
if ($.isFunction(self.options.deleteConfirmation)) {
|
||||
var data = { row: $row, record: $row.data('record'), deleteConfirm: true, deleteConfirmMessage: deleteConfirmMessage, cancel: false, cancelMessage: null };
|
||||
self.options.deleteConfirmation(data);
|
||||
|
||||
//If delete progress is cancelled
|
||||
if (data.cancel) {
|
||||
|
||||
//If a canlellation reason is specified
|
||||
if (data.cancelMessage) {
|
||||
self._showError(data.cancelMessage); //TODO: show warning/stop message instead of error (also show warning/error ui icon)!
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
deleteConfirmMessage = data.deleteConfirmMessage;
|
||||
deleteConfirm = data.deleteConfirm;
|
||||
} else {
|
||||
deleteConfirm = self.options.deleteConfirmation;
|
||||
}
|
||||
|
||||
if (deleteConfirm != false) {
|
||||
//Confirmation
|
||||
self._$deleteRecordDiv.find('.jtable-delete-confirm-message').html(deleteConfirmMessage);
|
||||
self._showDeleteDialog($row);
|
||||
} else {
|
||||
//No confirmation
|
||||
self._deleteRecordFromServer(
|
||||
$row,
|
||||
function () { //success
|
||||
self._removeRowsFromTableWithAnimation($row);
|
||||
},
|
||||
function (message) { //error
|
||||
self._showError(message);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/* Shows delete comfirmation dialog.
|
||||
*************************************************************************/
|
||||
_showDeleteDialog: function ($row) {
|
||||
this._$deletingRow = $row;
|
||||
this._$deleteRecordDiv.dialog('open');
|
||||
},
|
||||
|
||||
/* Performs an ajax call to server to delete record
|
||||
* and removes row of the record from table if ajax call success.
|
||||
*************************************************************************/
|
||||
_deleteRecordFromServer: function ($row, success, error, url) {
|
||||
var self = this;
|
||||
|
||||
var completeDelete = function(data) {
|
||||
if (data.Result != 'OK') {
|
||||
$row.data('deleting', false);
|
||||
if (error) {
|
||||
error(data.Message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self._trigger("recordDeleted", null, { record: $row.data('record'), row: $row, serverResponse: data });
|
||||
|
||||
if (success) {
|
||||
success(data);
|
||||
}
|
||||
};
|
||||
|
||||
//Check if it is already being deleted right now
|
||||
if ($row.data('deleting') == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
$row.data('deleting', true);
|
||||
|
||||
var postData = {};
|
||||
postData[self._keyField] = self._getKeyValueOfRecord($row.data('record'));
|
||||
|
||||
//deleteAction may be a function, check if it is
|
||||
if (!url && $.isFunction(self.options.actions.deleteAction)) {
|
||||
|
||||
//Execute the function
|
||||
var funcResult = self.options.actions.deleteAction(postData);
|
||||
|
||||
//Check if result is a jQuery Deferred object
|
||||
if (self._isDeferredObject(funcResult)) {
|
||||
//Wait promise
|
||||
funcResult.done(function (data) {
|
||||
completeDelete(data);
|
||||
}).fail(function () {
|
||||
$row.data('deleting', false);
|
||||
if (error) {
|
||||
error(self.options.messages.serverCommunicationError);
|
||||
}
|
||||
});
|
||||
} else { //assume it returned the deletion result
|
||||
completeDelete(funcResult);
|
||||
}
|
||||
|
||||
} else { //Assume it's a URL string
|
||||
//Make ajax call to delete the record from server
|
||||
this._ajax({
|
||||
url: (url || self.options.actions.deleteAction),
|
||||
data: postData,
|
||||
success: function (data) {
|
||||
completeDelete(data);
|
||||
},
|
||||
error: function () {
|
||||
$row.data('deleting', false);
|
||||
if (error) {
|
||||
error(self.options.messages.serverCommunicationError);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/* Removes a row from table after a 'deleting' animation.
|
||||
*************************************************************************/
|
||||
_removeRowsFromTableWithAnimation: function ($rows, animationsEnabled) {
|
||||
var self = this;
|
||||
|
||||
if (animationsEnabled == undefined) {
|
||||
animationsEnabled = self.options.animationsEnabled;
|
||||
}
|
||||
|
||||
if (animationsEnabled) {
|
||||
var className = 'jtable-row-deleting';
|
||||
if (this.options.jqueryuiTheme) {
|
||||
className = className + ' ui-state-disabled';
|
||||
}
|
||||
|
||||
//Stop current animation (if does exists) and begin 'deleting' animation.
|
||||
$rows.stop(true, true).addClass(className, 'slow', '').promise().done(function () {
|
||||
self._removeRowsFromTable($rows, 'deleted');
|
||||
});
|
||||
} else {
|
||||
self._removeRowsFromTable($rows, 'deleted');
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
461
jtable/dev/jquery.jtable.dynamiccolumns.js
Normal file
461
jtable/dev/jquery.jtable.dynamiccolumns.js
Normal file
|
@ -0,0 +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
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* 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);
|
452
jtable/dev/jquery.jtable.editing.js
Normal file
452
jtable/dev/jquery.jtable.editing.js
Normal file
|
@ -0,0 +1,452 @@
|
|||
/************************************************************************
|
||||
* EDIT RECORD extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_create: $.hik.jtable.prototype._create,
|
||||
_addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
|
||||
_addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
|
||||
//Events
|
||||
recordUpdated: function (event, data) { },
|
||||
rowUpdated: function (event, data) { },
|
||||
|
||||
//Localization
|
||||
messages: {
|
||||
editRecord: 'Edit Record'
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_$editDiv: null, //Reference to the editing dialog div (jQuery object)
|
||||
_$editingRow: null, //Reference to currently editing row (jQuery object)
|
||||
|
||||
/************************************************************************
|
||||
* CONSTRUCTOR AND INITIALIZATION METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to do editing-specific constructions.
|
||||
*************************************************************************/
|
||||
_create: function () {
|
||||
base._create.apply(this, arguments);
|
||||
|
||||
if (!this.options.actions.updateAction) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._createEditDialogDiv();
|
||||
},
|
||||
|
||||
/* Creates and prepares edit dialog div
|
||||
*************************************************************************/
|
||||
_createEditDialogDiv: function () {
|
||||
var self = this;
|
||||
|
||||
//Create a div for dialog and add to container element
|
||||
self._$editDiv = $('<div></div>')
|
||||
.appendTo(self._$mainContainer);
|
||||
|
||||
//Prepare dialog
|
||||
self._$editDiv.dialog({
|
||||
autoOpen: false,
|
||||
show: self.options.dialogShowEffect,
|
||||
hide: self.options.dialogHideEffect,
|
||||
width: 'auto',
|
||||
minWidth: '300',
|
||||
modal: true,
|
||||
title: self.options.messages.editRecord,
|
||||
buttons:
|
||||
[{ //cancel button
|
||||
text: self.options.messages.cancel,
|
||||
click: function () {
|
||||
self._$editDiv.dialog('close');
|
||||
}
|
||||
}, { //save button
|
||||
id: 'EditDialogSaveButton',
|
||||
text: self.options.messages.save,
|
||||
click: function () {
|
||||
self._onSaveClickedOnEditForm();
|
||||
}
|
||||
}],
|
||||
close: function () {
|
||||
var $editForm = self._$editDiv.find('form:first');
|
||||
var $saveButton = self._$editDiv.parent().find('#EditDialogSaveButton');
|
||||
self._trigger("formClosed", null, { form: $editForm, formType: 'edit', row: self._$editingRow });
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
$editForm.remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/* Saves editing form to server.
|
||||
*************************************************************************/
|
||||
_onSaveClickedOnEditForm: function () {
|
||||
var self = this;
|
||||
|
||||
//row maybe removed by another source, if so, do nothing
|
||||
if (self._$editingRow.hasClass('jtable-row-removed')) {
|
||||
self._$editDiv.dialog('close');
|
||||
return;
|
||||
}
|
||||
|
||||
var $saveButton = self._$editDiv.parent().find('#EditDialogSaveButton');
|
||||
var $editForm = self._$editDiv.find('form');
|
||||
if (self._trigger("formSubmitting", null, { form: $editForm, formType: 'edit', row: self._$editingRow }) != false) {
|
||||
self._setEnabledOfDialogButton($saveButton, false, self.options.messages.saving);
|
||||
self._saveEditForm($editForm, $saveButton);
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PUBLIC METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Updates a record on the table (optionally on the server also)
|
||||
*************************************************************************/
|
||||
updateRecord: function (options) {
|
||||
var self = this;
|
||||
options = $.extend({
|
||||
clientOnly: false,
|
||||
animationsEnabled: self.options.animationsEnabled,
|
||||
success: function () { },
|
||||
error: function () { }
|
||||
}, options);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var $updatingRow = self.getRowByKey(key);
|
||||
if ($updatingRow == null) {
|
||||
self._logWarn('Can not found any row by key "' + key + '" on the table. Updating row must be visible on the table.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.clientOnly) {
|
||||
$.extend($updatingRow.data('record'), options.record);
|
||||
self._updateRowTexts($updatingRow);
|
||||
self._onRecordUpdated($updatingRow, null);
|
||||
if (options.animationsEnabled) {
|
||||
self._showUpdateAnimationForRow($updatingRow);
|
||||
}
|
||||
|
||||
options.success();
|
||||
return;
|
||||
}
|
||||
|
||||
var completeEdit = function (data) {
|
||||
if (data.Result != 'OK') {
|
||||
self._showError(data.Message);
|
||||
options.error(data);
|
||||
return;
|
||||
}
|
||||
|
||||
$.extend($updatingRow.data('record'), options.record);
|
||||
self._updateRecordValuesFromServerResponse($updatingRow.data('record'), data);
|
||||
|
||||
self._updateRowTexts($updatingRow);
|
||||
self._onRecordUpdated($updatingRow, data);
|
||||
if (options.animationsEnabled) {
|
||||
self._showUpdateAnimationForRow($updatingRow);
|
||||
}
|
||||
|
||||
options.success(data);
|
||||
};
|
||||
|
||||
//updateAction may be a function, check if it is
|
||||
if (!options.url && $.isFunction(self.options.actions.updateAction)) {
|
||||
|
||||
//Execute the function
|
||||
var funcResult = self.options.actions.updateAction($.param(options.record));
|
||||
|
||||
//Check if result is a jQuery Deferred object
|
||||
if (self._isDeferredObject(funcResult)) {
|
||||
//Wait promise
|
||||
funcResult.done(function (data) {
|
||||
completeEdit(data);
|
||||
}).fail(function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
options.error();
|
||||
});
|
||||
} else { //assume it returned the creation result
|
||||
completeEdit(funcResult);
|
||||
}
|
||||
|
||||
} else { //Assume it's a URL string
|
||||
|
||||
//Make an Ajax call to create record
|
||||
self._submitFormUsingAjax(
|
||||
options.url || self.options.actions.updateAction,
|
||||
$.param(options.record),
|
||||
function (data) {
|
||||
completeEdit(data);
|
||||
},
|
||||
function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
options.error();
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to add a 'editing column cell' to header row.
|
||||
*************************************************************************/
|
||||
_addColumnsToHeaderRow: function ($tr) {
|
||||
base._addColumnsToHeaderRow.apply(this, arguments);
|
||||
if (this.options.actions.updateAction != undefined) {
|
||||
$tr.append(this._createEmptyCommandHeader());
|
||||
}
|
||||
},
|
||||
|
||||
/* Overrides base method to add a 'edit command cell' to a row.
|
||||
*************************************************************************/
|
||||
_addCellsToRowUsingRecord: function ($row) {
|
||||
var self = this;
|
||||
base._addCellsToRowUsingRecord.apply(this, arguments);
|
||||
|
||||
if (self.options.actions.updateAction != undefined) {
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Shows edit form for a row.
|
||||
*************************************************************************/
|
||||
_showEditForm: function ($tableRow) {
|
||||
var self = this;
|
||||
var record = $tableRow.data('record');
|
||||
|
||||
//Create edit form
|
||||
var $editForm = $('<form id="jtable-edit-form" class="jtable-dialog-form jtable-edit-form"></form>');
|
||||
|
||||
//Create input fields
|
||||
for (var i = 0; i < self._fieldList.length; i++) {
|
||||
|
||||
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 (field.edit == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Hidden field
|
||||
if (field.type == 'hidden') {
|
||||
$editForm.append(self._createInputForHidden(fieldName, fieldValue));
|
||||
continue;
|
||||
}
|
||||
|
||||
//Create a container div for this input field and add to form
|
||||
var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($editForm);
|
||||
|
||||
//Create a label for input
|
||||
$fieldContainer.append(self._createInputLabelForRecordField(fieldName));
|
||||
|
||||
//Create input element with it's current value
|
||||
var currentValue = self._getValueForRecordField(record, fieldName);
|
||||
$fieldContainer.append(
|
||||
self._createInputForRecordField({
|
||||
fieldName: fieldName,
|
||||
value: currentValue,
|
||||
record: record,
|
||||
formType: 'edit',
|
||||
form: $editForm
|
||||
}));
|
||||
}
|
||||
|
||||
self._makeCascadeDropDowns($editForm, record, 'edit');
|
||||
|
||||
$editForm.submit(function () {
|
||||
self._onSaveClickedOnEditForm();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Open dialog
|
||||
self._$editingRow = $tableRow;
|
||||
self._$editDiv.append($editForm).dialog('open');
|
||||
self._trigger("formCreated", null, { form: $editForm, formType: 'edit', record: record, row: $tableRow });
|
||||
},
|
||||
|
||||
/* Saves editing form to the server and updates the record on the table.
|
||||
*************************************************************************/
|
||||
_saveEditForm: function ($editForm, $saveButton) {
|
||||
var self = this;
|
||||
|
||||
var completeEdit = function (data) {
|
||||
if (data.Result != 'OK') {
|
||||
self._showError(data.Message);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
return;
|
||||
}
|
||||
|
||||
var record = self._$editingRow.data('record');
|
||||
|
||||
self._updateRecordValuesFromForm(record, $editForm);
|
||||
self._updateRecordValuesFromServerResponse(record, data);
|
||||
self._updateRowTexts(self._$editingRow);
|
||||
|
||||
self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
|
||||
|
||||
self._onRecordUpdated(self._$editingRow, data);
|
||||
|
||||
if (self.options.animationsEnabled) {
|
||||
self._showUpdateAnimationForRow(self._$editingRow);
|
||||
}
|
||||
|
||||
self._$editDiv.dialog("close");
|
||||
};
|
||||
|
||||
|
||||
//updateAction may be a function, check if it is
|
||||
if ($.isFunction(self.options.actions.updateAction)) {
|
||||
|
||||
//Execute the function
|
||||
var funcResult = self.options.actions.updateAction($editForm.serialize());
|
||||
|
||||
//Check if result is a jQuery Deferred object
|
||||
if (self._isDeferredObject(funcResult)) {
|
||||
//Wait promise
|
||||
funcResult.done(function (data) {
|
||||
completeEdit(data);
|
||||
}).fail(function () {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
});
|
||||
} else { //assume it returned the creation result
|
||||
completeEdit(funcResult);
|
||||
}
|
||||
|
||||
} else { //Assume it's a URL string
|
||||
|
||||
//Make an Ajax call to update record
|
||||
self._submitFormUsingAjax(
|
||||
self.options.actions.updateAction,
|
||||
$editForm.serialize(),
|
||||
function(data) {
|
||||
completeEdit(data);
|
||||
},
|
||||
function() {
|
||||
self._showError(self.options.messages.serverCommunicationError);
|
||||
self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/* 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) {
|
||||
var field = this.options.fields[fieldName];
|
||||
var fieldValue = record[fieldName];
|
||||
if (field.type == 'date') {
|
||||
return this._getDisplayTextForDateRecordField(field, fieldValue);
|
||||
} else {
|
||||
return fieldValue;
|
||||
}
|
||||
},
|
||||
|
||||
/* Updates cells of a table row's text values from row's record values.
|
||||
*************************************************************************/
|
||||
_updateRowTexts: function ($tableRow) {
|
||||
var record = $tableRow.data('record');
|
||||
var $columns = $tableRow.find('td');
|
||||
for (var i = 0; i < this._columnList.length; i++) {
|
||||
var displayItem = this._getDisplayTextForRecordField(record, this._columnList[i]);
|
||||
if ((displayItem === 0)) displayItem = "0";
|
||||
$columns.eq(this._firstDataColumnOffset + i).html(displayItem || '');
|
||||
}
|
||||
|
||||
this._onRowUpdated($tableRow);
|
||||
},
|
||||
|
||||
/* Shows 'updated' animation for a table row.
|
||||
*************************************************************************/
|
||||
_showUpdateAnimationForRow: function ($tableRow) {
|
||||
var className = 'jtable-row-updated';
|
||||
if (this.options.jqueryuiTheme) {
|
||||
className = className + ' ui-state-highlight';
|
||||
}
|
||||
|
||||
$tableRow.stop(true, true).addClass(className, 'slow', '', function () {
|
||||
$tableRow.removeClass(className, 5000);
|
||||
});
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* EVENT RAISING METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
_onRowUpdated: function ($row) {
|
||||
this._trigger("rowUpdated", null, { row: $row, record: $row.data('record') });
|
||||
},
|
||||
|
||||
_onRecordUpdated: function ($row, data) {
|
||||
this._trigger("recordUpdated", null, { record: $row.data('record'), row: $row, serverResponse: data });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
483
jtable/dev/jquery.jtable.forms.js
Normal file
483
jtable/dev/jquery.jtable.forms.js
Normal file
|
@ -0,0 +1,483 @@
|
|||
/************************************************************************
|
||||
* FORMS extension for jTable (base for edit/create forms) *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Submits a form asynchronously using AJAX.
|
||||
* This method is needed, since form submitting logic can be overrided
|
||||
* by extensions.
|
||||
*************************************************************************/
|
||||
_submitFormUsingAjax: function (url, formData, 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 />')
|
||||
.addClass('jtable-input-label')
|
||||
.html(this.options.fields[fieldName].inputTitle || this.options.fields[fieldName].title);
|
||||
},
|
||||
|
||||
/* Creates an input element according to field type.
|
||||
*************************************************************************/
|
||||
_createInputForRecordField: function (funcParams) {
|
||||
var fieldName = funcParams.fieldName,
|
||||
value = funcParams.value,
|
||||
record = funcParams.record,
|
||||
formType = funcParams.formType,
|
||||
form = funcParams.form;
|
||||
|
||||
//Get the field
|
||||
var field = this.options.fields[fieldName];
|
||||
|
||||
//If value if not supplied, use defaultValue of the field
|
||||
if (value == undefined || value == null) {
|
||||
value = field.defaultValue;
|
||||
}
|
||||
|
||||
//Use custom function if supplied
|
||||
if (field.input) {
|
||||
var $input = $(field.input({
|
||||
value: value,
|
||||
record: record,
|
||||
formType: formType,
|
||||
form: form
|
||||
}));
|
||||
|
||||
//Add id attribute if does not exists
|
||||
if (!$input.attr('id')) {
|
||||
$input.attr('id', 'Edit-' + fieldName);
|
||||
}
|
||||
|
||||
//Wrap input element with div
|
||||
return $('<div />')
|
||||
.addClass('jtable-input jtable-custom-input')
|
||||
.append($input);
|
||||
}
|
||||
|
||||
//Create input according to field type
|
||||
if (field.type == 'date') {
|
||||
return this._createDateInputForField(field, fieldName, value);
|
||||
} else if (field.type == 'textarea') {
|
||||
return this._createTextAreaForField(field, fieldName, value);
|
||||
} else if (field.type == 'password') {
|
||||
return this._createPasswordInputForField(field, fieldName, value);
|
||||
} else if (field.type == 'checkbox') {
|
||||
return this._createCheckboxForField(field, fieldName, value);
|
||||
} else if (field.options) {
|
||||
if (field.type == 'radiobutton') {
|
||||
return this._createRadioButtonListForField(field, fieldName, value, record, formType);
|
||||
} else {
|
||||
return this._createDropDownListForField(field, fieldName, value, record, formType, form);
|
||||
}
|
||||
} else {
|
||||
return this._createTextInputForField(field, fieldName, value);
|
||||
}
|
||||
},
|
||||
|
||||
//Creates a hidden input element with given name and value.
|
||||
_createInputForHidden: function (fieldName, value) {
|
||||
if (value == undefined) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
return $('<input type="hidden" name="' + fieldName + '" id="Edit-' + fieldName + '"></input>')
|
||||
.val(value);
|
||||
},
|
||||
|
||||
/* Creates a date input for a field.
|
||||
*************************************************************************/
|
||||
_createDateInputForField: function (field, fieldName, value) {
|
||||
var $input = $('<input class="' + field.inputClass + '" id="Edit-' + fieldName + '" type="text" name="' + fieldName + '"></input>');
|
||||
if(value != undefined) {
|
||||
$input.val(value);
|
||||
}
|
||||
|
||||
var displayFormat = field.displayFormat || this.options.defaultDateFormat;
|
||||
$input.datepicker({ dateFormat: displayFormat });
|
||||
return $('<div />')
|
||||
.addClass('jtable-input jtable-date-input')
|
||||
.append($input);
|
||||
},
|
||||
|
||||
/* Creates a textarea element for a field.
|
||||
*************************************************************************/
|
||||
_createTextAreaForField: function (field, fieldName, value) {
|
||||
var $textArea = $('<textarea class="' + field.inputClass + '" id="Edit-' + fieldName + '" name="' + fieldName + '"></textarea>');
|
||||
if (value != undefined) {
|
||||
$textArea.val(value);
|
||||
}
|
||||
|
||||
return $('<div />')
|
||||
.addClass('jtable-input jtable-textarea-input')
|
||||
.append($textArea);
|
||||
},
|
||||
|
||||
/* Creates a standart textbox for a field.
|
||||
*************************************************************************/
|
||||
_createTextInputForField: function (field, fieldName, value) {
|
||||
var $input = $('<input class="' + field.inputClass + '" placeholder="' + field.placeholder + '" id="Edit-' + fieldName + '" type="text" name="' + fieldName + '"></input>');
|
||||
if (value != undefined) {
|
||||
$input.val(value);
|
||||
}
|
||||
|
||||
return $('<div />')
|
||||
.addClass('jtable-input jtable-text-input')
|
||||
.append($input);
|
||||
},
|
||||
|
||||
/* Creates a password input for a field.
|
||||
*************************************************************************/
|
||||
_createPasswordInputForField: function (field, fieldName, value) {
|
||||
var $input = $('<input class="' + field.inputClass + '" placeholder="' + field.placeholder + '" id="Edit-' + fieldName + '" type="password" name="' + fieldName + '"></input>');
|
||||
if (value != undefined) {
|
||||
$input.val(value);
|
||||
}
|
||||
|
||||
return $('<div />')
|
||||
.addClass('jtable-input jtable-password-input')
|
||||
.append($input);
|
||||
},
|
||||
|
||||
/* Creates a checkboxfor a field.
|
||||
*************************************************************************/
|
||||
_createCheckboxForField: function (field, fieldName, value) {
|
||||
var self = this;
|
||||
|
||||
//If value is undefined, get unchecked state's value
|
||||
if (value == undefined) {
|
||||
value = self._getCheckBoxPropertiesForFieldByState(fieldName, false).Value;
|
||||
}
|
||||
|
||||
//Create a container 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 + '" />')
|
||||
.appendTo($containerDiv);
|
||||
if (value != undefined) {
|
||||
$checkBox.val(value);
|
||||
}
|
||||
|
||||
//Create display text of checkbox for current state
|
||||
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)) {
|
||||
$checkBox.attr('checked', 'checked');
|
||||
}
|
||||
|
||||
//This method sets checkbox's value and text according to state of the checkbox
|
||||
var refreshCheckBoxValueAndText = function () {
|
||||
var checkboxProps = self._getCheckBoxPropertiesForFieldByState(fieldName, $checkBox.is(':checked'));
|
||||
$checkBox.attr('value', checkboxProps.Value);
|
||||
$textSpan.html(field.formText || checkboxProps.DisplayText);
|
||||
};
|
||||
|
||||
//Register to click event to change display text when state of checkbox is changed.
|
||||
$checkBox.click(function () {
|
||||
refreshCheckBoxValueAndText();
|
||||
});
|
||||
|
||||
//Change checkbox state when clicked to text
|
||||
if (field.setOnTextClick != false) {
|
||||
$textSpan
|
||||
.addClass('jtable-option-text-clickable')
|
||||
.click(function () {
|
||||
if ($checkBox.is(':checked')) {
|
||||
$checkBox.attr('checked', false);
|
||||
} else {
|
||||
$checkBox.attr('checked', true);
|
||||
}
|
||||
|
||||
refreshCheckBoxValueAndText();
|
||||
});
|
||||
}
|
||||
|
||||
return $containerDiv;
|
||||
},
|
||||
|
||||
/* Creates a drop down list (combobox) input element for a field.
|
||||
*************************************************************************/
|
||||
_createDropDownListForField: function (field, fieldName, value, record, source, form) {
|
||||
|
||||
//Create a container 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);
|
||||
|
||||
//add options
|
||||
var options = this._getOptionsForField(fieldName, {
|
||||
record: record,
|
||||
source: source,
|
||||
form: form,
|
||||
dependedValues: this._createDependedValuesUsingForm(form, field.dependsOn)
|
||||
});
|
||||
|
||||
this._fillDropDownListWithOptions($select, options, value);
|
||||
|
||||
return $containerDiv;
|
||||
},
|
||||
|
||||
/* Fills a dropdown list with given options.
|
||||
*************************************************************************/
|
||||
_fillDropDownListWithOptions: function ($select, options, value) {
|
||||
$select.empty();
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
$('<option' + (options[i].Value == value ? ' selected="selected"' : '') + '>' + options[i].DisplayText + '</option>')
|
||||
.val(options[i].Value)
|
||||
.appendTo($select);
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates depended values object from given form.
|
||||
*************************************************************************/
|
||||
_createDependedValuesUsingForm: function ($form, dependsOn) {
|
||||
if (!dependsOn) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var dependedValues = {};
|
||||
|
||||
for (var i = 0; i < dependsOn.length; i++) {
|
||||
var dependedField = dependsOn[i];
|
||||
|
||||
var $dependsOn = $form.find('select[name=' + dependedField + ']');
|
||||
if ($dependsOn.length <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dependedValues[dependedField] = $dependsOn.val();
|
||||
}
|
||||
|
||||
|
||||
return dependedValues;
|
||||
},
|
||||
|
||||
/* Creates a radio button list for a field.
|
||||
*************************************************************************/
|
||||
_createRadioButtonListForField: function (field, fieldName, value, record, source) {
|
||||
var $containerDiv = $('<div />')
|
||||
.addClass('jtable-input jtable-radiobuttonlist-input');
|
||||
|
||||
var options = this._getOptionsForField(fieldName, {
|
||||
record: record,
|
||||
source: source
|
||||
});
|
||||
|
||||
$.each(options, function(i, option) {
|
||||
var $radioButtonDiv = $('<div class=""></div>')
|
||||
.addClass('jtable-radio-input')
|
||||
.appendTo($containerDiv);
|
||||
|
||||
var $radioButton = $('<input type="radio" id="Edit-' + fieldName + '-' + i + '" class="' + field.inputClass + '" name="' + fieldName + '"' + ((option.Value == (value + '')) ? ' checked="true"' : '') + ' />')
|
||||
.val(option.Value)
|
||||
.appendTo($radioButtonDiv);
|
||||
|
||||
var $textSpan = $('<span></span>')
|
||||
.html(option.DisplayText)
|
||||
.appendTo($radioButtonDiv);
|
||||
|
||||
if (field.setOnTextClick != false) {
|
||||
$textSpan
|
||||
.addClass('jtable-option-text-clickable')
|
||||
.click(function () {
|
||||
if (!$radioButton.is(':checked')) {
|
||||
$radioButton.attr('checked', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return $containerDiv;
|
||||
},
|
||||
|
||||
/* Gets display text for a checkbox field.
|
||||
*************************************************************************/
|
||||
_getCheckBoxTextForFieldByValue: function (fieldName, value) {
|
||||
return this.options.fields[fieldName].values[value];
|
||||
},
|
||||
|
||||
/* Returns true if given field's value must be checked state.
|
||||
*************************************************************************/
|
||||
_getIsCheckBoxSelectedForFieldByValue: function (fieldName, value) {
|
||||
return (this._createCheckBoxStateArrayForFieldWithCaching(fieldName)[1].Value.toString() == value.toString());
|
||||
},
|
||||
|
||||
/* Gets an object for a checkbox field that has Value and DisplayText
|
||||
* properties.
|
||||
*************************************************************************/
|
||||
_getCheckBoxPropertiesForFieldByState: function (fieldName, checked) {
|
||||
return this._createCheckBoxStateArrayForFieldWithCaching(fieldName)[(checked ? 1 : 0)];
|
||||
},
|
||||
|
||||
/* Calls _createCheckBoxStateArrayForField with caching.
|
||||
*************************************************************************/
|
||||
_createCheckBoxStateArrayForFieldWithCaching: function (fieldName) {
|
||||
var cacheKey = 'checkbox_' + fieldName;
|
||||
if (!this._cache[cacheKey]) {
|
||||
|
||||
this._cache[cacheKey] = this._createCheckBoxStateArrayForField(fieldName);
|
||||
}
|
||||
|
||||
return this._cache[cacheKey];
|
||||
},
|
||||
|
||||
/* Creates a two element array of objects for states of a checkbox field.
|
||||
* First element for unchecked state, second for checked state.
|
||||
* Each object has two properties: Value and DisplayText
|
||||
*************************************************************************/
|
||||
_createCheckBoxStateArrayForField: function (fieldName) {
|
||||
var stateArray = [];
|
||||
var currentIndex = 0;
|
||||
$.each(this.options.fields[fieldName].values, function (propName, propValue) {
|
||||
if (currentIndex++ < 2) {
|
||||
stateArray.push({ 'Value': propName, 'DisplayText': propValue });
|
||||
}
|
||||
});
|
||||
|
||||
return stateArray;
|
||||
},
|
||||
|
||||
/* Searches a form for dependend dropdowns and makes them cascaded.
|
||||
*/
|
||||
_makeCascadeDropDowns: function ($form, record, source) {
|
||||
var self = this;
|
||||
|
||||
$form.find('select') //for each combobox
|
||||
.each(function () {
|
||||
var $thisDropdown = $(this);
|
||||
|
||||
//get field name
|
||||
var fieldName = $thisDropdown.attr('name');
|
||||
if (!fieldName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var field = self.options.fields[fieldName];
|
||||
|
||||
//check if this combobox depends on others
|
||||
if (!field.dependsOn) {
|
||||
return;
|
||||
}
|
||||
|
||||
//for each dependency
|
||||
$.each(field.dependsOn, function (index, dependsOnField) {
|
||||
//find the depended combobox
|
||||
var $dependsOnDropdown = $form.find('select[name=' + dependsOnField + ']');
|
||||
//when depended combobox changes
|
||||
$dependsOnDropdown.change(function () {
|
||||
|
||||
//Refresh options
|
||||
var funcParams = {
|
||||
record: record,
|
||||
source: source,
|
||||
form: $form,
|
||||
dependedValues: {}
|
||||
};
|
||||
funcParams.dependedValues = self._createDependedValuesUsingForm($form, field.dependsOn);
|
||||
var options = self._getOptionsForField(fieldName, funcParams);
|
||||
|
||||
//Fill combobox with new options
|
||||
self._fillDropDownListWithOptions($thisDropdown, options, undefined);
|
||||
|
||||
//Thigger change event to refresh multi cascade dropdowns.
|
||||
$thisDropdown.change();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* Updates values of a record from given form
|
||||
*************************************************************************/
|
||||
_updateRecordValuesFromForm: function (record, $form) {
|
||||
for (var i = 0; i < this._fieldList.length; i++) {
|
||||
var fieldName = this._fieldList[i];
|
||||
var field = this.options.fields[fieldName];
|
||||
|
||||
//Do not update non-editable fields
|
||||
if (field.edit == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Get field name and the input element of this field in the form
|
||||
var $inputElement = $form.find('[name="' + fieldName + '"]');
|
||||
if ($inputElement.length <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//Update field in record according to it's type
|
||||
if (field.type == 'date') {
|
||||
var dateVal = $inputElement.val();
|
||||
if (dateVal) {
|
||||
var displayFormat = field.displayFormat || this.options.defaultDateFormat;
|
||||
try {
|
||||
var date = $.datepicker.parseDate(displayFormat, dateVal);
|
||||
record[fieldName] = '/Date(' + date.getTime() + ')/';
|
||||
} catch (e) {
|
||||
//TODO: Handle incorrect/different date formats
|
||||
this._logWarn('Date format is incorrect for field ' + fieldName + ': ' + dateVal);
|
||||
record[fieldName] = undefined;
|
||||
}
|
||||
} else {
|
||||
this._logDebug('Date is empty for ' + fieldName);
|
||||
record[fieldName] = undefined; //TODO: undefined, null or empty string?
|
||||
}
|
||||
} else if (field.options && field.type == 'radiobutton') {
|
||||
var $checkedElement = $inputElement.filter(':checked');
|
||||
if ($checkedElement.length) {
|
||||
record[fieldName] = $checkedElement.val();
|
||||
} else {
|
||||
record[fieldName] = undefined;
|
||||
}
|
||||
} else {
|
||||
record[fieldName] = $inputElement.val();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* Sets enabled/disabled state of a dialog button.
|
||||
*************************************************************************/
|
||||
_setEnabledOfDialogButton: function ($button, enabled, buttonText) {
|
||||
if (!$button) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled != false) {
|
||||
$button
|
||||
.removeAttr('disabled')
|
||||
.removeClass('ui-state-disabled');
|
||||
} else {
|
||||
$button
|
||||
.attr('disabled', 'disabled')
|
||||
.addClass('ui-state-disabled');
|
||||
}
|
||||
|
||||
if (buttonText) {
|
||||
$button
|
||||
.find('span')
|
||||
.text(buttonText);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
28
jtable/dev/jquery.jtable.header.txt
Normal file
28
jtable/dev/jquery.jtable.header.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
|
||||
jTable 2.4.0
|
||||
http://www.jtable.org
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 2011-2014 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
171
jtable/dev/jquery.jtable.masterchild.js
Normal file
171
jtable/dev/jquery.jtable.masterchild.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
/************************************************************************
|
||||
* MASTER/CHILD tables extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
openChildAsAccordion: false
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PUBLIC METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Creates and opens a new child table for given row.
|
||||
*************************************************************************/
|
||||
openChildTable: function ($row, tableOptions, opened) {
|
||||
var self = this;
|
||||
|
||||
//Apply theming as same as parent table unless explicitily set
|
||||
if (tableOptions.jqueryuiTheme == undefined) {
|
||||
tableOptions.jqueryuiTheme = self.options.jqueryuiTheme;
|
||||
}
|
||||
|
||||
//Show close button as default
|
||||
tableOptions.showCloseButton = (tableOptions.showCloseButton != false);
|
||||
|
||||
//Close child table when close button is clicked (default behavior)
|
||||
if (tableOptions.showCloseButton && !tableOptions.closeRequested) {
|
||||
tableOptions.closeRequested = function () {
|
||||
self.closeChildTable($row);
|
||||
};
|
||||
}
|
||||
|
||||
//If accordion style, close open child table (if it does exists)
|
||||
if (self.options.openChildAsAccordion) {
|
||||
$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).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
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* Closes child table for given row.
|
||||
*************************************************************************/
|
||||
closeChildTable: function ($row, closed) {
|
||||
var self = this;
|
||||
|
||||
var $childRowColumn = this.getChildRow($row).children('td');
|
||||
var $childTable = $childRowColumn.data('childTable');
|
||||
if (!$childTable) {
|
||||
if (closed) {
|
||||
closed();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$childRowColumn.data('childTable', null);
|
||||
$childTable.slideUp('fast', function () {
|
||||
$childTable.jtable('destroy');
|
||||
$childTable.remove();
|
||||
self.closeChildRow($row);
|
||||
if (closed) {
|
||||
closed();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/* Returns a boolean value indicates that if a child row is open for given row.
|
||||
*************************************************************************/
|
||||
isChildRowOpen: function ($row) {
|
||||
return (this.getChildRow($row).is(':visible'));
|
||||
},
|
||||
|
||||
/* Gets child row for given row, opens it if it's closed (Creates if needed).
|
||||
*************************************************************************/
|
||||
getChildRow: function ($row) {
|
||||
return $row.data('childRow') || this._createChildRow($row);
|
||||
},
|
||||
|
||||
/* Creates and opens child row for given row.
|
||||
*************************************************************************/
|
||||
openChildRow: function ($row) {
|
||||
var $childRow = this.getChildRow($row);
|
||||
if (!$childRow.is(':visible')) {
|
||||
$childRow.show();
|
||||
}
|
||||
|
||||
return $childRow;
|
||||
},
|
||||
|
||||
/* Closes child row if it's open.
|
||||
*************************************************************************/
|
||||
closeChildRow: function ($row) {
|
||||
var $childRow = this.getChildRow($row);
|
||||
if ($childRow.is(':visible')) {
|
||||
$childRow.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides _removeRowsFromTable method to remove child rows of deleted rows.
|
||||
*************************************************************************/
|
||||
_removeRowsFromTable: function ($rows, reason) {
|
||||
//var self = this;
|
||||
|
||||
if (reason == 'deleted') {
|
||||
$rows.each(function () {
|
||||
var $row = $(this);
|
||||
var $childRow = $row.data('childRow');
|
||||
if ($childRow) {
|
||||
//self.closeChildTable($row); //Removed since it causes "Uncaught Error: cannot call methods on jtable prior to initialization; attempted to call method 'destroy'"
|
||||
$childRow.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
base._removeRowsFromTable.apply(this, arguments);
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Creates a child row for a row, hides and returns it.
|
||||
*************************************************************************/
|
||||
_createChildRow: function ($row) {
|
||||
var totalColumnCount = this._$table.find('thead th').length;
|
||||
var $childRow = $('<tr></tr>')
|
||||
.addClass('jtable-child-row')
|
||||
.append('<td colspan="' + totalColumnCount + '"></td>');
|
||||
$row.after($childRow);
|
||||
$row.data('childRow', $childRow);
|
||||
$childRow.hide();
|
||||
return $childRow;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
595
jtable/dev/jquery.jtable.paging.js
Normal file
595
jtable/dev/jquery.jtable.paging.js
Normal file
|
@ -0,0 +1,595 @@
|
|||
/************************************************************************
|
||||
* PAGING extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
load: $.hik.jtable.prototype.load,
|
||||
_create: $.hik.jtable.prototype._create,
|
||||
_setOption: $.hik.jtable.prototype._setOption,
|
||||
_createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
|
||||
_createJtParamsForLoading: $.hik.jtable.prototype._createJtParamsForLoading,
|
||||
_addRowToTable: $.hik.jtable.prototype._addRowToTable,
|
||||
_addRow: $.hik.jtable.prototype._addRow,
|
||||
_removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable,
|
||||
_onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
paging: false,
|
||||
pageList: 'normal', //possible values: 'minimal', 'normal'
|
||||
pageSize: 10,
|
||||
pageSizes: [10, 25, 50, 100, 250, 500],
|
||||
pageSizeChangeArea: true,
|
||||
gotoPageArea: 'combobox', //possible values: 'textbox', 'combobox', 'none'
|
||||
|
||||
messages: {
|
||||
pagingInfo: 'Showing {0}-{1} of {2}',
|
||||
pageSizeChangeLabel: 'Row count',
|
||||
gotoPageLabel: 'Go to page'
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_$bottomPanel: null, //Reference to the panel at the bottom of the table (jQuery object)
|
||||
_$pagingListArea: null, //Reference to the page list area in to bottom panel (jQuery object)
|
||||
_$pageSizeChangeArea: null, //Reference to the page size change area in to bottom panel (jQuery object)
|
||||
_$pageInfoSpan: null, //Reference to the paging info area in to bottom panel (jQuery object)
|
||||
_$gotoPageArea: null, //Reference to 'Go to page' input area in to bottom panel (jQuery object)
|
||||
_$gotoPageInput: null, //Reference to 'Go to page' input in to bottom panel (jQuery object)
|
||||
_totalRecordCount: 0, //Total count of records on all pages
|
||||
_currentPageNo: 1, //Current page number
|
||||
|
||||
/************************************************************************
|
||||
* CONSTRUCTOR AND INITIALIZING METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to do paging-specific constructions.
|
||||
*************************************************************************/
|
||||
_create: function() {
|
||||
base._create.apply(this, arguments);
|
||||
if (this.options.paging) {
|
||||
this._loadPagingSettings();
|
||||
this._createBottomPanel();
|
||||
this._createPageListArea();
|
||||
this._createGotoPageInput();
|
||||
this._createPageSizeSelection();
|
||||
}
|
||||
},
|
||||
|
||||
/* Loads user preferences for paging.
|
||||
*************************************************************************/
|
||||
_loadPagingSettings: function() {
|
||||
if (!this.options.saveUserPreferences) {
|
||||
return;
|
||||
}
|
||||
|
||||
var pageSize = this._getCookie('page-size');
|
||||
if (pageSize) {
|
||||
this.options.pageSize = this._normalizeNumber(pageSize, 1, 1000000, this.options.pageSize);
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates bottom panel and adds to the page.
|
||||
*************************************************************************/
|
||||
_createBottomPanel: function() {
|
||||
this._$bottomPanel = $('<div />')
|
||||
.addClass('jtable-bottom-panel')
|
||||
.insertAfter(this._$table);
|
||||
|
||||
this._jqueryuiThemeAddClass(this._$bottomPanel, 'ui-state-default');
|
||||
|
||||
$('<div />').addClass('jtable-left-area').appendTo(this._$bottomPanel);
|
||||
$('<div />').addClass('jtable-right-area').appendTo(this._$bottomPanel);
|
||||
},
|
||||
|
||||
/* Creates page list area.
|
||||
*************************************************************************/
|
||||
_createPageListArea: function() {
|
||||
this._$pagingListArea = $('<span></span>')
|
||||
.addClass('jtable-page-list')
|
||||
.appendTo(this._$bottomPanel.find('.jtable-left-area'));
|
||||
|
||||
this._$pageInfoSpan = $('<span></span>')
|
||||
.addClass('jtable-page-info')
|
||||
.appendTo(this._$bottomPanel.find('.jtable-right-area'));
|
||||
},
|
||||
|
||||
/* Creates page list change area.
|
||||
*************************************************************************/
|
||||
_createPageSizeSelection: function() {
|
||||
var self = this;
|
||||
|
||||
if (!self.options.pageSizeChangeArea) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Add current page size to page sizes list if not contains it
|
||||
if (self._findIndexInArray(self.options.pageSize, self.options.pageSizes) < 0) {
|
||||
self.options.pageSizes.push(parseInt(self.options.pageSize));
|
||||
self.options.pageSizes.sort(function(a, b) { return a - b; });
|
||||
}
|
||||
|
||||
//Add a span to contain page size change items
|
||||
self._$pageSizeChangeArea = $('<span></span>')
|
||||
.addClass('jtable-page-size-change')
|
||||
.appendTo(self._$bottomPanel.find('.jtable-left-area'));
|
||||
|
||||
//Page size label
|
||||
self._$pageSizeChangeArea.append('<span>' + self.options.messages.pageSizeChangeLabel + ': </span>');
|
||||
|
||||
//Page size change combobox
|
||||
var $pageSizeChangeCombobox = $('<select></select>').appendTo(self._$pageSizeChangeArea);
|
||||
|
||||
//Add page sizes to the combobox
|
||||
for (var i = 0; i < self.options.pageSizes.length; i++) {
|
||||
$pageSizeChangeCombobox.append('<option value="' + self.options.pageSizes[i] + '">' + self.options.pageSizes[i] + '</option>');
|
||||
}
|
||||
|
||||
//Select current page size
|
||||
$pageSizeChangeCombobox.val(self.options.pageSize);
|
||||
|
||||
//Change page size on combobox change
|
||||
$pageSizeChangeCombobox.change(function() {
|
||||
self._changePageSize(parseInt($(this).val()));
|
||||
});
|
||||
},
|
||||
|
||||
/* Creates go to page area.
|
||||
*************************************************************************/
|
||||
_createGotoPageInput: function() {
|
||||
var self = this;
|
||||
|
||||
if (!self.options.gotoPageArea || self.options.gotoPageArea == 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
//Add a span to contain goto page items
|
||||
this._$gotoPageArea = $('<span></span>')
|
||||
.addClass('jtable-goto-page')
|
||||
.appendTo(self._$bottomPanel.find('.jtable-left-area'));
|
||||
|
||||
//Goto page label
|
||||
this._$gotoPageArea.append('<span>' + self.options.messages.gotoPageLabel + ': </span>');
|
||||
|
||||
//Goto page input
|
||||
if (self.options.gotoPageArea == 'combobox') {
|
||||
|
||||
self._$gotoPageInput = $('<select></select>')
|
||||
.appendTo(this._$gotoPageArea)
|
||||
.data('pageCount', 1)
|
||||
.change(function() {
|
||||
self._changePage(parseInt($(this).val()));
|
||||
});
|
||||
self._$gotoPageInput.append('<option value="1">1</option>');
|
||||
|
||||
} else { //textbox
|
||||
|
||||
self._$gotoPageInput = $('<input type="text" maxlength="10" value="' + self._currentPageNo + '" />')
|
||||
.appendTo(this._$gotoPageArea)
|
||||
.keypress(function(event) {
|
||||
if (event.which == 13) { //enter
|
||||
event.preventDefault();
|
||||
self._changePage(parseInt(self._$gotoPageInput.val()));
|
||||
} else if (event.which == 43) { // +
|
||||
event.preventDefault();
|
||||
self._changePage(parseInt(self._$gotoPageInput.val()) + 1);
|
||||
} else if (event.which == 45) { // -
|
||||
event.preventDefault();
|
||||
self._changePage(parseInt(self._$gotoPageInput.val()) - 1);
|
||||
} else {
|
||||
//Allow only digits
|
||||
var isValid = (
|
||||
(47 < event.keyCode && event.keyCode < 58 && event.shiftKey == false && event.altKey == false)
|
||||
|| (event.keyCode == 8)
|
||||
|| (event.keyCode == 9)
|
||||
);
|
||||
|
||||
if (!isValid) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/* Refreshes the 'go to page' input.
|
||||
*************************************************************************/
|
||||
_refreshGotoPageInput: function() {
|
||||
if (!this.options.gotoPageArea || this.options.gotoPageArea == 'none') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._totalRecordCount <= 0) {
|
||||
this._$gotoPageArea.hide();
|
||||
} else {
|
||||
this._$gotoPageArea.show();
|
||||
}
|
||||
|
||||
if (this.options.gotoPageArea == 'combobox') {
|
||||
var oldPageCount = this._$gotoPageInput.data('pageCount');
|
||||
var currentPageCount = this._calculatePageCount();
|
||||
if (oldPageCount != currentPageCount) {
|
||||
this._$gotoPageInput.empty();
|
||||
|
||||
//Skip some pages is there are too many pages
|
||||
var pageStep = 1;
|
||||
if (currentPageCount > 10000) {
|
||||
pageStep = 100;
|
||||
} else if (currentPageCount > 5000) {
|
||||
pageStep = 10;
|
||||
} else if (currentPageCount > 2000) {
|
||||
pageStep = 5;
|
||||
} else if (currentPageCount > 1000) {
|
||||
pageStep = 2;
|
||||
}
|
||||
|
||||
for (var i = pageStep; i <= currentPageCount; i += pageStep) {
|
||||
this._$gotoPageInput.append('<option value="' + i + '">' + i + '</option>');
|
||||
}
|
||||
|
||||
this._$gotoPageInput.data('pageCount', currentPageCount);
|
||||
}
|
||||
}
|
||||
|
||||
//same for 'textbox' and 'combobox'
|
||||
this._$gotoPageInput.val(this._currentPageNo);
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides load method to set current page to 1.
|
||||
*************************************************************************/
|
||||
load: function() {
|
||||
this._currentPageNo = 1;
|
||||
|
||||
base.load.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Used to change options dynamically after initialization.
|
||||
*************************************************************************/
|
||||
_setOption: function(key, value) {
|
||||
base._setOption.apply(this, arguments);
|
||||
|
||||
if (key == 'pageSize') {
|
||||
this._changePageSize(parseInt(value));
|
||||
}
|
||||
},
|
||||
|
||||
/* Changes current page size with given value.
|
||||
*************************************************************************/
|
||||
_changePageSize: function(pageSize) {
|
||||
if (pageSize == this.options.pageSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.options.pageSize = pageSize;
|
||||
|
||||
//Normalize current page
|
||||
var pageCount = this._calculatePageCount();
|
||||
if (this._currentPageNo > pageCount) {
|
||||
this._currentPageNo = pageCount;
|
||||
}
|
||||
if (this._currentPageNo <= 0) {
|
||||
this._currentPageNo = 1;
|
||||
}
|
||||
|
||||
//if user sets one of the options on the combobox, then select it.
|
||||
var $pageSizeChangeCombobox = this._$bottomPanel.find('.jtable-page-size-change select');
|
||||
if ($pageSizeChangeCombobox.length > 0) {
|
||||
if (parseInt($pageSizeChangeCombobox.val()) != pageSize) {
|
||||
var selectedOption = $pageSizeChangeCombobox.find('option[value=' + pageSize + ']');
|
||||
if (selectedOption.length > 0) {
|
||||
$pageSizeChangeCombobox.val(pageSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._savePagingSettings();
|
||||
this._reloadTable();
|
||||
},
|
||||
|
||||
/* Saves user preferences for paging
|
||||
*************************************************************************/
|
||||
_savePagingSettings: function() {
|
||||
if (!this.options.saveUserPreferences) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setCookie('page-size', this.options.pageSize);
|
||||
},
|
||||
|
||||
/* Overrides _createRecordLoadUrl method to add paging info to URL.
|
||||
*************************************************************************/
|
||||
_createRecordLoadUrl: function() {
|
||||
var loadUrl = base._createRecordLoadUrl.apply(this, arguments);
|
||||
loadUrl = this._addPagingInfoToUrl(loadUrl, this._currentPageNo);
|
||||
return loadUrl;
|
||||
},
|
||||
|
||||
/* Overrides _createJtParamsForLoading method to add paging parameters to jtParams object.
|
||||
*************************************************************************/
|
||||
_createJtParamsForLoading: function () {
|
||||
var jtParams = base._createJtParamsForLoading.apply(this, arguments);
|
||||
|
||||
if (this.options.paging) {
|
||||
jtParams.jtStartIndex = (this._currentPageNo - 1) * this.options.pageSize;
|
||||
jtParams.jtPageSize = this.options.pageSize;
|
||||
}
|
||||
|
||||
return jtParams;
|
||||
},
|
||||
|
||||
/* 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) {
|
||||
this._reloadTable();
|
||||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
*************************************************************************/
|
||||
_removeRowsFromTable: function ($rows, reason) {
|
||||
base._removeRowsFromTable.apply(this, arguments);
|
||||
|
||||
if (this.options.paging) {
|
||||
if (this._$tableRows.length <= 0 && this._currentPageNo > 1) {
|
||||
--this._currentPageNo;
|
||||
}
|
||||
|
||||
this._reloadTable();
|
||||
}
|
||||
},
|
||||
|
||||
/* Overrides _onRecordsLoaded method to to do paging specific tasks.
|
||||
*************************************************************************/
|
||||
_onRecordsLoaded: function (data) {
|
||||
if (this.options.paging) {
|
||||
this._totalRecordCount = data.TotalRecordCount;
|
||||
this._createPagingList();
|
||||
this._createPagingInfo();
|
||||
this._refreshGotoPageInput();
|
||||
}
|
||||
|
||||
base._onRecordsLoaded.apply(this, arguments);
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Adds jtStartIndex and jtPageSize parameters to a URL as query string.
|
||||
*************************************************************************/
|
||||
_addPagingInfoToUrl: function (url, pageNumber) {
|
||||
if (!this.options.paging) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var jtStartIndex = (pageNumber - 1) * this.options.pageSize;
|
||||
var jtPageSize = this.options.pageSize;
|
||||
|
||||
return (url + (url.indexOf('?') < 0 ? '?' : '&') + 'jtStartIndex=' + jtStartIndex + '&jtPageSize=' + jtPageSize);
|
||||
},
|
||||
|
||||
/* Creates and shows the page list.
|
||||
*************************************************************************/
|
||||
_createPagingList: function () {
|
||||
if (this.options.pageSize <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._$pagingListArea.empty();
|
||||
if (this._totalRecordCount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var pageCount = this._calculatePageCount();
|
||||
|
||||
this._createFirstAndPreviousPageButtons();
|
||||
if (this.options.pageList == 'normal') {
|
||||
this._createPageNumberButtons(this._calculatePageNumbers(pageCount));
|
||||
}
|
||||
this._createLastAndNextPageButtons(pageCount);
|
||||
this._bindClickEventsToPageNumberButtons();
|
||||
},
|
||||
|
||||
/* Creates and shows previous and first page links.
|
||||
*************************************************************************/
|
||||
_createFirstAndPreviousPageButtons: function () {
|
||||
var $first = $('<span></span>')
|
||||
.addClass('jtable-page-number-first')
|
||||
.html('<<')
|
||||
.data('pageNumber', 1)
|
||||
.appendTo(this._$pagingListArea);
|
||||
|
||||
var $previous = $('<span></span>')
|
||||
.addClass('jtable-page-number-previous')
|
||||
.html('<')
|
||||
.data('pageNumber', this._currentPageNo - 1)
|
||||
.appendTo(this._$pagingListArea);
|
||||
|
||||
this._jqueryuiThemeAddClass($first, 'ui-button ui-state-default', 'ui-state-hover');
|
||||
this._jqueryuiThemeAddClass($previous, 'ui-button ui-state-default', 'ui-state-hover');
|
||||
|
||||
if (this._currentPageNo <= 1) {
|
||||
$first.addClass('jtable-page-number-disabled');
|
||||
$previous.addClass('jtable-page-number-disabled');
|
||||
this._jqueryuiThemeAddClass($first, 'ui-state-disabled');
|
||||
this._jqueryuiThemeAddClass($previous, 'ui-state-disabled');
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates and shows next and last page links.
|
||||
*************************************************************************/
|
||||
_createLastAndNextPageButtons: function (pageCount) {
|
||||
var $next = $('<span></span>')
|
||||
.addClass('jtable-page-number-next')
|
||||
.html('>')
|
||||
.data('pageNumber', this._currentPageNo + 1)
|
||||
.appendTo(this._$pagingListArea);
|
||||
var $last = $('<span></span>')
|
||||
.addClass('jtable-page-number-last')
|
||||
.html('>>')
|
||||
.data('pageNumber', pageCount)
|
||||
.appendTo(this._$pagingListArea);
|
||||
|
||||
this._jqueryuiThemeAddClass($next, 'ui-button ui-state-default', 'ui-state-hover');
|
||||
this._jqueryuiThemeAddClass($last, 'ui-button ui-state-default', 'ui-state-hover');
|
||||
|
||||
if (this._currentPageNo >= pageCount) {
|
||||
$next.addClass('jtable-page-number-disabled');
|
||||
$last.addClass('jtable-page-number-disabled');
|
||||
this._jqueryuiThemeAddClass($next, 'ui-state-disabled');
|
||||
this._jqueryuiThemeAddClass($last, 'ui-state-disabled');
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates and shows page number links for given number array.
|
||||
*************************************************************************/
|
||||
_createPageNumberButtons: function (pageNumbers) {
|
||||
var previousNumber = 0;
|
||||
for (var i = 0; i < pageNumbers.length; i++) {
|
||||
//Create "..." between page numbers if needed
|
||||
if ((pageNumbers[i] - previousNumber) > 1) {
|
||||
$('<span></span>')
|
||||
.addClass('jtable-page-number-space')
|
||||
.html('...')
|
||||
.appendTo(this._$pagingListArea);
|
||||
}
|
||||
|
||||
this._createPageNumberButton(pageNumbers[i]);
|
||||
previousNumber = pageNumbers[i];
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates a page number link and adds to paging area.
|
||||
*************************************************************************/
|
||||
_createPageNumberButton: function (pageNumber) {
|
||||
var $pageNumber = $('<span></span>')
|
||||
.addClass('jtable-page-number')
|
||||
.html(pageNumber)
|
||||
.data('pageNumber', pageNumber)
|
||||
.appendTo(this._$pagingListArea);
|
||||
|
||||
this._jqueryuiThemeAddClass($pageNumber, 'ui-button ui-state-default', 'ui-state-hover');
|
||||
|
||||
if (this._currentPageNo == pageNumber) {
|
||||
$pageNumber.addClass('jtable-page-number-active jtable-page-number-disabled');
|
||||
this._jqueryuiThemeAddClass($pageNumber, 'ui-state-active');
|
||||
}
|
||||
},
|
||||
|
||||
/* Calculates total page count according to page size and total record count.
|
||||
*************************************************************************/
|
||||
_calculatePageCount: function () {
|
||||
var pageCount = Math.floor(this._totalRecordCount / this.options.pageSize);
|
||||
if (this._totalRecordCount % this.options.pageSize != 0) {
|
||||
++pageCount;
|
||||
}
|
||||
|
||||
return pageCount;
|
||||
},
|
||||
|
||||
/* Calculates page numbers and returns an array of these numbers.
|
||||
*************************************************************************/
|
||||
_calculatePageNumbers: function (pageCount) {
|
||||
if (pageCount <= 4) {
|
||||
//Show all pages
|
||||
var pageNumbers = [];
|
||||
for (var i = 1; i <= pageCount; ++i) {
|
||||
pageNumbers.push(i);
|
||||
}
|
||||
|
||||
return pageNumbers;
|
||||
} else {
|
||||
//show first three, last three, current, previous and next page numbers
|
||||
var shownPageNumbers = [1, 2, pageCount - 1, pageCount];
|
||||
var previousPageNo = this._normalizeNumber(this._currentPageNo - 1, 1, pageCount, 1);
|
||||
var nextPageNo = this._normalizeNumber(this._currentPageNo + 1, 1, pageCount, 1);
|
||||
|
||||
this._insertToArrayIfDoesNotExists(shownPageNumbers, previousPageNo);
|
||||
this._insertToArrayIfDoesNotExists(shownPageNumbers, this._currentPageNo);
|
||||
this._insertToArrayIfDoesNotExists(shownPageNumbers, nextPageNo);
|
||||
|
||||
shownPageNumbers.sort(function (a, b) { return a - b; });
|
||||
return shownPageNumbers;
|
||||
}
|
||||
},
|
||||
|
||||
/* Creates and shows paging informations.
|
||||
*************************************************************************/
|
||||
_createPagingInfo: function () {
|
||||
if (this._totalRecordCount <= 0) {
|
||||
this._$pageInfoSpan.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
var startNo = (this._currentPageNo - 1) * this.options.pageSize + 1;
|
||||
var endNo = this._currentPageNo * this.options.pageSize;
|
||||
endNo = this._normalizeNumber(endNo, startNo, this._totalRecordCount, 0);
|
||||
|
||||
if (endNo >= startNo) {
|
||||
var pagingInfoMessage = this._formatString(this.options.messages.pagingInfo, startNo, endNo, this._totalRecordCount);
|
||||
this._$pageInfoSpan.html(pagingInfoMessage);
|
||||
}
|
||||
},
|
||||
|
||||
/* Binds click events of all page links to change the page.
|
||||
*************************************************************************/
|
||||
_bindClickEventsToPageNumberButtons: function () {
|
||||
var self = this;
|
||||
self._$pagingListArea
|
||||
.find('.jtable-page-number,.jtable-page-number-previous,.jtable-page-number-next,.jtable-page-number-first,.jtable-page-number-last')
|
||||
.not('.jtable-page-number-disabled')
|
||||
.click(function (e) {
|
||||
e.preventDefault();
|
||||
self._changePage($(this).data('pageNumber'));
|
||||
});
|
||||
},
|
||||
|
||||
/* Changes current page to given value.
|
||||
*************************************************************************/
|
||||
_changePage: function (pageNo) {
|
||||
pageNo = this._normalizeNumber(pageNo, 1, this._calculatePageCount(), 1);
|
||||
if (pageNo == this._currentPageNo) {
|
||||
this._refreshGotoPageInput();
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentPageNo = pageNo;
|
||||
this._reloadTable();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
382
jtable/dev/jquery.jtable.selecting.js
Normal file
382
jtable/dev/jquery.jtable.selecting.js
Normal file
|
@ -0,0 +1,382 @@
|
|||
/************************************************************************
|
||||
* SELECTING extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_create: $.hik.jtable.prototype._create,
|
||||
_addColumnsToHeaderRow: $.hik.jtable.prototype._addColumnsToHeaderRow,
|
||||
_addCellsToRowUsingRecord: $.hik.jtable.prototype._addCellsToRowUsingRecord,
|
||||
_onLoadingRecords: $.hik.jtable.prototype._onLoadingRecords,
|
||||
_onRecordsLoaded: $.hik.jtable.prototype._onRecordsLoaded,
|
||||
_onRowsRemoved: $.hik.jtable.prototype._onRowsRemoved
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
|
||||
//Options
|
||||
selecting: false,
|
||||
multiselect: false,
|
||||
selectingCheckboxes: false,
|
||||
selectOnRowClick: true,
|
||||
|
||||
//Events
|
||||
selectionChanged: function (event, data) { }
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_selectedRecordIdsBeforeLoad: null, //This array is used to store selected row Id's to restore them after a page refresh (string array).
|
||||
_$selectAllCheckbox: null, //Reference to the 'select/deselect all' checkbox (jQuery object)
|
||||
_shiftKeyDown: false, //True, if shift key is currently down.
|
||||
|
||||
/************************************************************************
|
||||
* CONSTRUCTOR *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to do selecting-specific constructions.
|
||||
*************************************************************************/
|
||||
_create: function () {
|
||||
if (this.options.selecting && this.options.selectingCheckboxes) {
|
||||
++this._firstDataColumnOffset;
|
||||
this._bindKeyboardEvents();
|
||||
}
|
||||
|
||||
//Call base method
|
||||
base._create.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Registers to keyboard events those are needed for selection
|
||||
*************************************************************************/
|
||||
_bindKeyboardEvents: function () {
|
||||
var self = this;
|
||||
//Register to events to set _shiftKeyDown value
|
||||
$(document)
|
||||
.keydown(function (event) {
|
||||
switch (event.which) {
|
||||
case 16:
|
||||
self._shiftKeyDown = true;
|
||||
break;
|
||||
}
|
||||
})
|
||||
.keyup(function (event) {
|
||||
switch (event.which) {
|
||||
case 16:
|
||||
self._shiftKeyDown = false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PUBLIC METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Gets jQuery selection for currently selected rows.
|
||||
*************************************************************************/
|
||||
selectedRows: function () {
|
||||
return this._getSelectedRows();
|
||||
},
|
||||
|
||||
/* Makes row/rows 'selected'.
|
||||
*************************************************************************/
|
||||
selectRows: function ($rows) {
|
||||
this._selectRows($rows);
|
||||
this._onSelectionChanged(); //TODO: trigger only if selected rows changes?
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to add a 'select column' to header row.
|
||||
*************************************************************************/
|
||||
_addColumnsToHeaderRow: function ($tr) {
|
||||
if (this.options.selecting && this.options.selectingCheckboxes) {
|
||||
if (this.options.multiselect) {
|
||||
$tr.append(this._createSelectAllHeader());
|
||||
} else {
|
||||
$tr.append(this._createEmptyCommandHeader());
|
||||
}
|
||||
}
|
||||
|
||||
base._addColumnsToHeaderRow.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Overrides base method to add a 'delete command cell' to a row.
|
||||
*************************************************************************/
|
||||
_addCellsToRowUsingRecord: function ($row) {
|
||||
if (this.options.selecting) {
|
||||
this._makeRowSelectable($row);
|
||||
}
|
||||
|
||||
base._addCellsToRowUsingRecord.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Overrides base event to store selection list
|
||||
*************************************************************************/
|
||||
_onLoadingRecords: function () {
|
||||
if (this.options.selecting) {
|
||||
this._storeSelectionList();
|
||||
}
|
||||
|
||||
base._onLoadingRecords.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Overrides base event to restore selection list
|
||||
*************************************************************************/
|
||||
_onRecordsLoaded: function () {
|
||||
if (this.options.selecting) {
|
||||
this._restoreSelectionList();
|
||||
}
|
||||
|
||||
base._onRecordsLoaded.apply(this, arguments);
|
||||
},
|
||||
|
||||
/* Overrides base event to check is any selected row is being removed.
|
||||
*************************************************************************/
|
||||
_onRowsRemoved: function ($rows, reason) {
|
||||
if (this.options.selecting && (reason != 'reloading') && ($rows.filter('.jtable-row-selected').length > 0)) {
|
||||
this._onSelectionChanged();
|
||||
}
|
||||
|
||||
base._onRowsRemoved.apply(this, arguments);
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Creates a header column to select/deselect all rows.
|
||||
*************************************************************************/
|
||||
_createSelectAllHeader: function () {
|
||||
var self = this;
|
||||
|
||||
var $columnHeader = $('<th class=""></th>')
|
||||
.addClass('jtable-command-column-header jtable-column-header-selecting');
|
||||
this._jqueryuiThemeAddClass($columnHeader, 'ui-state-default');
|
||||
|
||||
var $headerContainer = $('<div />')
|
||||
.addClass('jtable-column-header-container')
|
||||
.appendTo($columnHeader);
|
||||
|
||||
self._$selectAllCheckbox = $('<input type="checkbox" />')
|
||||
.appendTo($headerContainer)
|
||||
.click(function () {
|
||||
if (self._$tableRows.length <= 0) {
|
||||
self._$selectAllCheckbox.attr('checked', false);
|
||||
return;
|
||||
}
|
||||
|
||||
var allRows = self._$tableBody.find('>tr.jtable-data-row');
|
||||
if (self._$selectAllCheckbox.is(':checked')) {
|
||||
self._selectRows(allRows);
|
||||
} else {
|
||||
self._deselectRows(allRows);
|
||||
}
|
||||
|
||||
self._onSelectionChanged();
|
||||
});
|
||||
|
||||
return $columnHeader;
|
||||
},
|
||||
|
||||
/* Stores Id's of currently selected records to _selectedRecordIdsBeforeLoad.
|
||||
*************************************************************************/
|
||||
_storeSelectionList: function () {
|
||||
var self = this;
|
||||
|
||||
if (!self.options.selecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
self._selectedRecordIdsBeforeLoad = [];
|
||||
self._getSelectedRows().each(function () {
|
||||
self._selectedRecordIdsBeforeLoad.push(self._getKeyValueOfRecord($(this).data('record')));
|
||||
});
|
||||
},
|
||||
|
||||
/* Selects rows whose Id is in _selectedRecordIdsBeforeLoad;
|
||||
*************************************************************************/
|
||||
_restoreSelectionList: function () {
|
||||
var self = this;
|
||||
|
||||
if (!self.options.selecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedRowCount = 0;
|
||||
for (var i = 0; i < self._$tableRows.length; ++i) {
|
||||
var recordId = self._getKeyValueOfRecord(self._$tableRows[i].data('record'));
|
||||
if ($.inArray(recordId, self._selectedRecordIdsBeforeLoad) > -1) {
|
||||
self._selectRows(self._$tableRows[i]);
|
||||
++selectedRowCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (self._selectedRecordIdsBeforeLoad.length > 0 && self._selectedRecordIdsBeforeLoad.length != selectedRowCount) {
|
||||
self._onSelectionChanged();
|
||||
}
|
||||
|
||||
self._selectedRecordIdsBeforeLoad = [];
|
||||
self._refreshSelectAllCheckboxState();
|
||||
},
|
||||
|
||||
/* Gets all selected rows.
|
||||
*************************************************************************/
|
||||
_getSelectedRows: function () {
|
||||
return this._$tableBody
|
||||
.find('>tr.jtable-row-selected');
|
||||
},
|
||||
|
||||
/* Adds selectable feature to a row.
|
||||
*************************************************************************/
|
||||
_makeRowSelectable: function ($row) {
|
||||
var self = this;
|
||||
|
||||
//Select/deselect on row click
|
||||
if (self.options.selectOnRowClick) {
|
||||
$row.click(function () {
|
||||
self._invertRowSelection($row);
|
||||
});
|
||||
}
|
||||
|
||||
//'select/deselect' checkbox column
|
||||
if (self.options.selectingCheckboxes) {
|
||||
var $cell = $('<td></td>').addClass('jtable-selecting-column');
|
||||
var $selectCheckbox = $('<input type="checkbox" />').appendTo($cell);
|
||||
if (!self.options.selectOnRowClick) {
|
||||
$selectCheckbox.click(function () {
|
||||
self._invertRowSelection($row);
|
||||
});
|
||||
}
|
||||
|
||||
$row.append($cell);
|
||||
}
|
||||
},
|
||||
|
||||
/* Inverts selection state of a single row.
|
||||
*************************************************************************/
|
||||
_invertRowSelection: function ($row) {
|
||||
if ($row.hasClass('jtable-row-selected')) {
|
||||
this._deselectRows($row);
|
||||
} else {
|
||||
//Shift key?
|
||||
if (this._shiftKeyDown) {
|
||||
var rowIndex = this._findRowIndex($row);
|
||||
//try to select row and above rows until first selected row
|
||||
var beforeIndex = this._findFirstSelectedRowIndexBeforeIndex(rowIndex) + 1;
|
||||
if (beforeIndex > 0 && beforeIndex < rowIndex) {
|
||||
this._selectRows(this._$tableBody.find('tr').slice(beforeIndex, rowIndex + 1));
|
||||
} else {
|
||||
//try to select row and below rows until first selected row
|
||||
var afterIndex = this._findFirstSelectedRowIndexAfterIndex(rowIndex) - 1;
|
||||
if (afterIndex > rowIndex) {
|
||||
this._selectRows(this._$tableBody.find('tr').slice(rowIndex, afterIndex + 1));
|
||||
} else {
|
||||
//just select this row
|
||||
this._selectRows($row);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this._selectRows($row);
|
||||
}
|
||||
}
|
||||
|
||||
this._onSelectionChanged();
|
||||
},
|
||||
|
||||
/* Search for a selected row (that is before given row index) to up and returns it's index
|
||||
*************************************************************************/
|
||||
_findFirstSelectedRowIndexBeforeIndex: function (rowIndex) {
|
||||
for (var i = rowIndex - 1; i >= 0; --i) {
|
||||
if (this._$tableRows[i].hasClass('jtable-row-selected')) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
},
|
||||
|
||||
/* Search for a selected row (that is after given row index) to down and returns it's index
|
||||
*************************************************************************/
|
||||
_findFirstSelectedRowIndexAfterIndex: function (rowIndex) {
|
||||
for (var i = rowIndex + 1; i < this._$tableRows.length; ++i) {
|
||||
if (this._$tableRows[i].hasClass('jtable-row-selected')) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
},
|
||||
|
||||
/* Makes row/rows 'selected'.
|
||||
*************************************************************************/
|
||||
_selectRows: function ($rows) {
|
||||
if (!this.options.multiselect) {
|
||||
this._deselectRows(this._getSelectedRows());
|
||||
}
|
||||
|
||||
$rows.addClass('jtable-row-selected');
|
||||
this._jqueryuiThemeAddClass($rows, 'ui-state-highlight');
|
||||
|
||||
if (this.options.selectingCheckboxes) {
|
||||
$rows.find('>td.jtable-selecting-column >input').prop('checked', true);
|
||||
}
|
||||
|
||||
this._refreshSelectAllCheckboxState();
|
||||
},
|
||||
|
||||
/* Makes row/rows 'non selected'.
|
||||
*************************************************************************/
|
||||
_deselectRows: function ($rows) {
|
||||
$rows.removeClass('jtable-row-selected ui-state-highlight');
|
||||
if (this.options.selectingCheckboxes) {
|
||||
$rows.find('>td.jtable-selecting-column >input').prop('checked', false);
|
||||
}
|
||||
|
||||
this._refreshSelectAllCheckboxState();
|
||||
},
|
||||
|
||||
/* Updates state of the 'select/deselect' all checkbox according to count of selected rows.
|
||||
*************************************************************************/
|
||||
_refreshSelectAllCheckboxState: function () {
|
||||
if (!this.options.selectingCheckboxes || !this.options.multiselect) {
|
||||
return;
|
||||
}
|
||||
|
||||
var totalRowCount = this._$tableRows.length;
|
||||
var selectedRowCount = this._getSelectedRows().length;
|
||||
|
||||
if (selectedRowCount == 0) {
|
||||
this._$selectAllCheckbox.prop('indeterminate', false);
|
||||
this._$selectAllCheckbox.attr('checked', false);
|
||||
} else if (selectedRowCount == totalRowCount) {
|
||||
this._$selectAllCheckbox.prop('indeterminate', false);
|
||||
this._$selectAllCheckbox.attr('checked', true);
|
||||
} else {
|
||||
this._$selectAllCheckbox.attr('checked', false);
|
||||
this._$selectAllCheckbox.prop('indeterminate', true);
|
||||
}
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* EVENT RAISING METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
_onSelectionChanged: function () {
|
||||
this._trigger("selectionChanged", null, {});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
202
jtable/dev/jquery.jtable.sorting.js
Normal file
202
jtable/dev/jquery.jtable.sorting.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
/************************************************************************
|
||||
* SORTING extension for jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
//Reference to base object members
|
||||
var base = {
|
||||
_initializeFields: $.hik.jtable.prototype._initializeFields,
|
||||
_normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
|
||||
_createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
|
||||
_createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
|
||||
_createJtParamsForLoading: $.hik.jtable.prototype._createJtParamsForLoading
|
||||
};
|
||||
|
||||
//extension members
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/************************************************************************
|
||||
* DEFAULT OPTIONS / EVENTS *
|
||||
*************************************************************************/
|
||||
options: {
|
||||
sorting: false,
|
||||
multiSorting: false,
|
||||
defaultSorting: ''
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE FIELDS *
|
||||
*************************************************************************/
|
||||
|
||||
_lastSorting: null, //Last sorting of the table
|
||||
|
||||
/************************************************************************
|
||||
* OVERRIDED METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Overrides base method to create sorting array.
|
||||
*************************************************************************/
|
||||
_initializeFields: function () {
|
||||
base._initializeFields.apply(this, arguments);
|
||||
|
||||
this._lastSorting = [];
|
||||
if (this.options.sorting) {
|
||||
this._buildDefaultSortingArray();
|
||||
}
|
||||
},
|
||||
|
||||
/* Overrides _normalizeFieldOptions method to normalize sorting option for fields.
|
||||
*************************************************************************/
|
||||
_normalizeFieldOptions: function (fieldName, props) {
|
||||
base._normalizeFieldOptions.apply(this, arguments);
|
||||
props.sorting = (props.sorting != false);
|
||||
},
|
||||
|
||||
/* Overrides _createHeaderCellForField to make columns sortable.
|
||||
*************************************************************************/
|
||||
_createHeaderCellForField: function (fieldName, field) {
|
||||
var $headerCell = base._createHeaderCellForField.apply(this, arguments);
|
||||
if (this.options.sorting && field.sorting) {
|
||||
this._makeColumnSortable($headerCell, fieldName);
|
||||
}
|
||||
|
||||
return $headerCell;
|
||||
},
|
||||
|
||||
/* Overrides _createRecordLoadUrl to add sorting specific info to URL.
|
||||
*************************************************************************/
|
||||
_createRecordLoadUrl: function () {
|
||||
var loadUrl = base._createRecordLoadUrl.apply(this, arguments);
|
||||
loadUrl = this._addSortingInfoToUrl(loadUrl);
|
||||
return loadUrl;
|
||||
},
|
||||
|
||||
/************************************************************************
|
||||
* PRIVATE METHODS *
|
||||
*************************************************************************/
|
||||
|
||||
/* Builds the sorting array according to defaultSorting string
|
||||
*************************************************************************/
|
||||
_buildDefaultSortingArray: function () {
|
||||
var self = this;
|
||||
|
||||
$.each(self.options.defaultSorting.split(","), function (orderIndex, orderValue) {
|
||||
$.each(self.options.fields, function (fieldName, fieldProps) {
|
||||
if (fieldProps.sorting) {
|
||||
var colOffset = orderValue.indexOf(fieldName);
|
||||
if (colOffset > -1) {
|
||||
if (orderValue.toUpperCase().indexOf(' DESC', colOffset) > -1) {
|
||||
self._lastSorting.push({
|
||||
fieldName: fieldName,
|
||||
sortOrder: 'DESC'
|
||||
});
|
||||
} else {
|
||||
self._lastSorting.push({
|
||||
fieldName: fieldName,
|
||||
sortOrder: 'ASC'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/* Makes a column sortable.
|
||||
*************************************************************************/
|
||||
_makeColumnSortable: function ($columnHeader, fieldName) {
|
||||
var self = this;
|
||||
|
||||
$columnHeader
|
||||
.addClass('jtable-column-header-sortable')
|
||||
.click(function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (!self.options.multiSorting || !e.ctrlKey) {
|
||||
self._lastSorting = []; //clear previous sorting
|
||||
}
|
||||
|
||||
self._sortTableByColumn($columnHeader);
|
||||
});
|
||||
|
||||
//Set default sorting
|
||||
$.each(this._lastSorting, function (sortIndex, sortField) {
|
||||
if (sortField.fieldName == fieldName) {
|
||||
if (sortField.sortOrder == 'DESC') {
|
||||
$columnHeader.addClass('jtable-column-header-sorted-desc');
|
||||
} else {
|
||||
$columnHeader.addClass('jtable-column-header-sorted-asc');
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/* Sorts table according to a column header.
|
||||
*************************************************************************/
|
||||
_sortTableByColumn: function ($columnHeader) {
|
||||
//Remove sorting styles from all columns except this one
|
||||
if (this._lastSorting.length == 0) {
|
||||
$columnHeader.siblings().removeClass('jtable-column-header-sorted-asc jtable-column-header-sorted-desc');
|
||||
}
|
||||
|
||||
//If current sorting list includes this column, remove it from the list
|
||||
for (var i = 0; i < this._lastSorting.length; i++) {
|
||||
if (this._lastSorting[i].fieldName == $columnHeader.data('fieldName')) {
|
||||
this._lastSorting.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//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');
|
||||
this._lastSorting.push({
|
||||
'fieldName': $columnHeader.data('fieldName'),
|
||||
sortOrder: 'DESC'
|
||||
});
|
||||
} else {
|
||||
$columnHeader.removeClass('jtable-column-header-sorted-desc').addClass('jtable-column-header-sorted-asc');
|
||||
this._lastSorting.push({
|
||||
'fieldName': $columnHeader.data('fieldName'),
|
||||
sortOrder: 'ASC'
|
||||
});
|
||||
}
|
||||
|
||||
//Load current page again
|
||||
this._reloadTable();
|
||||
},
|
||||
|
||||
/* Adds jtSorting parameter to a URL as query string.
|
||||
*************************************************************************/
|
||||
_addSortingInfoToUrl: function (url) {
|
||||
if (!this.options.sorting || this._lastSorting.length == 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
var sorting = [];
|
||||
$.each(this._lastSorting, function (idx, value) {
|
||||
sorting.push(value.fieldName + ' ' + value.sortOrder);
|
||||
});
|
||||
|
||||
return (url + (url.indexOf('?') < 0 ? '?' : '&') + 'jtSorting=' + sorting.join(","));
|
||||
},
|
||||
|
||||
/* Overrides _createJtParamsForLoading method to add sorging parameters to jtParams object.
|
||||
*************************************************************************/
|
||||
_createJtParamsForLoading: function () {
|
||||
var jtParams = base._createJtParamsForLoading.apply(this, arguments);
|
||||
|
||||
if (this.options.sorting && this._lastSorting.length) {
|
||||
var sorting = [];
|
||||
$.each(this._lastSorting, function (idx, value) {
|
||||
sorting.push(value.fieldName + ' ' + value.sortOrder);
|
||||
});
|
||||
|
||||
jtParams.jtSorting = sorting.join(",");
|
||||
}
|
||||
|
||||
return jtParams;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
159
jtable/dev/jquery.jtable.utils.js
Normal file
159
jtable/dev/jquery.jtable.utils.js
Normal file
|
@ -0,0 +1,159 @@
|
|||
/************************************************************************
|
||||
* Some UTULITY methods used by jTable *
|
||||
*************************************************************************/
|
||||
(function ($) {
|
||||
|
||||
$.extend(true, $.hik.jtable.prototype, {
|
||||
|
||||
/* Gets property value of an object recursively.
|
||||
*************************************************************************/
|
||||
_getPropertyOfObject: function (obj, propName) {
|
||||
if (propName.indexOf('.') < 0) {
|
||||
return obj[propName];
|
||||
} else {
|
||||
var preDot = propName.substring(0, propName.indexOf('.'));
|
||||
var postDot = propName.substring(propName.indexOf('.') + 1);
|
||||
return this._getPropertyOfObject(obj[preDot], postDot);
|
||||
}
|
||||
},
|
||||
|
||||
/* Sets property value of an object recursively.
|
||||
*************************************************************************/
|
||||
_setPropertyOfObject: function (obj, propName, value) {
|
||||
if (propName.indexOf('.') < 0) {
|
||||
obj[propName] = value;
|
||||
} else {
|
||||
var preDot = propName.substring(0, propName.indexOf('.'));
|
||||
var postDot = propName.substring(propName.indexOf('.') + 1);
|
||||
this._setPropertyOfObject(obj[preDot], postDot, value);
|
||||
}
|
||||
},
|
||||
|
||||
/* Inserts a value to an array if it does not exists in the array.
|
||||
*************************************************************************/
|
||||
_insertToArrayIfDoesNotExists: function (array, value) {
|
||||
if ($.inArray(value, array) < 0) {
|
||||
array.push(value);
|
||||
}
|
||||
},
|
||||
|
||||
/* Finds index of an element in an array according to given comparision function
|
||||
*************************************************************************/
|
||||
_findIndexInArray: function (value, array, compareFunc) {
|
||||
|
||||
//If not defined, use default comparision
|
||||
if (!compareFunc) {
|
||||
compareFunc = function (a, b) {
|
||||
return a == b;
|
||||
};
|
||||
}
|
||||
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (compareFunc(value, array[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
},
|
||||
|
||||
/* Normalizes a number between given bounds or sets to a defaultValue
|
||||
* if it is undefined
|
||||
*************************************************************************/
|
||||
_normalizeNumber: function (number, min, max, defaultValue) {
|
||||
if (number == undefined || number == null || isNaN(number)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (number < min) {
|
||||
return min;
|
||||
}
|
||||
|
||||
if (number > max) {
|
||||
return max;
|
||||
}
|
||||
|
||||
return number;
|
||||
},
|
||||
|
||||
/* Formats a string just like string.format in c#.
|
||||
* Example:
|
||||
* _formatString('Hello {0}','Halil') = 'Hello Halil'
|
||||
*************************************************************************/
|
||||
_formatString: function () {
|
||||
if (arguments.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var str = arguments[0];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
var placeHolder = '{' + (i - 1) + '}';
|
||||
str = str.replace(placeHolder, arguments[i]);
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
/* Checks if given object is a jQuery Deferred object.
|
||||
*/
|
||||
_isDeferredObject: function (obj) {
|
||||
return obj.then && obj.done && obj.fail;
|
||||
},
|
||||
|
||||
//Logging methods ////////////////////////////////////////////////////////
|
||||
|
||||
_logDebug: function (text) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('jTable DEBUG: ' + text);
|
||||
},
|
||||
|
||||
_logInfo: function (text) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('jTable INFO: ' + text);
|
||||
},
|
||||
|
||||
_logWarn: function (text) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('jTable WARNING: ' + text);
|
||||
},
|
||||
|
||||
_logError: function (text) {
|
||||
if (!window.console) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('jTable ERROR: ' + text);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/* Fix for array.indexOf method in IE7.
|
||||
* This code is taken from http://www.tutorialspoint.com/javascript/array_indexof.htm */
|
||||
if (!Array.prototype.indexOf) {
|
||||
Array.prototype.indexOf = function (elt) {
|
||||
var len = this.length;
|
||||
var from = Number(arguments[1]) || 0;
|
||||
from = (from < 0)
|
||||
? Math.ceil(from)
|
||||
: Math.floor(from);
|
||||
if (from < 0)
|
||||
from += len;
|
||||
for (; from < len; from++) {
|
||||
if (from in this &&
|
||||
this[from] === elt)
|
||||
return from;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
})(jQuery);
|
Loading…
Add table
Add a link
Reference in a new issue