summaryrefslogtreecommitdiffstats
path: root/lib/jquery.jtable.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/jquery.jtable.js')
-rw-r--r--lib/jquery.jtable.js720
1 files changed, 499 insertions, 221 deletions
diff --git a/lib/jquery.jtable.js b/lib/jquery.jtable.js
index b70b111..869af24 100644
--- a/lib/jquery.jtable.js
+++ b/lib/jquery.jtable.js
@@ -1,11 +1,11 @@
/*
-jTable 2.3.0
+jTable 2.4.0
http://www.jtable.org
---------------------------------------------------------------------------
-Copyright (C) 2011-2013 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
+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
@@ -32,6 +32,15 @@ THE SOFTWARE.
*************************************************************************/
(function ($) {
+ var unloadingPage;
+
+ $(window).on('beforeunload', function () {
+ unloadingPage = true;
+ });
+ $(window).on('unload', function () {
+ unloadingPage = false;
+ });
+
$.widget("hik.jtable", {
/************************************************************************
@@ -50,6 +59,7 @@ THE SOFTWARE.
loadingAnimationDelay: 500,
saveUserPreferences: true,
jqueryuiTheme: false,
+ unAuthorizedRequestRedirectUrl: null,
ajaxSettings: {
type: 'POST',
@@ -136,7 +146,7 @@ THE SOFTWARE.
this._createErrorDialogDiv();
this._addNoDataRow();
- this._cookieKeyPrefix = this._generateCookieKeyPrefix();
+ this._cookieKeyPrefix = this._generateCookieKeyPrefix();
},
/* Normalizes some options for all fields (sets default values).
@@ -422,42 +432,68 @@ THE SOFTWARE.
_reloadTable: function (completeCallback) {
var self = this;
- //Disable table since it's busy
- self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay);
+ var completeReload = function(data) {
+ self._hideBusy();
+
+ //Show the error message if server returns error
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ return;
+ }
+
+ //Re-generate table rows
+ self._removeAllRows('reloading');
+ self._addRecordsToTable(data.Records);
+
+ self._onRecordsLoaded(data);
- //Generate URL (with query string parameters) to load records
- var loadUrl = self._createRecordLoadUrl();
+ //Call complete callback
+ if (completeCallback) {
+ completeCallback();
+ }
+ };
- //Load data from server
+ self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay); //Disable table since it's busy
self._onLoadingRecords();
- self._ajax({
- url: loadUrl,
- data: self._lastPostData,
- success: function (data) {
- self._hideBusy();
- //Show the error message if server returns error
- if (data.Result != 'OK') {
- self._showError(data.Message);
- return;
- }
+ //listAction may be a function, check if it is
+ if ($.isFunction(self.options.actions.listAction)) {
- //Re-generate table rows
- self._removeAllRows('reloading');
- self._addRecordsToTable(data.Records);
+ //Execute the function
+ var funcResult = self.options.actions.listAction(self._lastPostData, self._createJtParamsForLoading());
- self._onRecordsLoaded(data);
+ //Check if result is a jQuery Deferred object
+ if (self._isDeferredObject(funcResult)) {
+ funcResult.done(function(data) {
+ completeReload(data);
+ }).fail(function() {
+ self._showError(self.options.messages.serverCommunicationError);
+ }).always(function() {
+ self._hideBusy();
+ });
+ } else { //assume it's the data we're loading
+ completeReload(funcResult);
+ }
+
+ } else { //assume listAction as URL string.
+
+ //Generate URL (with query string parameters) to load records
+ var loadUrl = self._createRecordLoadUrl();
- //Call complete callback
- if (completeCallback) {
- completeCallback();
+ //Load data from server using AJAX
+ self._ajax({
+ url: loadUrl,
+ data: self._lastPostData,
+ success: function (data) {
+ completeReload(data);
+ },
+ error: function () {
+ self._hideBusy();
+ self._showError(self.options.messages.serverCommunicationError);
}
- },
- error: function () {
- self._hideBusy();
- self._showError(self.options.messages.serverCommunicationError);
- }
- });
+ });
+
+ }
},
/* Creates URL to load records.
@@ -466,6 +502,12 @@ THE SOFTWARE.
return this.options.actions.listAction;
},
+ _createJtParamsForLoading: function() {
+ return {
+ //Empty as default, paging, sorting or other extensions can override this method to add additional params to load request
+ };
+ },
+
/* TABLE MANIPULATION METHODS *******************************************/
/* Creates a row from given record
@@ -1114,23 +1156,52 @@ THE SOFTWARE.
});
},
+ _unAuthorizedRequestHandler: function() {
+ if (this.options.unAuthorizedRequestRedirectUrl) {
+ location.href = this.options.unAuthorizedRequestRedirectUrl;
+ } else {
+ location.reload(true);
+ }
+ },
+
/* This method is used to perform AJAX calls in jTable instead of direct
* usage of jQuery.ajax method.
*************************************************************************/
_ajax: function (options) {
- var opts = $.extend({}, this.options.ajaxSettings, options);
+ var self = this;
+
+ //Handlers for HTTP status codes
+ var opts = {
+ statusCode: {
+ 401: function () { //Unauthorized
+ self._unAuthorizedRequestHandler();
+ }
+ }
+ };
+
+ opts = $.extend(opts, this.options.ajaxSettings, options);
//Override success
opts.success = function (data) {
+ //Checking for Authorization error
+ if (data && data.UnAuthorizedRequest == true) {
+ self._unAuthorizedRequestHandler();
+ }
+
if (options.success) {
options.success(data);
}
};
//Override error
- opts.error = function () {
+ opts.error = function (jqXHR, textStatus, errorThrown) {
+ if (unloadingPage) {
+ jqXHR.abort();
+ return;
+ }
+
if (options.error) {
- options.error();
+ options.error(arguments);
}
};
@@ -1341,6 +1412,12 @@ THE SOFTWARE.
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) {
@@ -1926,6 +2003,11 @@ THE SOFTWARE.
*************************************************************************/
_create: function () {
base._create.apply(this, arguments);
+
+ if (!this.options.actions.createAction) {
+ return;
+ }
+
this._createAddRecordDialogDiv();
},
@@ -1934,11 +2016,6 @@ THE SOFTWARE.
_createAddRecordDialogDiv: function () {
var self = this;
- //Check if createAction is supplied
- if (!self.options.actions.createAction) {
- return;
- }
-
//Create a div for dialog and add to container element
self._$addRecordDiv = $('<div />')
.appendTo(self._$mainContainer);
@@ -1962,18 +2039,12 @@ THE SOFTWARE.
id: 'AddRecordDialogSaveButton',
text: self.options.messages.save,
click: function () {
- var $saveButton = $('#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);
- }
+ self._onSaveClickedOnCreateForm();
}
}],
close: function () {
var $addRecordForm = self._$addRecordDiv.find('form').first();
- var $saveButton = $('#AddRecordDialogSaveButton');
+ 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();
@@ -1999,6 +2070,18 @@ THE SOFTWARE.
}
},
+ _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 *
*************************************************************************/
@@ -2016,7 +2099,6 @@ THE SOFTWARE.
options = $.extend({
clientOnly: false,
animationsEnabled: self.options.animationsEnabled,
- url: self.options.actions.createAction,
success: function () { },
error: function () { }
}, options);
@@ -2032,41 +2114,68 @@ THE SOFTWARE.
isNewRow: true,
animationsEnabled: options.animationsEnabled
});
-
+
options.success();
return;
}
- self._submitFormUsingAjax(
- options.url,
- $.param(options.record),
- 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;
- }
+ var completeAddRecord = function (data) {
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ options.error(data);
+ return;
+ }
- self._onRecordAdded(data);
-
- self._addRow(
- self._createRowFromRecord(data.Record), {
- isNewRow: true,
- animationsEnabled: options.animationsEnabled
- });
+ if (!data.Record) {
+ self._logError('Server must return the created Record object.');
+ options.error(data);
+ return;
+ }
- options.success(data);
- },
- function () {
- self._showError(self.options.messages.serverCommunicationError);
- options.error();
- });
+ 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();
+ });
+
+ }
},
/************************************************************************
@@ -2079,7 +2188,7 @@ THE SOFTWARE.
var self = this;
//Create add new record form
- var $addRecordForm = $('<form id="jtable-create-form" class="jtable-dialog-form jtable-create-form" action="' + self.options.actions.createAction + '" method="POST"></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++) {
@@ -2121,6 +2230,11 @@ THE SOFTWARE.
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' });
@@ -2131,37 +2245,62 @@ THE SOFTWARE.
_saveAddRecordForm: function ($addRecordForm, $saveButton) {
var self = this;
- //Make an Ajax call to update record
- $addRecordForm.data('submitting', true);
+ var completeAddRecord = function (data) {
+ if (data.Result != 'OK') {
+ self._showError(data.Message);
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
+ return;
+ }
- self._submitFormUsingAjax(
- $addRecordForm.attr('action'),
- $addRecordForm.serialize(),
- 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.');
+ 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);
- return;
- }
+ });
+ } else { //assume it returned the creation result
+ completeAddRecord(funcResult);
+ }
- self._onRecordAdded(data);
- self._addRow(
- self._createRowFromRecord(data.Record), {
- isNewRow: true
- });
- self._$addRecordDiv.dialog("close");
- },
- function () {
- self._showError(self.options.messages.serverCommunicationError);
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
- });
+ } 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) {
@@ -2218,6 +2357,11 @@ THE SOFTWARE.
*************************************************************************/
_create: function () {
base._create.apply(this, arguments);
+
+ if (!this.options.actions.updateAction) {
+ return;
+ }
+
this._createEditDialogDiv();
},
@@ -2249,24 +2393,12 @@ THE SOFTWARE.
id: 'EditDialogSaveButton',
text: self.options.messages.save,
click: function () {
-
- //row maybe removed by another source, if so, do nothing
- if (self._$editingRow.hasClass('jtable-row-removed')) {
- self._$editDiv.dialog('close');
- return;
- }
-
- var $saveButton = $('#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);
- }
+ self._onSaveClickedOnEditForm();
}
}],
close: function () {
var $editForm = self._$editDiv.find('form:first');
- var $saveButton = $('#EditDialogSaveButton');
+ 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();
@@ -2274,8 +2406,27 @@ THE SOFTWARE.
});
},
+ /* 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);
+ }
+ },
+
/************************************************************************
- * PUNLIC METHODS *
+ * PUBLIC METHODS *
*************************************************************************/
/* Updates a record on the table (optionally on the server also)
@@ -2285,7 +2436,6 @@ THE SOFTWARE.
options = $.extend({
clientOnly: false,
animationsEnabled: self.options.animationsEnabled,
- url: self.options.actions.updateAction,
success: function () { },
error: function () { }
}, options);
@@ -2303,7 +2453,7 @@ THE SOFTWARE.
var $updatingRow = self.getRowByKey(key);
if ($updatingRow == null) {
- self._logWarn('Can not found any row by key: ' + key);
+ self._logWarn('Can not found any row by key "' + key + '" on the table. Updating row must be visible on the table.');
return;
}
@@ -2319,31 +2469,59 @@ THE SOFTWARE.
return;
}
- self._submitFormUsingAjax(
- options.url,
- $.param(options.record),
- function (data) {
- if (data.Result != 'OK') {
- self._showError(data.Message);
- options.error(data);
- 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);
+ $.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);
- }
+ self._updateRowTexts($updatingRow);
+ self._onRecordUpdated($updatingRow, data);
+ if (options.animationsEnabled) {
+ self._showUpdateAnimationForRow($updatingRow);
+ }
- options.success(data);
- },
- function () {
- self._showError(self.options.messages.serverCommunicationError);
- options.error();
- });
+ 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();
+ });
+
+ }
},
/************************************************************************
@@ -2393,7 +2571,7 @@ THE SOFTWARE.
var record = $tableRow.data('record');
//Create edit form
- var $editForm = $('<form id="jtable-edit-form" class="jtable-dialog-form jtable-edit-form" action="' + self.options.actions.updateAction + '" method="POST"></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++) {
@@ -2441,9 +2619,14 @@ THE SOFTWARE.
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');
@@ -2454,37 +2637,66 @@ THE SOFTWARE.
*************************************************************************/
_saveEditForm: function ($editForm, $saveButton) {
var self = this;
- self._submitFormUsingAjax(
- $editForm.attr('action'),
- $editForm.serialize(),
- function (data) {
- //Check for errors
- if (data.Result != 'OK') {
- self._showError(data.Message);
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
- return;
- }
+
+ 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');
+ var record = self._$editingRow.data('record');
- self._updateRecordValuesFromForm(record, $editForm);
- self._updateRecordValuesFromServerResponse(record, data);
- self._updateRowTexts(self._$editingRow);
+ self._updateRecordValuesFromForm(record, $editForm);
+ self._updateRecordValuesFromServerResponse(record, data);
+ self._updateRowTexts(self._$editingRow);
- self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
+ self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
- self._onRecordUpdated(self._$editingRow, data);
+ self._onRecordUpdated(self._$editingRow, data);
- if (self.options.animationsEnabled) {
- self._showUpdateAnimationForRow(self._$editingRow);
- }
+ 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);
+ });
+ }
- self._$editDiv.dialog("close");
- },
- 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,
@@ -2517,6 +2729,7 @@ THE SOFTWARE.
var $columns = $tableRow.find('td');
for (var i = 0; i < this._columnList.length; i++) {
var displayItem = this._getDisplayTextForRecordField(record, this._columnList[i]);
+ if ((displayItem != "") && (displayItem == 0)) displayItem = "0";
$columns.eq(this._firstDataColumnOffset + i).html(displayItem || '');
}
@@ -2530,7 +2743,7 @@ THE SOFTWARE.
if (this.options.jqueryuiTheme) {
className = className + ' ui-state-highlight';
}
-
+
$tableRow.stop(true, true).addClass(className, 'slow', '', function () {
$tableRow.removeClass(className, 5000);
});
@@ -2612,6 +2825,11 @@ THE SOFTWARE.
_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);
@@ -2632,14 +2850,14 @@ THE SOFTWARE.
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 = $('#DeleteDialogButton');
+ var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
self._setEnabledOfDialogButton($deleteButton, false, self.options.messages.deleting);
self._deleteRecordFromServer(
self._$deletingRow,
@@ -2655,7 +2873,7 @@ THE SOFTWARE.
}
}],
close: function () {
- var $deleteButton = $('#DeleteDialogButton');
+ var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
}
});
@@ -2674,7 +2892,7 @@ THE SOFTWARE.
self._logWarn('No rows specified to jTable deleteRows method.');
return;
}
-
+
if (self._isBusy()) {
self._logWarn('Can not delete rows since jTable is busy!');
return;
@@ -2881,11 +3099,28 @@ THE SOFTWARE.
},
/* Performs an ajax call to server to delete record
- * and removesd row of record from table if ajax call success.
+ * 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;
@@ -2895,34 +3130,45 @@ THE SOFTWARE.
var postData = {};
postData[self._keyField] = self._getKeyValueOfRecord($row.data('record'));
-
- this._ajax({
- url: (url || self.options.actions.deleteAction),
- data: postData,
- success: function (data) {
-
- if (data.Result != 'OK') {
+
+ //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(data.Message);
+ error(self.options.messages.serverCommunicationError);
}
+ });
+ } else { //assume it returned the deletion result
+ completeDelete(funcResult);
+ }
- return;
+ } 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);
+ }
}
+ });
- self._trigger("recordDeleted", null, { record: $row.data('record'), row: $row, serverResponse: data });
-
- if (success) {
- success(data);
- }
- },
- error: function () {
- $row.data('deleting', false);
- if (error) {
- error(self.options.messages.serverCommunicationError);
- }
- }
- });
+ }
},
/* Removes a row from table after a 'deleting' animation.
@@ -2939,7 +3185,7 @@ THE SOFTWARE.
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');
@@ -3349,6 +3595,7 @@ THE SOFTWARE.
_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,
@@ -3395,7 +3642,7 @@ THE SOFTWARE.
/* Overrides base method to do paging-specific constructions.
*************************************************************************/
- _create: function () {
+ _create: function() {
base._create.apply(this, arguments);
if (this.options.paging) {
this._loadPagingSettings();
@@ -3408,7 +3655,7 @@ THE SOFTWARE.
/* Loads user preferences for paging.
*************************************************************************/
- _loadPagingSettings: function () {
+ _loadPagingSettings: function() {
if (!this.options.saveUserPreferences) {
return;
}
@@ -3421,7 +3668,7 @@ THE SOFTWARE.
/* Creates bottom panel and adds to the page.
*************************************************************************/
- _createBottomPanel: function () {
+ _createBottomPanel: function() {
this._$bottomPanel = $('<div />')
.addClass('jtable-bottom-panel')
.insertAfter(this._$table);
@@ -3434,7 +3681,7 @@ THE SOFTWARE.
/* Creates page list area.
*************************************************************************/
- _createPageListArea: function () {
+ _createPageListArea: function() {
this._$pagingListArea = $('<span></span>')
.addClass('jtable-page-list')
.appendTo(this._$bottomPanel.find('.jtable-left-area'));
@@ -3446,7 +3693,7 @@ THE SOFTWARE.
/* Creates page list change area.
*************************************************************************/
- _createPageSizeSelection: function () {
+ _createPageSizeSelection: function() {
var self = this;
if (!self.options.pageSizeChangeArea) {
@@ -3456,7 +3703,7 @@ THE SOFTWARE.
//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; });
+ self.options.pageSizes.sort(function(a, b) { return a - b; });
}
//Add a span to contain page size change items
@@ -3479,14 +3726,14 @@ THE SOFTWARE.
$pageSizeChangeCombobox.val(self.options.pageSize);
//Change page size on combobox change
- $pageSizeChangeCombobox.change(function () {
+ $pageSizeChangeCombobox.change(function() {
self._changePageSize(parseInt($(this).val()));
});
},
/* Creates go to page area.
*************************************************************************/
- _createGotoPageInput: function () {
+ _createGotoPageInput: function() {
var self = this;
if (!self.options.gotoPageArea || self.options.gotoPageArea == 'none') {
@@ -3507,7 +3754,7 @@ THE SOFTWARE.
self._$gotoPageInput = $('<select></select>')
.appendTo(this._$gotoPageArea)
.data('pageCount', 1)
- .change(function () {
+ .change(function() {
self._changePage(parseInt($(this).val()));
});
self._$gotoPageInput.append('<option value="1">1</option>');
@@ -3516,7 +3763,7 @@ THE SOFTWARE.
self._$gotoPageInput = $('<input type="text" maxlength="10" value="' + self._currentPageNo + '" />')
.appendTo(this._$gotoPageArea)
- .keypress(function (event) {
+ .keypress(function(event) {
if (event.which == 13) { //enter
event.preventDefault();
self._changePage(parseInt(self._$gotoPageInput.val()));
@@ -3545,7 +3792,7 @@ THE SOFTWARE.
/* Refreshes the 'go to page' input.
*************************************************************************/
- _refreshGotoPageInput: function () {
+ _refreshGotoPageInput: function() {
if (!this.options.gotoPageArea || this.options.gotoPageArea == 'none') {
return;
}
@@ -3592,7 +3839,7 @@ THE SOFTWARE.
/* Overrides load method to set current page to 1.
*************************************************************************/
- load: function () {
+ load: function() {
this._currentPageNo = 1;
base.load.apply(this, arguments);
@@ -3600,7 +3847,7 @@ THE SOFTWARE.
/* Used to change options dynamically after initialization.
*************************************************************************/
- _setOption: function (key, value) {
+ _setOption: function(key, value) {
base._setOption.apply(this, arguments);
if (key == 'pageSize') {
@@ -3610,7 +3857,7 @@ THE SOFTWARE.
/* Changes current page size with given value.
*************************************************************************/
- _changePageSize: function (pageSize) {
+ _changePageSize: function(pageSize) {
if (pageSize == this.options.pageSize) {
return;
}
@@ -3643,7 +3890,7 @@ THE SOFTWARE.
/* Saves user preferences for paging
*************************************************************************/
- _savePagingSettings: function () {
+ _savePagingSettings: function() {
if (!this.options.saveUserPreferences) {
return;
}
@@ -3653,12 +3900,25 @@ THE SOFTWARE.
/* Overrides _createRecordLoadUrl method to add paging info to URL.
*************************************************************************/
- _createRecordLoadUrl: function () {
+ _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.
@@ -3931,7 +4191,8 @@ THE SOFTWARE.
_initializeFields: $.hik.jtable.prototype._initializeFields,
_normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
_createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
- _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl
+ _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
+ _createJtParamsForLoading: $.hik.jtable.prototype._createJtParamsForLoading
};
//extension members
@@ -4007,7 +4268,7 @@ THE SOFTWARE.
if (fieldProps.sorting) {
var colOffset = orderValue.indexOf(fieldName);
if (colOffset > -1) {
- if (orderValue.toUpperCase().indexOf('DESC', colOffset) > -1) {
+ if (orderValue.toUpperCase().indexOf(' DESC', colOffset) > -1) {
self._lastSorting.push({
fieldName: fieldName,
sortOrder: 'DESC'
@@ -4100,6 +4361,23 @@ THE SOFTWARE.
});
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;
}
});
@@ -4704,14 +4982,14 @@ THE SOFTWARE.
/* Overrides _removeRowsFromTable method to remove child rows of deleted rows.
*************************************************************************/
_removeRowsFromTable: function ($rows, reason) {
- var self = this;
+ //var self = this;
if (reason == 'deleted') {
$rows.each(function () {
var $row = $(this);
var $childRow = $row.data('childRow');
if ($childRow) {
- self.closeChildTable($row);
+ //self.closeChildTable($row); //Removed since it causes "Uncaught Error: cannot call methods on jtable prior to initialization; attempted to call method 'destroy'"
$childRow.remove();
}
});