jquery-jtable-rails 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44cf8718821d0bfc682c4bdd36ad304b4dd51a33
4
- data.tar.gz: 115a45003eaa6b0d23c4012df0bbc4ec5a8507c5
3
+ metadata.gz: 35a2a0fe42c0b26f39e3a90bd129e37070ee8259
4
+ data.tar.gz: bf12327df50ebc3be62c23f7baae66a2dd9b1ecd
5
5
  SHA512:
6
- metadata.gz: 97734b1a1a32a7badc819ab863e913ca5fe755cbb1e9889fd7a7cf02448d70e6376320e0ba03fe580bcd686afa293ce09144c901a2b363c08935f959dd98c221
7
- data.tar.gz: d1d6471d846d26fe0a08eea2bf992b7b0caee1c5a651014c848b3e822d3b10ff6f4a660375dc9a4d8ddee54702eee2442636465d7bae6b78fbc8d83c8641af32
6
+ metadata.gz: 7f13dfd5580a18e6aa6ab00b13c9f09f07f881c92224e34d51d793e6abf7db5620b9d2547f67fa1a5ec14fb0ef17a715d907669462c89301f2b4276968dfc1fa
7
+ data.tar.gz: 118561b77dde78a998219603fc4523f980f01c77d629ffbf9a2eac806d4e619e690d7b68c19d8e167102340bc0bec079a8e21818454d946862fbcf78d72ae3c8
@@ -1,11 +1,11 @@
1
1
  /*
2
2
 
3
- jTable 2.3.1
3
+ jTable 2.4.0
4
4
  http://www.jtable.org
5
5
 
6
6
  ---------------------------------------------------------------------------
7
7
 
8
- Copyright (C) 2011-2013 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
8
+ Copyright (C) 2011-2014 by Halil İbrahim Kalkan (http://www.halilibrahimkalkan.com)
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -59,6 +59,7 @@ THE SOFTWARE.
59
59
  loadingAnimationDelay: 500,
60
60
  saveUserPreferences: true,
61
61
  jqueryuiTheme: false,
62
+ unAuthorizedRequestRedirectUrl: null,
62
63
 
63
64
  ajaxSettings: {
64
65
  type: 'POST',
@@ -431,42 +432,68 @@ THE SOFTWARE.
431
432
  _reloadTable: function (completeCallback) {
432
433
  var self = this;
433
434
 
434
- //Disable table since it's busy
435
- self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay);
435
+ var completeReload = function(data) {
436
+ self._hideBusy();
437
+
438
+ //Show the error message if server returns error
439
+ if (data.Result != 'OK') {
440
+ self._showError(data.Message);
441
+ return;
442
+ }
436
443
 
437
- //Generate URL (with query string parameters) to load records
438
- var loadUrl = self._createRecordLoadUrl();
444
+ //Re-generate table rows
445
+ self._removeAllRows('reloading');
446
+ self._addRecordsToTable(data.Records);
447
+
448
+ self._onRecordsLoaded(data);
449
+
450
+ //Call complete callback
451
+ if (completeCallback) {
452
+ completeCallback();
453
+ }
454
+ };
439
455
 
440
- //Load data from server
456
+ self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay); //Disable table since it's busy
441
457
  self._onLoadingRecords();
442
- self._ajax({
443
- url: loadUrl,
444
- data: self._lastPostData,
445
- success: function (data) {
446
- self._hideBusy();
447
458
 
448
- //Show the error message if server returns error
449
- if (data.Result != 'OK') {
450
- self._showError(data.Message);
451
- return;
452
- }
459
+ //listAction may be a function, check if it is
460
+ if ($.isFunction(self.options.actions.listAction)) {
461
+
462
+ //Execute the function
463
+ var funcResult = self.options.actions.listAction(self._lastPostData, self._createJtParamsForLoading());
453
464
 
454
- //Re-generate table rows
455
- self._removeAllRows('reloading');
456
- self._addRecordsToTable(data.Records);
465
+ //Check if result is a jQuery Deferred object
466
+ if (self._isDeferredObject(funcResult)) {
467
+ funcResult.done(function(data) {
468
+ completeReload(data);
469
+ }).fail(function() {
470
+ self._showError(self.options.messages.serverCommunicationError);
471
+ }).always(function() {
472
+ self._hideBusy();
473
+ });
474
+ } else { //assume it's the data we're loading
475
+ completeReload(funcResult);
476
+ }
457
477
 
458
- self._onRecordsLoaded(data);
478
+ } else { //assume listAction as URL string.
459
479
 
460
- //Call complete callback
461
- if (completeCallback) {
462
- completeCallback();
480
+ //Generate URL (with query string parameters) to load records
481
+ var loadUrl = self._createRecordLoadUrl();
482
+
483
+ //Load data from server using AJAX
484
+ self._ajax({
485
+ url: loadUrl,
486
+ data: self._lastPostData,
487
+ success: function (data) {
488
+ completeReload(data);
489
+ },
490
+ error: function () {
491
+ self._hideBusy();
492
+ self._showError(self.options.messages.serverCommunicationError);
463
493
  }
464
- },
465
- error: function () {
466
- self._hideBusy();
467
- self._showError(self.options.messages.serverCommunicationError);
468
- }
469
- });
494
+ });
495
+
496
+ }
470
497
  },
471
498
 
472
499
  /* Creates URL to load records.
@@ -475,6 +502,12 @@ THE SOFTWARE.
475
502
  return this.options.actions.listAction;
476
503
  },
477
504
 
505
+ _createJtParamsForLoading: function() {
506
+ return {
507
+ //Empty as default, paging, sorting or other extensions can override this method to add additional params to load request
508
+ };
509
+ },
510
+
478
511
  /* TABLE MANIPULATION METHODS *******************************************/
479
512
 
480
513
  /* Creates a row from given record
@@ -1123,14 +1156,38 @@ THE SOFTWARE.
1123
1156
  });
1124
1157
  },
1125
1158
 
1159
+ _unAuthorizedRequestHandler: function() {
1160
+ if (this.options.unAuthorizedRequestRedirectUrl) {
1161
+ location.href = this.options.unAuthorizedRequestRedirectUrl;
1162
+ } else {
1163
+ location.reload(true);
1164
+ }
1165
+ },
1166
+
1126
1167
  /* This method is used to perform AJAX calls in jTable instead of direct
1127
1168
  * usage of jQuery.ajax method.
1128
1169
  *************************************************************************/
1129
1170
  _ajax: function (options) {
1130
- var opts = $.extend({}, this.options.ajaxSettings, options);
1171
+ var self = this;
1172
+
1173
+ //Handlers for HTTP status codes
1174
+ var opts = {
1175
+ statusCode: {
1176
+ 401: function () { //Unauthorized
1177
+ self._unAuthorizedRequestHandler();
1178
+ }
1179
+ }
1180
+ };
1181
+
1182
+ opts = $.extend(opts, this.options.ajaxSettings, options);
1131
1183
 
1132
1184
  //Override success
1133
1185
  opts.success = function (data) {
1186
+ //Checking for Authorization error
1187
+ if (data && data.UnAuthorizedRequest == true) {
1188
+ self._unAuthorizedRequestHandler();
1189
+ }
1190
+
1134
1191
  if (options.success) {
1135
1192
  options.success(data);
1136
1193
  }
@@ -1355,6 +1412,12 @@ THE SOFTWARE.
1355
1412
  return str;
1356
1413
  },
1357
1414
 
1415
+ /* Checks if given object is a jQuery Deferred object.
1416
+ */
1417
+ _isDeferredObject: function (obj) {
1418
+ return obj.then && obj.done && obj.fail;
1419
+ },
1420
+
1358
1421
  //Logging methods ////////////////////////////////////////////////////////
1359
1422
 
1360
1423
  _logDebug: function (text) {
@@ -1940,11 +2003,11 @@ THE SOFTWARE.
1940
2003
  *************************************************************************/
1941
2004
  _create: function () {
1942
2005
  base._create.apply(this, arguments);
1943
-
2006
+
1944
2007
  if (!this.options.actions.createAction) {
1945
2008
  return;
1946
2009
  }
1947
-
2010
+
1948
2011
  this._createAddRecordDialogDiv();
1949
2012
  },
1950
2013
 
@@ -1981,7 +2044,7 @@ THE SOFTWARE.
1981
2044
  }],
1982
2045
  close: function () {
1983
2046
  var $addRecordForm = self._$addRecordDiv.find('form').first();
1984
- var $saveButton = $('#AddRecordDialogSaveButton');
2047
+ var $saveButton = self._$addRecordDiv.parent().find('#AddRecordDialogSaveButton');
1985
2048
  self._trigger("formClosed", null, { form: $addRecordForm, formType: 'create' });
1986
2049
  self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
1987
2050
  $addRecordForm.remove();
@@ -2006,11 +2069,11 @@ THE SOFTWARE.
2006
2069
  });
2007
2070
  }
2008
2071
  },
2009
-
2072
+
2010
2073
  _onSaveClickedOnCreateForm: function () {
2011
2074
  var self = this;
2012
-
2013
- var $saveButton = $('#AddRecordDialogSaveButton');
2075
+
2076
+ var $saveButton = self._$addRecordDiv.parent().find('#AddRecordDialogSaveButton');
2014
2077
  var $addRecordForm = self._$addRecordDiv.find('form');
2015
2078
 
2016
2079
  if (self._trigger("formSubmitting", null, { form: $addRecordForm, formType: 'create' }) != false) {
@@ -2036,7 +2099,6 @@ THE SOFTWARE.
2036
2099
  options = $.extend({
2037
2100
  clientOnly: false,
2038
2101
  animationsEnabled: self.options.animationsEnabled,
2039
- url: self.options.actions.createAction,
2040
2102
  success: function () { },
2041
2103
  error: function () { }
2042
2104
  }, options);
@@ -2052,41 +2114,68 @@ THE SOFTWARE.
2052
2114
  isNewRow: true,
2053
2115
  animationsEnabled: options.animationsEnabled
2054
2116
  });
2055
-
2117
+
2056
2118
  options.success();
2057
2119
  return;
2058
2120
  }
2059
2121
 
2060
- self._submitFormUsingAjax(
2061
- options.url,
2062
- $.param(options.record),
2063
- function (data) {
2064
- if (data.Result != 'OK') {
2065
- self._showError(data.Message);
2066
- options.error(data);
2067
- return;
2068
- }
2069
-
2070
- if(!data.Record) {
2071
- self._logError('Server must return the created Record object.');
2072
- options.error(data);
2073
- return;
2074
- }
2122
+ var completeAddRecord = function (data) {
2123
+ if (data.Result != 'OK') {
2124
+ self._showError(data.Message);
2125
+ options.error(data);
2126
+ return;
2127
+ }
2075
2128
 
2076
- self._onRecordAdded(data);
2077
-
2078
- self._addRow(
2079
- self._createRowFromRecord(data.Record), {
2080
- isNewRow: true,
2081
- animationsEnabled: options.animationsEnabled
2082
- });
2129
+ if (!data.Record) {
2130
+ self._logError('Server must return the created Record object.');
2131
+ options.error(data);
2132
+ return;
2133
+ }
2083
2134
 
2084
- options.success(data);
2085
- },
2086
- function () {
2087
- self._showError(self.options.messages.serverCommunicationError);
2088
- options.error();
2089
- });
2135
+ self._onRecordAdded(data);
2136
+ self._addRow(
2137
+ self._createRowFromRecord(data.Record), {
2138
+ isNewRow: true,
2139
+ animationsEnabled: options.animationsEnabled
2140
+ });
2141
+
2142
+ options.success(data);
2143
+ };
2144
+
2145
+ //createAction may be a function, check if it is
2146
+ if (!options.url && $.isFunction(self.options.actions.createAction)) {
2147
+
2148
+ //Execute the function
2149
+ var funcResult = self.options.actions.createAction($.param(options.record));
2150
+
2151
+ //Check if result is a jQuery Deferred object
2152
+ if (self._isDeferredObject(funcResult)) {
2153
+ //Wait promise
2154
+ funcResult.done(function (data) {
2155
+ completeAddRecord(data);
2156
+ }).fail(function () {
2157
+ self._showError(self.options.messages.serverCommunicationError);
2158
+ options.error();
2159
+ });
2160
+ } else { //assume it returned the creation result
2161
+ completeAddRecord(funcResult);
2162
+ }
2163
+
2164
+ } else { //Assume it's a URL string
2165
+
2166
+ //Make an Ajax call to create record
2167
+ self._submitFormUsingAjax(
2168
+ options.url || self.options.actions.createAction,
2169
+ $.param(options.record),
2170
+ function (data) {
2171
+ completeAddRecord(data);
2172
+ },
2173
+ function () {
2174
+ self._showError(self.options.messages.serverCommunicationError);
2175
+ options.error();
2176
+ });
2177
+
2178
+ }
2090
2179
  },
2091
2180
 
2092
2181
  /************************************************************************
@@ -2156,37 +2245,62 @@ THE SOFTWARE.
2156
2245
  _saveAddRecordForm: function ($addRecordForm, $saveButton) {
2157
2246
  var self = this;
2158
2247
 
2159
- //Make an Ajax call to update record
2160
- $addRecordForm.data('submitting', true);
2248
+ var completeAddRecord = function (data) {
2249
+ if (data.Result != 'OK') {
2250
+ self._showError(data.Message);
2251
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2252
+ return;
2253
+ }
2161
2254
 
2162
- self._submitFormUsingAjax(
2163
- self.options.actions.createAction,
2164
- $addRecordForm.serialize(),
2165
- function (data) {
2166
-
2167
- if (data.Result != 'OK') {
2168
- self._showError(data.Message);
2169
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2170
- return;
2171
- }
2172
-
2173
- if (!data.Record) {
2174
- self._logError('Server must return the created Record object.');
2255
+ if (!data.Record) {
2256
+ self._logError('Server must return the created Record object.');
2257
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2258
+ return;
2259
+ }
2260
+
2261
+ self._onRecordAdded(data);
2262
+ self._addRow(
2263
+ self._createRowFromRecord(data.Record), {
2264
+ isNewRow: true
2265
+ });
2266
+ self._$addRecordDiv.dialog("close");
2267
+ };
2268
+
2269
+ $addRecordForm.data('submitting', true); //TODO: Why it's used, can remove? Check it.
2270
+
2271
+ //createAction may be a function, check if it is
2272
+ if ($.isFunction(self.options.actions.createAction)) {
2273
+
2274
+ //Execute the function
2275
+ var funcResult = self.options.actions.createAction($addRecordForm.serialize());
2276
+
2277
+ //Check if result is a jQuery Deferred object
2278
+ if (self._isDeferredObject(funcResult)) {
2279
+ //Wait promise
2280
+ funcResult.done(function (data) {
2281
+ completeAddRecord(data);
2282
+ }).fail(function () {
2283
+ self._showError(self.options.messages.serverCommunicationError);
2175
2284
  self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2176
- return;
2177
- }
2285
+ });
2286
+ } else { //assume it returned the creation result
2287
+ completeAddRecord(funcResult);
2288
+ }
2178
2289
 
2179
- self._onRecordAdded(data);
2180
- self._addRow(
2181
- self._createRowFromRecord(data.Record), {
2182
- isNewRow: true
2183
- });
2184
- self._$addRecordDiv.dialog("close");
2185
- },
2186
- function () {
2187
- self._showError(self.options.messages.serverCommunicationError);
2188
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2189
- });
2290
+ } else { //Assume it's a URL string
2291
+
2292
+ //Make an Ajax call to create record
2293
+ self._submitFormUsingAjax(
2294
+ self.options.actions.createAction,
2295
+ $addRecordForm.serialize(),
2296
+ function (data) {
2297
+ completeAddRecord(data);
2298
+ },
2299
+ function () {
2300
+ self._showError(self.options.messages.serverCommunicationError);
2301
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2302
+ });
2303
+ }
2190
2304
  },
2191
2305
 
2192
2306
  _onRecordAdded: function (data) {
@@ -2284,7 +2398,7 @@ THE SOFTWARE.
2284
2398
  }],
2285
2399
  close: function () {
2286
2400
  var $editForm = self._$editDiv.find('form:first');
2287
- var $saveButton = $('#EditDialogSaveButton');
2401
+ var $saveButton = self._$editDiv.parent().find('#EditDialogSaveButton');
2288
2402
  self._trigger("formClosed", null, { form: $editForm, formType: 'edit', row: self._$editingRow });
2289
2403
  self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2290
2404
  $editForm.remove();
@@ -2303,7 +2417,7 @@ THE SOFTWARE.
2303
2417
  return;
2304
2418
  }
2305
2419
 
2306
- var $saveButton = $('#EditDialogSaveButton');
2420
+ var $saveButton = self._$editDiv.parent().find('#EditDialogSaveButton');
2307
2421
  var $editForm = self._$editDiv.find('form');
2308
2422
  if (self._trigger("formSubmitting", null, { form: $editForm, formType: 'edit', row: self._$editingRow }) != false) {
2309
2423
  self._setEnabledOfDialogButton($saveButton, false, self.options.messages.saving);
@@ -2322,7 +2436,6 @@ THE SOFTWARE.
2322
2436
  options = $.extend({
2323
2437
  clientOnly: false,
2324
2438
  animationsEnabled: self.options.animationsEnabled,
2325
- url: self.options.actions.updateAction,
2326
2439
  success: function () { },
2327
2440
  error: function () { }
2328
2441
  }, options);
@@ -2340,7 +2453,7 @@ THE SOFTWARE.
2340
2453
 
2341
2454
  var $updatingRow = self.getRowByKey(key);
2342
2455
  if ($updatingRow == null) {
2343
- self._logWarn('Can not found any row by key: ' + key);
2456
+ self._logWarn('Can not found any row by key "' + key + '" on the table. Updating row must be visible on the table.');
2344
2457
  return;
2345
2458
  }
2346
2459
 
@@ -2356,31 +2469,59 @@ THE SOFTWARE.
2356
2469
  return;
2357
2470
  }
2358
2471
 
2359
- self._submitFormUsingAjax(
2360
- options.url,
2361
- $.param(options.record),
2362
- function (data) {
2363
- if (data.Result != 'OK') {
2364
- self._showError(data.Message);
2365
- options.error(data);
2366
- return;
2367
- }
2472
+ var completeEdit = function (data) {
2473
+ if (data.Result != 'OK') {
2474
+ self._showError(data.Message);
2475
+ options.error(data);
2476
+ return;
2477
+ }
2368
2478
 
2369
- $.extend($updatingRow.data('record'), options.record);
2370
- self._updateRecordValuesFromServerResponse($updatingRow.data('record'), data);
2479
+ $.extend($updatingRow.data('record'), options.record);
2480
+ self._updateRecordValuesFromServerResponse($updatingRow.data('record'), data);
2371
2481
 
2372
- self._updateRowTexts($updatingRow);
2373
- self._onRecordUpdated($updatingRow, data);
2374
- if (options.animationsEnabled) {
2375
- self._showUpdateAnimationForRow($updatingRow);
2376
- }
2482
+ self._updateRowTexts($updatingRow);
2483
+ self._onRecordUpdated($updatingRow, data);
2484
+ if (options.animationsEnabled) {
2485
+ self._showUpdateAnimationForRow($updatingRow);
2486
+ }
2377
2487
 
2378
- options.success(data);
2379
- },
2380
- function () {
2381
- self._showError(self.options.messages.serverCommunicationError);
2382
- options.error();
2383
- });
2488
+ options.success(data);
2489
+ };
2490
+
2491
+ //updateAction may be a function, check if it is
2492
+ if (!options.url && $.isFunction(self.options.actions.updateAction)) {
2493
+
2494
+ //Execute the function
2495
+ var funcResult = self.options.actions.updateAction($.param(options.record));
2496
+
2497
+ //Check if result is a jQuery Deferred object
2498
+ if (self._isDeferredObject(funcResult)) {
2499
+ //Wait promise
2500
+ funcResult.done(function (data) {
2501
+ completeEdit(data);
2502
+ }).fail(function () {
2503
+ self._showError(self.options.messages.serverCommunicationError);
2504
+ options.error();
2505
+ });
2506
+ } else { //assume it returned the creation result
2507
+ completeEdit(funcResult);
2508
+ }
2509
+
2510
+ } else { //Assume it's a URL string
2511
+
2512
+ //Make an Ajax call to create record
2513
+ self._submitFormUsingAjax(
2514
+ options.url || self.options.actions.updateAction,
2515
+ $.param(options.record),
2516
+ function (data) {
2517
+ completeEdit(data);
2518
+ },
2519
+ function () {
2520
+ self._showError(self.options.messages.serverCommunicationError);
2521
+ options.error();
2522
+ });
2523
+
2524
+ }
2384
2525
  },
2385
2526
 
2386
2527
  /************************************************************************
@@ -2496,37 +2637,66 @@ THE SOFTWARE.
2496
2637
  *************************************************************************/
2497
2638
  _saveEditForm: function ($editForm, $saveButton) {
2498
2639
  var self = this;
2499
- self._submitFormUsingAjax(
2500
- self.options.actions.updateAction,
2501
- $editForm.serialize(),
2502
- function (data) {
2503
- //Check for errors
2504
- if (data.Result != 'OK') {
2505
- self._showError(data.Message);
2506
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2507
- return;
2508
- }
2640
+
2641
+ var completeEdit = function (data) {
2642
+ if (data.Result != 'OK') {
2643
+ self._showError(data.Message);
2644
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2645
+ return;
2646
+ }
2509
2647
 
2510
- var record = self._$editingRow.data('record');
2648
+ var record = self._$editingRow.data('record');
2511
2649
 
2512
- self._updateRecordValuesFromForm(record, $editForm);
2513
- self._updateRecordValuesFromServerResponse(record, data);
2514
- self._updateRowTexts(self._$editingRow);
2650
+ self._updateRecordValuesFromForm(record, $editForm);
2651
+ self._updateRecordValuesFromServerResponse(record, data);
2652
+ self._updateRowTexts(self._$editingRow);
2515
2653
 
2516
- self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
2654
+ self._$editingRow.attr('data-record-key', self._getKeyValueOfRecord(record));
2517
2655
 
2518
- self._onRecordUpdated(self._$editingRow, data);
2656
+ self._onRecordUpdated(self._$editingRow, data);
2519
2657
 
2520
- if (self.options.animationsEnabled) {
2521
- self._showUpdateAnimationForRow(self._$editingRow);
2522
- }
2658
+ if (self.options.animationsEnabled) {
2659
+ self._showUpdateAnimationForRow(self._$editingRow);
2660
+ }
2661
+
2662
+ self._$editDiv.dialog("close");
2663
+ };
2664
+
2665
+
2666
+ //updateAction may be a function, check if it is
2667
+ if ($.isFunction(self.options.actions.updateAction)) {
2668
+
2669
+ //Execute the function
2670
+ var funcResult = self.options.actions.updateAction($editForm.serialize());
2671
+
2672
+ //Check if result is a jQuery Deferred object
2673
+ if (self._isDeferredObject(funcResult)) {
2674
+ //Wait promise
2675
+ funcResult.done(function (data) {
2676
+ completeEdit(data);
2677
+ }).fail(function () {
2678
+ self._showError(self.options.messages.serverCommunicationError);
2679
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2680
+ });
2681
+ } else { //assume it returned the creation result
2682
+ completeEdit(funcResult);
2683
+ }
2684
+
2685
+ } else { //Assume it's a URL string
2686
+
2687
+ //Make an Ajax call to update record
2688
+ self._submitFormUsingAjax(
2689
+ self.options.actions.updateAction,
2690
+ $editForm.serialize(),
2691
+ function(data) {
2692
+ completeEdit(data);
2693
+ },
2694
+ function() {
2695
+ self._showError(self.options.messages.serverCommunicationError);
2696
+ self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2697
+ });
2698
+ }
2523
2699
 
2524
- self._$editDiv.dialog("close");
2525
- },
2526
- function () {
2527
- self._showError(self.options.messages.serverCommunicationError);
2528
- self._setEnabledOfDialogButton($saveButton, true, self.options.messages.save);
2529
- });
2530
2700
  },
2531
2701
 
2532
2702
  /* This method ensures updating of current record with server response,
@@ -2559,7 +2729,7 @@ THE SOFTWARE.
2559
2729
  var $columns = $tableRow.find('td');
2560
2730
  for (var i = 0; i < this._columnList.length; i++) {
2561
2731
  var displayItem = this._getDisplayTextForRecordField(record, this._columnList[i]);
2562
- if (displayItem == 0) displayItem = "0";
2732
+ if ((displayItem != "") && (displayItem == 0)) displayItem = "0";
2563
2733
  $columns.eq(this._firstDataColumnOffset + i).html(displayItem || '');
2564
2734
  }
2565
2735
 
@@ -2573,7 +2743,7 @@ THE SOFTWARE.
2573
2743
  if (this.options.jqueryuiTheme) {
2574
2744
  className = className + ' ui-state-highlight';
2575
2745
  }
2576
-
2746
+
2577
2747
  $tableRow.stop(true, true).addClass(className, 'slow', '', function () {
2578
2748
  $tableRow.removeClass(className, 5000);
2579
2749
  });
@@ -2654,7 +2824,7 @@ THE SOFTWARE.
2654
2824
  *************************************************************************/
2655
2825
  _createDeleteDialogDiv: function () {
2656
2826
  var self = this;
2657
-
2827
+
2658
2828
  //Check if deleteAction is supplied
2659
2829
  if (!self.options.actions.deleteAction) {
2660
2830
  return;
@@ -2680,14 +2850,14 @@ THE SOFTWARE.
2680
2850
  id: 'DeleteDialogButton',
2681
2851
  text: self.options.messages.deleteText,
2682
2852
  click: function () {
2683
-
2853
+
2684
2854
  //row maybe removed by another source, if so, do nothing
2685
2855
  if (self._$deletingRow.hasClass('jtable-row-removed')) {
2686
2856
  self._$deleteRecordDiv.dialog('close');
2687
2857
  return;
2688
2858
  }
2689
2859
 
2690
- var $deleteButton = $('#DeleteDialogButton');
2860
+ var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
2691
2861
  self._setEnabledOfDialogButton($deleteButton, false, self.options.messages.deleting);
2692
2862
  self._deleteRecordFromServer(
2693
2863
  self._$deletingRow,
@@ -2703,7 +2873,7 @@ THE SOFTWARE.
2703
2873
  }
2704
2874
  }],
2705
2875
  close: function () {
2706
- var $deleteButton = $('#DeleteDialogButton');
2876
+ var $deleteButton = self._$deleteRecordDiv.parent().find('#DeleteDialogButton');
2707
2877
  self._setEnabledOfDialogButton($deleteButton, true, self.options.messages.deleteText);
2708
2878
  }
2709
2879
  });
@@ -2722,7 +2892,7 @@ THE SOFTWARE.
2722
2892
  self._logWarn('No rows specified to jTable deleteRows method.');
2723
2893
  return;
2724
2894
  }
2725
-
2895
+
2726
2896
  if (self._isBusy()) {
2727
2897
  self._logWarn('Can not delete rows since jTable is busy!');
2728
2898
  return;
@@ -2929,11 +3099,28 @@ THE SOFTWARE.
2929
3099
  },
2930
3100
 
2931
3101
  /* Performs an ajax call to server to delete record
2932
- * and removesd row of record from table if ajax call success.
3102
+ * and removes row of the record from table if ajax call success.
2933
3103
  *************************************************************************/
2934
3104
  _deleteRecordFromServer: function ($row, success, error, url) {
2935
3105
  var self = this;
2936
3106
 
3107
+ var completeDelete = function(data) {
3108
+ if (data.Result != 'OK') {
3109
+ $row.data('deleting', false);
3110
+ if (error) {
3111
+ error(data.Message);
3112
+ }
3113
+
3114
+ return;
3115
+ }
3116
+
3117
+ self._trigger("recordDeleted", null, { record: $row.data('record'), row: $row, serverResponse: data });
3118
+
3119
+ if (success) {
3120
+ success(data);
3121
+ }
3122
+ };
3123
+
2937
3124
  //Check if it is already being deleted right now
2938
3125
  if ($row.data('deleting') == true) {
2939
3126
  return;
@@ -2943,34 +3130,45 @@ THE SOFTWARE.
2943
3130
 
2944
3131
  var postData = {};
2945
3132
  postData[self._keyField] = self._getKeyValueOfRecord($row.data('record'));
2946
-
2947
- this._ajax({
2948
- url: (url || self.options.actions.deleteAction),
2949
- data: postData,
2950
- success: function (data) {
2951
-
2952
- if (data.Result != 'OK') {
3133
+
3134
+ //deleteAction may be a function, check if it is
3135
+ if (!url && $.isFunction(self.options.actions.deleteAction)) {
3136
+
3137
+ //Execute the function
3138
+ var funcResult = self.options.actions.deleteAction(postData);
3139
+
3140
+ //Check if result is a jQuery Deferred object
3141
+ if (self._isDeferredObject(funcResult)) {
3142
+ //Wait promise
3143
+ funcResult.done(function (data) {
3144
+ completeDelete(data);
3145
+ }).fail(function () {
2953
3146
  $row.data('deleting', false);
2954
3147
  if (error) {
2955
- error(data.Message);
3148
+ error(self.options.messages.serverCommunicationError);
2956
3149
  }
3150
+ });
3151
+ } else { //assume it returned the deletion result
3152
+ completeDelete(funcResult);
3153
+ }
2957
3154
 
2958
- return;
3155
+ } else { //Assume it's a URL string
3156
+ //Make ajax call to delete the record from server
3157
+ this._ajax({
3158
+ url: (url || self.options.actions.deleteAction),
3159
+ data: postData,
3160
+ success: function (data) {
3161
+ completeDelete(data);
3162
+ },
3163
+ error: function () {
3164
+ $row.data('deleting', false);
3165
+ if (error) {
3166
+ error(self.options.messages.serverCommunicationError);
3167
+ }
2959
3168
  }
3169
+ });
2960
3170
 
2961
- self._trigger("recordDeleted", null, { record: $row.data('record'), row: $row, serverResponse: data });
2962
-
2963
- if (success) {
2964
- success(data);
2965
- }
2966
- },
2967
- error: function () {
2968
- $row.data('deleting', false);
2969
- if (error) {
2970
- error(self.options.messages.serverCommunicationError);
2971
- }
2972
- }
2973
- });
3171
+ }
2974
3172
  },
2975
3173
 
2976
3174
  /* Removes a row from table after a 'deleting' animation.
@@ -2987,7 +3185,7 @@ THE SOFTWARE.
2987
3185
  if (this.options.jqueryuiTheme) {
2988
3186
  className = className + ' ui-state-disabled';
2989
3187
  }
2990
-
3188
+
2991
3189
  //Stop current animation (if does exists) and begin 'deleting' animation.
2992
3190
  $rows.stop(true, true).addClass(className, 'slow', '').promise().done(function () {
2993
3191
  self._removeRowsFromTable($rows, 'deleted');
@@ -3397,6 +3595,7 @@ THE SOFTWARE.
3397
3595
  _create: $.hik.jtable.prototype._create,
3398
3596
  _setOption: $.hik.jtable.prototype._setOption,
3399
3597
  _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
3598
+ _createJtParamsForLoading: $.hik.jtable.prototype._createJtParamsForLoading,
3400
3599
  _addRowToTable: $.hik.jtable.prototype._addRowToTable,
3401
3600
  _addRow: $.hik.jtable.prototype._addRow,
3402
3601
  _removeRowsFromTable: $.hik.jtable.prototype._removeRowsFromTable,
@@ -3443,7 +3642,7 @@ THE SOFTWARE.
3443
3642
 
3444
3643
  /* Overrides base method to do paging-specific constructions.
3445
3644
  *************************************************************************/
3446
- _create: function () {
3645
+ _create: function() {
3447
3646
  base._create.apply(this, arguments);
3448
3647
  if (this.options.paging) {
3449
3648
  this._loadPagingSettings();
@@ -3456,7 +3655,7 @@ THE SOFTWARE.
3456
3655
 
3457
3656
  /* Loads user preferences for paging.
3458
3657
  *************************************************************************/
3459
- _loadPagingSettings: function () {
3658
+ _loadPagingSettings: function() {
3460
3659
  if (!this.options.saveUserPreferences) {
3461
3660
  return;
3462
3661
  }
@@ -3469,7 +3668,7 @@ THE SOFTWARE.
3469
3668
 
3470
3669
  /* Creates bottom panel and adds to the page.
3471
3670
  *************************************************************************/
3472
- _createBottomPanel: function () {
3671
+ _createBottomPanel: function() {
3473
3672
  this._$bottomPanel = $('<div />')
3474
3673
  .addClass('jtable-bottom-panel')
3475
3674
  .insertAfter(this._$table);
@@ -3482,7 +3681,7 @@ THE SOFTWARE.
3482
3681
 
3483
3682
  /* Creates page list area.
3484
3683
  *************************************************************************/
3485
- _createPageListArea: function () {
3684
+ _createPageListArea: function() {
3486
3685
  this._$pagingListArea = $('<span></span>')
3487
3686
  .addClass('jtable-page-list')
3488
3687
  .appendTo(this._$bottomPanel.find('.jtable-left-area'));
@@ -3494,7 +3693,7 @@ THE SOFTWARE.
3494
3693
 
3495
3694
  /* Creates page list change area.
3496
3695
  *************************************************************************/
3497
- _createPageSizeSelection: function () {
3696
+ _createPageSizeSelection: function() {
3498
3697
  var self = this;
3499
3698
 
3500
3699
  if (!self.options.pageSizeChangeArea) {
@@ -3504,7 +3703,7 @@ THE SOFTWARE.
3504
3703
  //Add current page size to page sizes list if not contains it
3505
3704
  if (self._findIndexInArray(self.options.pageSize, self.options.pageSizes) < 0) {
3506
3705
  self.options.pageSizes.push(parseInt(self.options.pageSize));
3507
- self.options.pageSizes.sort(function (a, b) { return a - b; });
3706
+ self.options.pageSizes.sort(function(a, b) { return a - b; });
3508
3707
  }
3509
3708
 
3510
3709
  //Add a span to contain page size change items
@@ -3527,14 +3726,14 @@ THE SOFTWARE.
3527
3726
  $pageSizeChangeCombobox.val(self.options.pageSize);
3528
3727
 
3529
3728
  //Change page size on combobox change
3530
- $pageSizeChangeCombobox.change(function () {
3729
+ $pageSizeChangeCombobox.change(function() {
3531
3730
  self._changePageSize(parseInt($(this).val()));
3532
3731
  });
3533
3732
  },
3534
3733
 
3535
3734
  /* Creates go to page area.
3536
3735
  *************************************************************************/
3537
- _createGotoPageInput: function () {
3736
+ _createGotoPageInput: function() {
3538
3737
  var self = this;
3539
3738
 
3540
3739
  if (!self.options.gotoPageArea || self.options.gotoPageArea == 'none') {
@@ -3555,7 +3754,7 @@ THE SOFTWARE.
3555
3754
  self._$gotoPageInput = $('<select></select>')
3556
3755
  .appendTo(this._$gotoPageArea)
3557
3756
  .data('pageCount', 1)
3558
- .change(function () {
3757
+ .change(function() {
3559
3758
  self._changePage(parseInt($(this).val()));
3560
3759
  });
3561
3760
  self._$gotoPageInput.append('<option value="1">1</option>');
@@ -3564,7 +3763,7 @@ THE SOFTWARE.
3564
3763
 
3565
3764
  self._$gotoPageInput = $('<input type="text" maxlength="10" value="' + self._currentPageNo + '" />')
3566
3765
  .appendTo(this._$gotoPageArea)
3567
- .keypress(function (event) {
3766
+ .keypress(function(event) {
3568
3767
  if (event.which == 13) { //enter
3569
3768
  event.preventDefault();
3570
3769
  self._changePage(parseInt(self._$gotoPageInput.val()));
@@ -3593,7 +3792,7 @@ THE SOFTWARE.
3593
3792
 
3594
3793
  /* Refreshes the 'go to page' input.
3595
3794
  *************************************************************************/
3596
- _refreshGotoPageInput: function () {
3795
+ _refreshGotoPageInput: function() {
3597
3796
  if (!this.options.gotoPageArea || this.options.gotoPageArea == 'none') {
3598
3797
  return;
3599
3798
  }
@@ -3640,7 +3839,7 @@ THE SOFTWARE.
3640
3839
 
3641
3840
  /* Overrides load method to set current page to 1.
3642
3841
  *************************************************************************/
3643
- load: function () {
3842
+ load: function() {
3644
3843
  this._currentPageNo = 1;
3645
3844
 
3646
3845
  base.load.apply(this, arguments);
@@ -3648,7 +3847,7 @@ THE SOFTWARE.
3648
3847
 
3649
3848
  /* Used to change options dynamically after initialization.
3650
3849
  *************************************************************************/
3651
- _setOption: function (key, value) {
3850
+ _setOption: function(key, value) {
3652
3851
  base._setOption.apply(this, arguments);
3653
3852
 
3654
3853
  if (key == 'pageSize') {
@@ -3658,7 +3857,7 @@ THE SOFTWARE.
3658
3857
 
3659
3858
  /* Changes current page size with given value.
3660
3859
  *************************************************************************/
3661
- _changePageSize: function (pageSize) {
3860
+ _changePageSize: function(pageSize) {
3662
3861
  if (pageSize == this.options.pageSize) {
3663
3862
  return;
3664
3863
  }
@@ -3691,7 +3890,7 @@ THE SOFTWARE.
3691
3890
 
3692
3891
  /* Saves user preferences for paging
3693
3892
  *************************************************************************/
3694
- _savePagingSettings: function () {
3893
+ _savePagingSettings: function() {
3695
3894
  if (!this.options.saveUserPreferences) {
3696
3895
  return;
3697
3896
  }
@@ -3701,12 +3900,25 @@ THE SOFTWARE.
3701
3900
 
3702
3901
  /* Overrides _createRecordLoadUrl method to add paging info to URL.
3703
3902
  *************************************************************************/
3704
- _createRecordLoadUrl: function () {
3903
+ _createRecordLoadUrl: function() {
3705
3904
  var loadUrl = base._createRecordLoadUrl.apply(this, arguments);
3706
3905
  loadUrl = this._addPagingInfoToUrl(loadUrl, this._currentPageNo);
3707
3906
  return loadUrl;
3708
3907
  },
3709
3908
 
3909
+ /* Overrides _createJtParamsForLoading method to add paging parameters to jtParams object.
3910
+ *************************************************************************/
3911
+ _createJtParamsForLoading: function () {
3912
+ var jtParams = base._createJtParamsForLoading.apply(this, arguments);
3913
+
3914
+ if (this.options.paging) {
3915
+ jtParams.jtStartIndex = (this._currentPageNo - 1) * this.options.pageSize;
3916
+ jtParams.jtPageSize = this.options.pageSize;
3917
+ }
3918
+
3919
+ return jtParams;
3920
+ },
3921
+
3710
3922
  /* Overrides _addRowToTable method to re-load table when a new row is created.
3711
3923
  * NOTE: THIS METHOD IS DEPRECATED AND WILL BE REMOVED FROM FEATURE RELEASES.
3712
3924
  * USE _addRow METHOD.
@@ -3979,7 +4191,8 @@ THE SOFTWARE.
3979
4191
  _initializeFields: $.hik.jtable.prototype._initializeFields,
3980
4192
  _normalizeFieldOptions: $.hik.jtable.prototype._normalizeFieldOptions,
3981
4193
  _createHeaderCellForField: $.hik.jtable.prototype._createHeaderCellForField,
3982
- _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl
4194
+ _createRecordLoadUrl: $.hik.jtable.prototype._createRecordLoadUrl,
4195
+ _createJtParamsForLoading: $.hik.jtable.prototype._createJtParamsForLoading
3983
4196
  };
3984
4197
 
3985
4198
  //extension members
@@ -4148,6 +4361,23 @@ THE SOFTWARE.
4148
4361
  });
4149
4362
 
4150
4363
  return (url + (url.indexOf('?') < 0 ? '?' : '&') + 'jtSorting=' + sorting.join(","));
4364
+ },
4365
+
4366
+ /* Overrides _createJtParamsForLoading method to add sorging parameters to jtParams object.
4367
+ *************************************************************************/
4368
+ _createJtParamsForLoading: function () {
4369
+ var jtParams = base._createJtParamsForLoading.apply(this, arguments);
4370
+
4371
+ if (this.options.sorting && this._lastSorting.length) {
4372
+ var sorting = [];
4373
+ $.each(this._lastSorting, function (idx, value) {
4374
+ sorting.push(value.fieldName + ' ' + value.sortOrder);
4375
+ });
4376
+
4377
+ jtParams.jtSorting = sorting.join(",");
4378
+ }
4379
+
4380
+ return jtParams;
4151
4381
  }
4152
4382
 
4153
4383
  });