jquery-datatables-rails 0.1.0 → 1.9.0

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.
Files changed (31) hide show
  1. data/.gitignore +1 -0
  2. data/lib/jquery/datatables/rails/version.rb +1 -1
  3. data/vendor/assets/images/dataTables/back_disabled.png +0 -0
  4. data/vendor/assets/images/dataTables/back_enabled.png +0 -0
  5. data/vendor/assets/images/dataTables/back_enabled_hover.png +0 -0
  6. data/vendor/assets/images/dataTables/favicon.ico +0 -0
  7. data/vendor/assets/images/dataTables/forward_disabled.png +0 -0
  8. data/vendor/assets/images/dataTables/forward_enabled.png +0 -0
  9. data/vendor/assets/images/dataTables/forward_enabled_hover.png +0 -0
  10. data/vendor/assets/images/dataTables/sort_asc.png +0 -0
  11. data/vendor/assets/images/dataTables/sort_asc_disabled.png +0 -0
  12. data/vendor/assets/images/dataTables/sort_both.png +0 -0
  13. data/vendor/assets/images/dataTables/sort_desc.png +0 -0
  14. data/vendor/assets/images/dataTables/sort_desc_disabled.png +0 -0
  15. data/vendor/assets/javascripts/jquery.dataTables.editable.js +1017 -0
  16. data/vendor/assets/javascripts/jquery.dataTables.fnReloadAjax.js +4 -3
  17. data/vendor/assets/javascripts/jquery.dataTables.js +9882 -5617
  18. data/vendor/assets/javascripts/jquery.dataTables.min.js +141 -139
  19. data/vendor/assets/javascripts/jquery.jeditable.js +507 -0
  20. data/vendor/assets/javascripts/jquery.validate.js +1150 -0
  21. data/vendor/assets/stylesheets/dataTables/demo_page.css +107 -0
  22. data/vendor/assets/stylesheets/dataTables/demo_table.css +59 -22
  23. data/vendor/assets/stylesheets/dataTables/demo_table_jui.css +17 -16
  24. data/vendor/assets/stylesheets/dataTables/jquery.dataTables.css +219 -0
  25. data/vendor/assets/stylesheets/dataTables/jquery.dataTables_themeroller.css +243 -0
  26. metadata +18 -10
  27. data/vendor/assets/images/dataTables/back_disabled.jpg +0 -0
  28. data/vendor/assets/images/dataTables/back_enabled.jpg +0 -0
  29. data/vendor/assets/images/dataTables/forward_disabled.jpg +0 -0
  30. data/vendor/assets/images/dataTables/forward_enabled.jpg +0 -0
  31. data/vendor/assets/javascripts/jquery.dataTables.min.js.gz +0 -0
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .DS_Store
@@ -1,7 +1,7 @@
1
1
  module Jquery
2
2
  module Datatables
3
3
  module Rails
4
- VERSION = "0.1.0"
4
+ VERSION = "1.9.0"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,1017 @@
1
+ /*
2
+ * File: jquery.dataTables.editable.js
3
+ * Version: 1.3.2
4
+ * Author: Jovan Popovic
5
+ *
6
+ * Copyright 2010-2011 Jovan Popovic, all rights reserved.
7
+ *
8
+ * This source file is free software, under either the GPL v2 license or a
9
+ * BSD style license, as supplied with this software.
10
+ *
11
+ * This source file is distributed in the hope that it will be useful, but
12
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
+ * or FITNESS FOR A PARTICULAR PURPOSE.
14
+ *
15
+ * Parameters:
16
+ * @sUpdateURL String URL of the server-side page used for updating cell. Default value is "UpdateData".
17
+ * @sAddURL String URL of the server-side page used for adding new row. Default value is "AddData".
18
+ * @sDeleteURL String URL of the server-side page used to delete row by id. Default value is "DeleteData".
19
+ * @fnShowError Function function(message, action){...} used to show error message. Action value can be "update", "add" or "delete".
20
+ * @sAddNewRowFormId String Id of the form for adding new row. Default id is "formAddNewRow".
21
+ * @oAddNewRowFormOptions Object Options that will be set to the "Add new row" dialog
22
+ * @sAddNewRowButtonId String Id of the button for adding new row. Default id is "btnAddNewRow".
23
+ * @oAddNewRowButtonOptions Object Options that will be set to the "Add new" button
24
+ * @sAddNewRowOkButtonId String Id of the OK button placed in add new row dialog. Default value is "btnAddNewRowOk".
25
+ * @oAddNewRowOkButtonOptions Object Options that will be set to the Ok button in the "Add new row" form
26
+ * @sAddNewRowCancelButtonId String Id of the Cancel button placed in add new row dialog. Default value is "btnAddNewRowCancel".
27
+ * @oAddNewRowCancelButtonOptions Object Options that will be set to the Cancel button in the "Add new row" form
28
+ * @sDeleteRowButtonId String Id of the button for adding new row. Default id is "btnDeleteRow".
29
+ * @oDeleteRowButtonOptions Object Options that will be set to the Delete button
30
+ * @sSelectedRowClass String Class that will be associated to the selected row. Default class is "row_selected".
31
+ * @sReadOnlyCellClass String Class of the cells that should not be editable. Default value is "read_only".
32
+ * @sAddDeleteToolbarSelector String Selector used to identify place where add and delete buttons should be placed. Default value is ".add_delete_toolbar".
33
+ * @fnStartProcessingMode Function function(){...} called when AJAX call is started. Use this function to add "Please wait..." message when some button is pressed.
34
+ * @fnEndProcessingMode Function function(){...} called when AJAX call is ended. Use this function to close "Please wait..." message.
35
+ * @aoColumns Array Array of the JEditable settings that will be applied on the columns
36
+ * @sAddHttpMethod String Method used for the Add AJAX request (default is 'POST')
37
+ * @sDeleteHttpMethod String Method used for the Delete AJAX request (default is 'POST')
38
+ * @fnOnDeleting Function function(tr, id, fnDeleteRow){...} Function called before row is deleted.
39
+ tr isJQuery object encapsulating row that will be deleted
40
+ id is an id of the record that will be deleted.
41
+ fnDeleteRow(id) callback function that should be called to delete row with id
42
+ returns true if plugin should continue with deleting row, false will abort delete.
43
+ * @fnOnDeleted Function function(status){...} Function called after delete action. Status can be "success" or "failure"
44
+ * @fnOnAdding Function function(){...} Function called before row is added.
45
+ returns true if plugin should continue with adding row, false will abort add.
46
+ * @fnOnNewRowPosted Function function(data) Function that can override default function that is called when server-side sAddURL returns result
47
+ You can use this function to add different behaviour when server-side page returns result
48
+ * @fnOnAdded Function function(status){...} Function called after add action. Status can be "success" or "failure"
49
+ * @fnOnEditing Function function(input){...} Function called before cell is updated.
50
+ input JQuery object wrapping the inut element used for editing value in the cell.
51
+ returns true if plugin should continue with sending AJAX request, false will abort update.
52
+ * @fnOnEdited Function function(status){...} Function called after edit action. Status can be "success" or "failure"
53
+ * @sEditorHeight String Default height of the cell editors
54
+ * @sEditorWidth String Default width of the cell editors
55
+ * @oDeleteParameters Object Additonal objects added to the DELETE Ajax request
56
+ * @sIDToken String Token in the add new row dialog that will be replaced with a returned id of the record that is created
57
+ */
58
+ (function ($) {
59
+
60
+ $.fn.makeEditable = function (options) {
61
+
62
+ var iDisplayStart = 0;
63
+
64
+ ///Utility function used to determine id of the cell
65
+ //By default it is assumed that id is placed as an id attribute of <tr> that that surround the cell (<td> tag). E.g.:
66
+ //<tr id="17">
67
+ // <td>...</td><td>...</td><td>...</td><td>...</td>
68
+ //</tr>
69
+ function fnGetCellID(cell) {
70
+ return properties.fnGetRowID($(cell.parentNode));
71
+ }
72
+
73
+ ///Utility function used to set id of the new row
74
+ //It is assumed that id is placed as an id attribute of <tr> that that surround the cell (<td> tag). E.g.:
75
+ //<tr id="17">
76
+ // <td>...</td><td>...</td><td>...</td><td>...</td>
77
+ //</tr>
78
+ function _fnSetRowIDInAttribute(row, id) {
79
+ row.attr("id", id);
80
+ }
81
+
82
+ //Utility function used to get id of the row
83
+ //It is assumed that id is placed as an id attribute of <tr> that that surround the cell (<td> tag). E.g.:
84
+ //<tr id="17">
85
+ // <td>...</td><td>...</td><td>...</td><td>...</td>
86
+ //</tr>
87
+ function _fnGetRowIDFromAttribute(row) {
88
+ return row.attr("id");
89
+ }
90
+
91
+ //Utility function used to set id of the new row
92
+ //It is assumed that id is placed as an id attribute of <tr> that that surround the cell (<td> tag). E.g.:
93
+ //<tr>
94
+ // <td>17</td><td>...</td><td>...</td><td>...</td>
95
+ //</tr>
96
+ function _fnSetRowIDInFirstCell(row, id) {
97
+ $("td:first", row).html(id);
98
+ }
99
+
100
+ //Utility function used to get id of the row
101
+ //It is assumed that id is placed as an id attribute of <tr> that that surround the cell (<td> tag). E.g.:
102
+ //<tr>
103
+ // <td>17</td><td>...</td><td>...</td><td>...</td>
104
+ //</tr>
105
+ function _fnGetRowIDFromFirstCell(row) {
106
+ return $("td:first", row).html();
107
+ }
108
+
109
+ //Reference to the DataTable object
110
+ var oTable;
111
+ //Refences to the buttons used for manipulating table data
112
+ var oAddNewRowButton, oDeleteRowButton, oConfirmRowAddingButton, oCancelRowAddingButton;
113
+ //Reference to the form used for adding new data
114
+ var oAddNewRowForm;
115
+
116
+ //Plugin options
117
+ var properties;
118
+
119
+ /// Utility function that shows an error message
120
+ ///@param errorText - text that should be shown
121
+ ///@param action - action that was executed when error occured e.g. "update", "delete", or "add"
122
+ function fnShowError(errorText, action) {
123
+ alert(errorText);
124
+ }
125
+
126
+ //Utility function that put the table into the "Processing" state
127
+ function fnStartProcessingMode() {
128
+ if (oTable.fnSettings().oFeatures.bProcessing) {
129
+ $(".dataTables_processing").css('visibility', 'visible');
130
+ }
131
+ }
132
+
133
+ //Utility function that put the table in the normal state
134
+ function fnEndProcessingMode() {
135
+ if (oTable.fnSettings().oFeatures.bProcessing) {
136
+ $(".dataTables_processing").css('visibility', 'hidden');
137
+ }
138
+ }
139
+
140
+ var sOldValue, sNewCellValue, sNewCellDislayValue;
141
+ //Utility function used to apply editable plugin on table cells
142
+ function _fnApplyEditable(aoNodes) {
143
+ if (properties.bDisableEditing)
144
+ return;
145
+ var oDefaultEditableSettings = {
146
+ event: 'dblclick',
147
+ "callback": function (sValue, settings) {
148
+ properties.fnEndProcessingMode();
149
+ var status = "";
150
+ var aPos = oTable.fnGetPosition(this);
151
+ if (sNewCellValue == sValue) {
152
+ oTable.fnUpdate(sNewCellDisplayValue, aPos[0], aPos[2]);
153
+ $("td.last-updated-cell", oTable).removeClass("last-updated-cell");
154
+ $(this).addClass("last-updated-cell");
155
+ status = "success";
156
+ } else {
157
+ oTable.fnUpdate(sOldValue, aPos[0], aPos[2]);
158
+ properties.fnShowError(sValue, "update");
159
+ status = "failure";
160
+ }
161
+
162
+ properties.fnOnEdited(status, sOldValue, sNewCellDisplayValue, aPos[0], aPos[1], aPos[2]);
163
+ if (settings.fnOnCellUpdated != null) {
164
+ settings.fnOnCellUpdated(status, sValue, aPos[0], aPos[2], settings);
165
+ }
166
+ _fnSetDisplayStart();
167
+
168
+ },
169
+ "onsubmit": function (settings, original) {
170
+ var input = $("input,select,textarea", this);
171
+ sOldValue = original.revert;
172
+ sNewCellValue = $("input,select,textarea", $(this)).val();
173
+ if (input.length == 1) {
174
+ var oEditElement = input[0];
175
+ if (oEditElement.nodeName.toLowerCase() == "select" || oEditElement.tagName.toLowerCase() == "select")
176
+ sNewCellDisplayValue = $("option:selected", oEditElement).text(); //For select list use selected text instead of value for displaying in table
177
+ else
178
+ sNewCellDisplayValue = sNewCellValue;
179
+ }
180
+
181
+ if (!properties.fnOnEditing(input))
182
+ return false;
183
+ var x = settings;
184
+ if (settings.cssclass != null) {
185
+ input.addClass(settings.cssclass);
186
+ if (!input.valid() || 0 == input.valid())
187
+ return false;
188
+ else
189
+ return true;
190
+ }
191
+ },
192
+ "submitdata": function (value, settings) {
193
+ iDisplayStart = _fnGetDisplayStart();
194
+ properties.fnStartProcessingMode();
195
+ var id = fnGetCellID(this);
196
+ var rowId = oTable.fnGetPosition(this)[0];
197
+ var columnPosition = oTable.fnGetPosition(this)[1];
198
+ var columnId = oTable.fnGetPosition(this)[2];
199
+ var sColumnName = oTable.fnSettings().aoColumns[columnId].sName;
200
+ if (sColumnName == null || sColumnName == "")
201
+ sColumnName = oTable.fnSettings().aoColumns[columnId].sTitle;
202
+ return {
203
+ "id": id,
204
+ "rowId": rowId,
205
+ "columnPosition": columnPosition,
206
+ "columnId": columnId,
207
+ "columnName": sColumnName
208
+ };
209
+ },
210
+ "onerror": function () {
211
+ properties.fnEndProcessingMode();
212
+ properties.fnShowError("Cell cannot be updated(Server error)", "update");
213
+ properties.fnOnEdited("failure");
214
+ },
215
+ "height": properties.sEditorHeight,
216
+ "width": properties.sEditorWidth
217
+ };
218
+
219
+ var cells = null;
220
+ if (properties.aoColumns != null) {
221
+ for (var i = 0; i < properties.aoColumns.length; i++) {
222
+ if (properties.aoColumns[i] != null) {
223
+ cells = $("td:nth-child(" + (i + 1) + ")", aoNodes);
224
+ var oColumnSettings = oDefaultEditableSettings;
225
+ oColumnSettings = $.extend({}, oDefaultEditableSettings, properties.aoColumns[i]);
226
+ var sUpdateURL = properties.sUpdateURL;
227
+ try {
228
+ if (oColumnSettings.sUpdateURL != null)
229
+ sUpdateURL = oColumnSettings.sUpdateURL;
230
+ } catch (ex) {
231
+ }
232
+ cells.editable(sUpdateURL, oColumnSettings);
233
+ }
234
+
235
+
236
+ }
237
+ } else {
238
+ cells = $('td:not(.' + properties.sReadOnlyCellClass + ')', aoNodes);
239
+ cells.editable(properties.sUpdateURL, oDefaultEditableSettings);
240
+
241
+ }
242
+
243
+ }
244
+
245
+ //Called when user confirm that he want to add new record
246
+ function _fnOnRowAdding(event) {
247
+ if (properties.fnOnAdding()) {
248
+ if (oAddNewRowForm.valid()) {
249
+ iDisplayStart = _fnGetDisplayStart();
250
+ properties.fnStartProcessingMode();
251
+
252
+ if (properties.bUseFormsPlugin) {
253
+ //Still in beta(development)
254
+ $(oAddNewRowForm).ajaxSubmit({
255
+ success: function (response, statusString, xhr) {
256
+ if (response.toLowerCase().indexOf("error") != -1 || statusString != "success") {
257
+ properties.fnEndProcessingMode();
258
+ properties.fnShowError(response, "add");
259
+ properties.fnOnAdded("failure");
260
+ } else {
261
+ _fnOnRowAdded(response);
262
+ }
263
+
264
+ },
265
+ error: function (response) {
266
+ properties.fnEndProcessingMode();
267
+ properties.fnShowError(response.responseText, "add");
268
+ properties.fnOnAdded("failure");
269
+ }
270
+ }
271
+ );
272
+
273
+ } else {
274
+
275
+ var params = oAddNewRowForm.serialize();
276
+ $.ajax({ 'url': properties.sAddURL,
277
+ 'data': params,
278
+ 'type': properties.sAddHttpMethod,
279
+ "dataType": "text",
280
+ success: _fnOnRowAdded,
281
+ error: function (response) {
282
+ properties.fnEndProcessingMode();
283
+ properties.fnShowError(response.responseText, "add");
284
+ properties.fnOnAdded("failure");
285
+ }
286
+ });
287
+ }
288
+ }
289
+ }
290
+ event.stopPropagation();
291
+ event.preventDefault();
292
+ }
293
+
294
+ function _fnOnNewRowPosted(data) {
295
+
296
+ return true;
297
+
298
+ }
299
+ ///Event handler called when a new row is added and response is returned from server
300
+ function _fnOnRowAdded(data) {
301
+ properties.fnEndProcessingMode();
302
+
303
+ if (properties.fnOnNewRowPosted(data)) {
304
+
305
+ var oSettings = oTable.fnSettings();
306
+ var iColumnCount = oSettings.aoColumns.length;
307
+ var values = new Array();
308
+
309
+ $("input:text[rel],input:radio[rel][checked],input:hidden[rel],select[rel],textarea[rel],span.datafield[rel]", oAddNewRowForm).each(function () {
310
+ var rel = $(this).attr("rel");
311
+ var sCellValue = "";
312
+ if (rel >= iColumnCount)
313
+ properties.fnShowError("In the add form is placed input element with the name '" + $(this).attr("name") + "' with the 'rel' attribute that must be less than a column count - " + iColumnCount, "add");
314
+ else {
315
+ if (this.nodeName.toLowerCase() == "select" || this.tagName.toLowerCase() == "select"){
316
+ //sCellValue = $("option:selected", this).text();
317
+ sCellValue = $.map(
318
+ $.makeArray($("option:selected", this)),
319
+ function (n, i) {
320
+ return $(n).text();
321
+ }).join(",");
322
+
323
+ }
324
+ else if (this.nodeName.toLowerCase() == "span" || this.tagName.toLowerCase() == "span")
325
+ sCellValue = $(this).html();
326
+ else
327
+ sCellValue = this.value;
328
+
329
+ sCellValue = sCellValue.replace(properties.sIDToken, data);
330
+ values[rel] = sCellValue;
331
+ }
332
+ });
333
+
334
+ //Add values from the form into the table
335
+ var rtn = oTable.fnAddData(values);
336
+ var oTRAdded = oTable.fnGetNodes(rtn);
337
+ //Apply editable plugin on the cells of the table
338
+ _fnApplyEditable(oTRAdded);
339
+ //add id returned by server page as an TR id attribute
340
+ properties.fnSetRowID($(oTRAdded), data);
341
+
342
+ $("tr.last-added-row", oTable).removeClass("last-added-row");
343
+ $(oTRAdded).addClass("last-added-row");
344
+
345
+ //Close the dialog
346
+ oAddNewRowForm.dialog('close');
347
+ $(oAddNewRowForm)[0].reset();
348
+ $(".error", $(oAddNewRowForm)).html("");
349
+
350
+ _fnSetDisplayStart();
351
+ properties.fnOnAdded("success");
352
+ }
353
+ }
354
+
355
+ //Called when user cancels adding new record in the popup dialog
356
+ function _fnOnCancelRowAdding(event) {
357
+ //Clear the validation messages and reset form
358
+ $(oAddNewRowForm).validate().resetForm(); // Clears the validation errors
359
+ $(oAddNewRowForm)[0].reset();
360
+
361
+ $(".error", $(oAddNewRowForm)).html("");
362
+ $(".error", $(oAddNewRowForm)).hide(); // Hides the error element
363
+
364
+ //Close the dialog
365
+ oAddNewRowForm.dialog('close');
366
+ event.stopPropagation();
367
+ event.preventDefault();
368
+ }
369
+
370
+
371
+
372
+ function _fnDisableDeleteButton() {
373
+ if (properties.oDeleteRowButtonOptions != null) {
374
+ //oDeleteRowButton.disable();
375
+ oDeleteRowButton.button("option", "disabled", true);
376
+ } else {
377
+ oDeleteRowButton.attr("disabled", "true");
378
+ }
379
+ }
380
+
381
+ function _fnEnableDeleteButton() {
382
+ if (properties.oDeleteRowButtonOptions != null) {
383
+ //oDeleteRowButton.enable();
384
+ oDeleteRowButton.button("option", "disabled", false);
385
+ } else {
386
+ oDeleteRowButton.removeAttr("disabled");
387
+ }
388
+ }
389
+
390
+ function _fnDeleteRow(id, sDeleteURL) {
391
+ var sURL = sDeleteURL;
392
+ if (sDeleteURL == null)
393
+ sURL = properties.sDeleteURL;
394
+ properties.fnStartProcessingMode();
395
+ var data = $.extend(properties.oDeleteParameters, { "id": id });
396
+ $.ajax({ 'url': sURL,
397
+ 'type': properties.sDeleteHttpMethod,
398
+ 'data': data,
399
+ "success": _fnOnRowDeleted,
400
+ "dataType": "text",
401
+ "error": function (response) {
402
+ properties.fnEndProcessingMode();
403
+ properties.fnShowError(response.responseText, "delete");
404
+ properties.fnOnDeleted("failure");
405
+
406
+ }
407
+ });
408
+ }
409
+
410
+ //Called when user deletes a row
411
+ function _fnOnRowDelete(event) {
412
+ iDisplayStart = _fnGetDisplayStart();
413
+ if ($('tr.' + properties.sSelectedRowClass + ' td', oTable).length == 0) {
414
+ //oDeleteRowButton.attr("disabled", "true");
415
+ _fnDisableDeleteButton();
416
+ return;
417
+ }
418
+ var id = fnGetCellID($('tr.' + properties.sSelectedRowClass + ' td', oTable)[0]);
419
+ if (properties.fnOnDeleting($('tr.' + properties.sSelectedRowClass, oTable), id, _fnDeleteRow)) {
420
+ _fnDeleteRow(id);
421
+ }
422
+ }
423
+
424
+ //Called when record is deleted on the server
425
+ function _fnOnRowDeleted(response) {
426
+ properties.fnEndProcessingMode();
427
+ var oTRSelected = $('tr.' + properties.sSelectedRowClass, oTable)[0];
428
+ if (response == "ok" || response == "") {
429
+ oTable.fnDeleteRow(oTRSelected);
430
+ //oDeleteRowButton.attr("disabled", "true");
431
+ _fnDisableDeleteButton();
432
+ _fnSetDisplayStart();
433
+ properties.fnOnDeleted("success");
434
+ }
435
+ else {
436
+ properties.fnShowError(response, "delete");
437
+ properties.fnOnDeleted("failure");
438
+ }
439
+ }
440
+
441
+ //Called before row is deleted
442
+ //Returning false will abort delete
443
+ /*
444
+ * Function called before row is deleted
445
+ * @param tr JQuery wrapped around the TR tag that will be deleted
446
+ * @param id id of the record that wil be deleted
447
+ * @return true if plugin should continue with deleting row, false will abort delete.
448
+ */
449
+ function fnOnDeleting(tr, id, fnDeleteRow) {
450
+ return confirm("Are you sure that you want to delete this record?"); ;
451
+ }
452
+
453
+ /* Function called after delete action
454
+ * @param result string
455
+ * "success" if row is actually deleted
456
+ * "failure" if delete failed
457
+ * @return void
458
+ */
459
+ function fnOnDeleted(result) { }
460
+
461
+ function fnOnEditing(input) { return true; }
462
+ function fnOnEdited(result, sOldValue, sNewValue, iRowIndex, iColumnIndex, iRealColumnIndex) {
463
+
464
+ }
465
+
466
+ function fnOnAdding() { return true; }
467
+ function fnOnAdded(result) { }
468
+
469
+ var oSettings;
470
+ function _fnGetDisplayStart() {
471
+ return oSettings._iDisplayStart;
472
+ }
473
+
474
+ function _fnSetDisplayStart() {
475
+ if (oSettings.oFeatures.bServerSide === false) {
476
+ oSettings._iDisplayStart = iDisplayStart;
477
+ oSettings.oApi._fnCalculateEnd(oSettings);
478
+ //draw the 'current' page
479
+ oSettings.oApi._fnDraw(oSettings);
480
+ }
481
+ }
482
+
483
+ function _fnOnBeforeAction(sAction) {
484
+ return true;
485
+ }
486
+
487
+ function _fnOnActionCompleted(sStatus) {
488
+ //alert("Action completed: " + sStatus);
489
+ }
490
+
491
+ function _fnGetActionSettings(sAction) {
492
+ if (properties.aoTableAction)
493
+ fnShowError("Configuration error - aoTableAction setting are not set", sAction);
494
+ var i = 0;
495
+
496
+ for (i = 0; i < properties.aoTableActions.length; i++) {
497
+ if (properties.aoTableActions[i].sAction == sAction)
498
+ return properties.aoTableActions[i];
499
+ }
500
+
501
+ fnShowError("Cannot find action configuration settings", sAction);
502
+ }
503
+
504
+
505
+ function _fnUpdateRow(oActionForm) {
506
+ var sAction = $(oActionForm).attr("id");
507
+ sAction = sAction.replace("form", "");
508
+ var sActionURL = $(oActionForm).attr("action");
509
+ if (properties.fnOnBeforeAction(sAction)) {
510
+ if ($(oActionForm).valid()) {
511
+ iDisplayStart = _fnGetDisplayStart();
512
+ properties.fnStartProcessingMode();
513
+ if (properties.bUseFormsPlugin) {
514
+
515
+ //Still in beta(development)
516
+ var oAjaxSubmitOptions = {
517
+ success: function (response, statusString, xhr) {
518
+ properties.fnEndProcessingMode();
519
+ if (response.toLowerCase().indexOf("error") != -1 || statusString != "success") {
520
+ properties.fnShowError(response, sAction);
521
+ properties.fnOnActionCompleted("failure");
522
+ } else {
523
+ _fnUpdateRowOnSuccess(oActionForm);
524
+ properties.fnOnActionCompleted("success");
525
+ }
526
+
527
+ },
528
+ error: function (response) {
529
+ properties.fnEndProcessingMode();
530
+ properties.fnShowError(response.responseText, sAction);
531
+ properties.fnOnActionCompleted("failure");
532
+ }
533
+ };
534
+ var oActionSettings = _fnGetActionSettings(sAction);
535
+ oAjaxSubmitOptions = $.extend({}, properties.oAjaxSubmitOptions, oAjaxSubmitOptions);
536
+ $(oActionForm).ajaxSubmit(oAjaxSubmitOptions);
537
+
538
+ } else {
539
+ var params = $(oActionForm).serialize();
540
+ $.ajax({ 'url': sActionURL,
541
+ 'data': params,
542
+ 'type': properties.sAddHttpMethod,
543
+ "dataType": "text",
544
+ success: function (response) {
545
+ properties.fnEndProcessingMode();
546
+ _fnUpdateRowOnSuccess(oActionForm);
547
+ properties.fnOnActionCompleted("success");
548
+ },
549
+ error: function (response) {
550
+ properties.fnEndProcessingMode();
551
+ properties.fnShowError(response.responseText, sAction);
552
+ properties.fnOnActionCompleted("failure");
553
+ }
554
+ });
555
+ }
556
+ }
557
+ }
558
+ }
559
+
560
+ function _fnUpdateRowOnSuccess(oActionForm) {
561
+
562
+ var iRowID = jQuery.data(oActionForm, 'ROWID');
563
+ //var iDataRowID = jQuery.data(oActionForm, 'DATAROWID');
564
+ var oSettings = oTable.fnSettings();
565
+ var iColumnCount = oSettings.aoColumns.length;
566
+ var values = new Array();
567
+
568
+ var sAction = $(oActionForm).attr("id");
569
+ sAction = sAction.replace("form", "");
570
+
571
+ //$("input.ROWID").val(iRowID);
572
+ //$("input.DATAROWID").val(iDataRowID);
573
+
574
+ $("input:text[rel],input:radio[rel][checked],input:hidden[rel],select[rel],textarea[rel],span.datafield[rel]", oActionForm).each(function () {
575
+ var rel = $(this).attr("rel");
576
+ var sCellValue = "";
577
+ if (rel >= iColumnCount)
578
+ properties.fnShowError("In the add form is placed input element with the name '" + $(this).attr("name") + "' with the 'rel' attribute that must be less than a column count - " + iColumnCount, "add");
579
+ else {
580
+ if (this.nodeName.toLowerCase() == "select" || this.tagName.toLowerCase() == "select")
581
+ sCellValue = $("option:selected", this).text();
582
+ else if (this.nodeName.toLowerCase() == "span" || this.tagName.toLowerCase() == "span")
583
+ sCellValue = $(this).html();
584
+ else
585
+ sCellValue = this.value;
586
+
587
+ //sCellValue = sCellValue.replace(properties.sIDToken, data);
588
+ //values[rel] = sCellValue;
589
+ oTable.fnUpdate(sCellValue, iRowID, rel);
590
+ }
591
+ });
592
+ $(oActionForm).dialog('close');
593
+
594
+
595
+ }
596
+
597
+ oTable = this;
598
+
599
+ var defaults = {
600
+
601
+ sUpdateURL: "UpdateData",
602
+ sAddURL: "AddData",
603
+ sDeleteURL: "DeleteData",
604
+ sAddNewRowFormId: "formAddNewRow",
605
+ oAddNewRowFormOptions: { autoOpen: false, modal: true },
606
+ sAddNewRowButtonId: "btnAddNewRow",
607
+ oAddNewRowButtonOptions: null,
608
+ sAddNewRowOkButtonId: "btnAddNewRowOk",
609
+ sAddNewRowCancelButtonId: "btnAddNewRowCancel",
610
+ oAddNewRowOkButtonOptions: { label: "Ok" },
611
+ oAddNewRowCancelButtonOptions: { label: "Cancel" },
612
+ sDeleteRowButtonId: "btnDeleteRow",
613
+ oDeleteRowButtonOptions: null,
614
+ sSelectedRowClass: "row_selected",
615
+ sReadOnlyCellClass: "read_only",
616
+ sAddDeleteToolbarSelector: ".add_delete_toolbar",
617
+ fnShowError: fnShowError,
618
+ fnStartProcessingMode: fnStartProcessingMode,
619
+ fnEndProcessingMode: fnEndProcessingMode,
620
+ aoColumns: null,
621
+ fnOnDeleting: fnOnDeleting,
622
+ fnOnDeleted: fnOnDeleted,
623
+ fnOnAdding: fnOnAdding,
624
+ fnOnNewRowPosted: _fnOnNewRowPosted,
625
+ fnOnAdded: fnOnAdded,
626
+ fnOnEditing: fnOnEditing,
627
+ fnOnEdited: fnOnEdited,
628
+ sAddHttpMethod: 'POST',
629
+ sDeleteHttpMethod: 'POST',
630
+ fnGetRowID: _fnGetRowIDFromAttribute,
631
+ fnSetRowID: _fnSetRowIDInAttribute,
632
+ sEditorHeight: "100%",
633
+ sEditorWidth: "100%",
634
+ bDisableEditing: false,
635
+ oDeleteParameters: {},
636
+ sIDToken: "DATAROWID",
637
+ aoTableActions: null,
638
+ fnOnBeforeAction: _fnOnBeforeAction,
639
+ bUseFormsPlugin: false,
640
+ fnOnActionCompleted: _fnOnActionCompleted
641
+
642
+
643
+ };
644
+
645
+ properties = $.extend(defaults, options);
646
+ oSettings = oTable.fnSettings();
647
+
648
+ return this.each(function () {
649
+
650
+ if (oTable.fnSettings().sAjaxSource != null) {
651
+ oTable.fnSettings().aoDrawCallback.push({
652
+ "fn": function () {
653
+ //Apply jEditable plugin on the table cells
654
+ _fnApplyEditable(oTable.fnGetNodes());
655
+ $(oTable.fnGetNodes()).each(function () {
656
+ var position = oTable.fnGetPosition(this);
657
+ var id = oTable.fnGetData(position)[0];
658
+ properties.fnSetRowID($(this), id);
659
+ }
660
+ );
661
+ },
662
+ "sName": "fnApplyEditable"
663
+ });
664
+
665
+ } else {
666
+ //Apply jEditable plugin on the table cells
667
+ _fnApplyEditable(oTable.fnGetNodes());
668
+ }
669
+
670
+ //Setup form to open in dialog
671
+ oAddNewRowForm = $("#" + properties.sAddNewRowFormId);
672
+ if (oAddNewRowForm.length != 0) {
673
+
674
+
675
+ ///Check does the add new form has all nessecary fields
676
+ var oSettings = oTable.fnSettings();
677
+ var iColumnCount = oSettings.aoColumns.length;
678
+ for (i = 0; i < iColumnCount; i++) {
679
+ if ($("[rel=" + i + "]", oAddNewRowForm).length == 0)
680
+ properties.fnShowError("In the form that is used for adding new records cannot be found an input element with rel=" + i + " that will be bound to the value in the column " + i + ". See http://code.google.com/p/jquery-datatables-editable/wiki/AddingNewRecords#Add_new_record_form for more details", "init");
681
+ }
682
+
683
+
684
+ if (properties.oAddNewRowFormOptions != null) {
685
+ properties.oAddNewRowFormOptions.autoOpen = false;
686
+ } else {
687
+ properties.oAddNewRowFormOptions = { autoOpen: false };
688
+ }
689
+ oAddNewRowForm.dialog(properties.oAddNewRowFormOptions);
690
+
691
+ //Add button click handler on the "Add new row" button
692
+ oAddNewRowButton = $("#" + properties.sAddNewRowButtonId);
693
+ if (oAddNewRowButton.length != 0) {
694
+ oAddNewRowButton.click(function () {
695
+ oAddNewRowForm.dialog('open');
696
+ });
697
+ } else {
698
+ if ($(properties.sAddDeleteToolbarSelector).length == 0) {
699
+ throw "Cannot find a button with an id '" + properties.sAddNewRowButtonId + "', or placeholder with an id '" + properties.sAddDeleteToolbarSelector + "' that should be used for adding new row although form for adding new record is specified";
700
+ } else {
701
+ oAddNewRowButton = null; //It will be auto-generated later
702
+ }
703
+ }
704
+
705
+ //Prevent Submit handler
706
+ if (oAddNewRowForm[0].nodeName.toLowerCase() == "form") {
707
+ oAddNewRowForm.unbind('submit');
708
+ oAddNewRowForm.submit(function (event) {
709
+ _fnOnRowAdding(event);
710
+ return false;
711
+ });
712
+ } else {
713
+ $("form", oAddNewRowForm[0]).unbind('submit');
714
+ $("form", oAddNewRowForm[0]).submit(function (event) {
715
+ _fnOnRowAdding(event);
716
+ return false;
717
+ });
718
+ }
719
+
720
+ // array to add default buttons to
721
+ var aAddNewRowFormButtons = [];
722
+
723
+ oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId, oAddNewRowForm);
724
+ if (oConfirmRowAddingButton.length == 0) {
725
+ //If someone forgotten to set the button text
726
+ if (properties.oAddNewRowOkButtonOptions.text == null
727
+ || properties.oAddNewRowOkButtonOptions.text == "") {
728
+ properties.oAddNewRowOkButtonOptions.text = "Ok";
729
+ }
730
+ properties.oAddNewRowOkButtonOptions.click = _fnOnRowAdding;
731
+ properties.oAddNewRowOkButtonOptions.id = properties.sAddNewRowOkButtonId;
732
+ // push the add button onto the array
733
+ aAddNewRowFormButtons.push(properties.oAddNewRowOkButtonOptions);
734
+ } else {
735
+ oConfirmRowAddingButton.click(_fnOnRowAdding);
736
+ }
737
+
738
+ oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId);
739
+ if (oCancelRowAddingButton.length == 0) {
740
+ //If someone forgotten to the button text
741
+ if (properties.oAddNewRowCancelButtonOptions.text == null
742
+ || properties.oAddNewRowCancelButtonOptions.text == "") {
743
+ properties.oAddNewRowCancelButtonOptions.text = "Cancel";
744
+ }
745
+ properties.oAddNewRowCancelButtonOptions.click = _fnOnCancelRowAdding;
746
+ properties.oAddNewRowCancelButtonOptions.id = properties.sAddNewRowCancelButtonId;
747
+ // push the cancel button onto the array
748
+ aAddNewRowFormButtons.push(properties.oAddNewRowCancelButtonOptions);
749
+ } else {
750
+ oCancelRowAddingButton.click(_fnOnCancelRowAdding);
751
+ }
752
+ // if the array contains elements, add them to the dialog
753
+ if (aAddNewRowFormButtons.length > 0) {
754
+ oAddNewRowForm.dialog('option', 'buttons', aAddNewRowFormButtons);
755
+ }
756
+ //Issue: It cannot find it with this call:
757
+ //oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId, oAddNewRowForm);
758
+ //oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId, oAddNewRowForm);
759
+ oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId);
760
+ oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId);
761
+ } else {
762
+ oAddNewRowForm = null;
763
+ }
764
+
765
+ //Set the click handler on the "Delete selected row" button
766
+ oDeleteRowButton = $('#' + properties.sDeleteRowButtonId);
767
+ if (oDeleteRowButton.length != 0)
768
+ oDeleteRowButton.click(_fnOnRowDelete);
769
+ else {
770
+ oDeleteRowButton = null;
771
+ }
772
+
773
+ //If an add and delete buttons does not exists but Add-delete toolbar is specificed
774
+ //Autogenerate these buttons
775
+ oAddDeleteToolbar = $(properties.sAddDeleteToolbarSelector);
776
+ if (oAddDeleteToolbar.length != 0) {
777
+ if (oAddNewRowButton == null && properties.sAddNewRowButtonId != ""
778
+ && oAddNewRowForm != null) {
779
+ oAddDeleteToolbar.append("<button id='" + properties.sAddNewRowButtonId + "' class='add_row'>Add</button>");
780
+ oAddNewRowButton = $("#" + properties.sAddNewRowButtonId);
781
+ oAddNewRowButton.click(function () { oAddNewRowForm.dialog('open'); });
782
+ }
783
+ if (oDeleteRowButton == null && properties.sDeleteRowButtonId != "") {
784
+ oAddDeleteToolbar.append("<button id='" + properties.sDeleteRowButtonId + "' class='delete_row'>Delete</button>");
785
+ oDeleteRowButton = $("#" + properties.sDeleteRowButtonId);
786
+ oDeleteRowButton.click(_fnOnRowDelete);
787
+ }
788
+ }
789
+
790
+ //If delete button exists disable it until some row is selected
791
+ if (oDeleteRowButton != null) {
792
+ if (properties.oDeleteRowButtonOptions != null) {
793
+ oDeleteRowButton.button(properties.oDeleteRowButtonOptions);
794
+ }
795
+ _fnDisableDeleteButton();
796
+ }
797
+
798
+ //If add button exists convert it to the JQuery-ui button
799
+ if (oAddNewRowButton != null) {
800
+ if (properties.oAddNewRowButtonOptions != null) {
801
+ oAddNewRowButton.button(properties.oAddNewRowButtonOptions);
802
+ }
803
+ }
804
+
805
+
806
+ //If form ok button exists convert it to the JQuery-ui button
807
+ if (oConfirmRowAddingButton != null) {
808
+ if (properties.oAddNewRowOkButtonOptions != null) {
809
+ oConfirmRowAddingButton.button(properties.oAddNewRowOkButtonOptions);
810
+ }
811
+ }
812
+
813
+ //If form cancel button exists convert it to the JQuery-ui button
814
+ if (oCancelRowAddingButton != null) {
815
+ if (properties.oAddNewRowCancelButtonOptions != null) {
816
+ oCancelRowAddingButton.button(properties.oAddNewRowCancelButtonOptions);
817
+ }
818
+ }
819
+
820
+ //Add handler to the inline delete buttons
821
+ $(".table-action-deletelink", oTable).live("click", function (e) {
822
+
823
+ e.preventDefault();
824
+ e.stopPropagation();
825
+ var sURL = $(this).attr("href");
826
+
827
+ if (sURL == null || sURL == "")
828
+ sURL = properties.sDeleteURL;
829
+
830
+ iDisplayStart = _fnGetDisplayStart();
831
+ var oTD = ($(this).parents('td'))[0];
832
+ var oTR = ($(this).parents('tr'))[0];
833
+
834
+ $(oTR).addClass(properties.sSelectedRowClass);
835
+
836
+ var id = fnGetCellID(oTD);
837
+ if (properties.fnOnDeleting(oTD, id, _fnDeleteRow)) {
838
+ _fnDeleteRow(id, sURL);
839
+ }
840
+
841
+
842
+ }
843
+ );
844
+
845
+ //Add handler to the inline delete buttons
846
+ $(".table-action-editlink", oTable).live("click", function (e) {
847
+
848
+ e.preventDefault();
849
+ e.stopPropagation();
850
+ var sURL = $(this).attr("href");
851
+
852
+ if (sURL == null || sURL == "")
853
+ sURL = properties.sDeleteURL;
854
+
855
+ iDisplayStart = _fnGetDisplayStart();
856
+ var oTD = ($(this).parents('td'))[0];
857
+ var oTR = ($(this).parents('tr'))[0];
858
+
859
+ $(oTR).addClass(properties.sSelectedRowClass);
860
+
861
+ var id = fnGetCellID(oTD);
862
+ if (properties.fnOnDeleting(oTD, id, _fnDeleteRow)) {
863
+ _fnDeleteRow(id, sURL);
864
+ }
865
+
866
+
867
+ }
868
+ );
869
+
870
+ //Set selected class on row that is clicked
871
+ //Enable delete button if row is selected, disable delete button if selected class is removed
872
+ $("tbody", oTable).click(function (event) {
873
+ if ($(event.target.parentNode).hasClass(properties.sSelectedRowClass)) {
874
+ $(event.target.parentNode).removeClass(properties.sSelectedRowClass);
875
+ if (oDeleteRowButton != null) {
876
+ _fnDisableDeleteButton();
877
+ }
878
+ } else {
879
+ $(oTable.fnSettings().aoData).each(function () {
880
+ $(this.nTr).removeClass(properties.sSelectedRowClass);
881
+ });
882
+ $(event.target.parentNode).addClass(properties.sSelectedRowClass);
883
+ if (oDeleteRowButton != null) {
884
+ _fnEnableDeleteButton();
885
+ }
886
+ }
887
+ });
888
+
889
+
890
+ if (properties.aoTableActions != null) {
891
+ for (var i = 0; i < properties.aoTableActions.length; i++) {
892
+ var oTableAction = properties.aoTableActions[i];
893
+ var sAction = oTableAction.sAction;
894
+ var sActionFormId = oTableAction.sActionFormId;
895
+
896
+ var oActionForm = $("#form" + sAction);
897
+ if (oActionForm.length != 0) {
898
+ var oFormOptions = { autoOpen: false, modal: true };
899
+ oFormOptions = $.extend({}, oTableAction.oFormOptions, oFormOptions);
900
+ oActionForm.dialog(oFormOptions);
901
+
902
+ var oActionFormLink = $(".table-action-" + sAction);
903
+ if (oActionFormLink.length != 0) {
904
+
905
+ oActionFormLink.live("click", function () {
906
+
907
+ var oTD = ($(this).parents('td'))[0];
908
+ var oTR = ($(this).parents('tr'))[0];
909
+
910
+ $(oTR).addClass(properties.sSelectedRowClass);
911
+
912
+ var iRowID = oTable.fnGetPosition(oTR);
913
+
914
+
915
+ var id = fnGetCellID(oTD);
916
+ var sClass = this.className;
917
+ var classList = sClass.split(/\s+/);
918
+ var sActionFormId = "";
919
+ var sAction = "";
920
+ for (i = 0; i < classList.length; i++) {
921
+ if (classList[i].indexOf("table-action-") > -1) {
922
+ sAction = classList[i].replace("table-action-", "");
923
+ sActionFormId = "#form" + sAction;
924
+ }
925
+ }
926
+ if (sActionFormId == "") {
927
+ properties.fnShowError("Cannot find a form with an id " + sActionFormId + " that should be associated to the action - " + sAction, sAction)
928
+ }
929
+ $(sActionFormId).validate().resetForm();
930
+ jQuery.data($(sActionFormId)[0], 'DATARECORDID', id);
931
+ $("input.DATARECORDID", $(sActionFormId)).val(id);
932
+ jQuery.data($(sActionFormId)[0], 'ROWID', iRowID);
933
+ $("input.ROWID", $(sActionFormId)).val(iRowID);
934
+
935
+
936
+ var oSettings = oTable.fnSettings();
937
+ var iColumnCount = oSettings.aoColumns.length;
938
+
939
+
940
+ $("input:text[rel],input:radio[rel][checked],input:hidden[rel],select[rel],textarea[rel]",
941
+ $(sActionFormId)).each(function () {
942
+ var rel = $(this).attr("rel");
943
+
944
+
945
+ if (rel >= iColumnCount)
946
+ properties.fnShowError("In the action form is placed input element with the name '" + $(this).attr("name") + "' with the 'rel' attribute that must be less than a column count - " + iColumnCount, "add");
947
+ else {
948
+ var sCellValue = oTable.fnGetData(oTR)[rel];
949
+ if (this.nodeName.toLowerCase() == "select" || this.tagName.toLowerCase() == "select")
950
+ $("option:selected", this).text(sCellValue);
951
+ else if (this.nodeName.toLowerCase() == "span" || this.tagName.toLowerCase() == "span")
952
+ $(this).html(sCellValue);
953
+ else
954
+ this.value = sCellValue;
955
+
956
+ //sCellValue = sCellValue.replace(properties.sIDToken, data);
957
+ //values[rel] = sCellValue;
958
+ //oTable.fnUpdate(sCellValue, iRowID, rel);
959
+ }
960
+ });
961
+
962
+
963
+
964
+ $(sActionFormId).dialog('open');
965
+ });
966
+ }
967
+
968
+ oActionForm.submit(function (event) {
969
+ ///Start function _fnUpdateRow
970
+ _fnUpdateRow(this);
971
+ ///end function _fnUpdateRow
972
+ return false;
973
+ });
974
+
975
+
976
+ var aActionFormButtons = new Array();
977
+
978
+ //var oActionSubmitButton = $("#form" + sAction + "Ok", oActionForm);
979
+ //aActionFormButtons.push(oActionSubmitButton);
980
+ var oActionFormCancel = $("#form" + sAction + "Cancel", oActionForm);
981
+ if (oActionFormCancel.length != 0) {
982
+ aActionFormButtons.push(oActionFormCancel);
983
+ oActionFormCancel.click(function () {
984
+
985
+ var oActionForm = $(this).parents("form")[0];
986
+ //Clear the validation messages and reset form
987
+ $(oActionForm).validate().resetForm(); // Clears the validation errors
988
+ $(oActionForm)[0].reset();
989
+
990
+ $(".error", $(oActionForm)).html("");
991
+ $(".error", $(oActionForm)).hide(); // Hides the error element
992
+ $(oActionForm).dialog('close');
993
+ });
994
+ }
995
+
996
+ //Convert all action form buttons to the JQuery UI buttons
997
+ $("button", oActionForm).button();
998
+ /*
999
+ if (aActionFormButtons.length > 0) {
1000
+ oActionForm.dialog('option', 'buttons', aActionFormButtons);
1001
+ }
1002
+ */
1003
+
1004
+
1005
+
1006
+ }
1007
+
1008
+
1009
+
1010
+
1011
+ } // end for (var i = 0; i < properties.aoTableActions.length; i++)
1012
+ } //end if (properties.aoTableActions != null)
1013
+
1014
+
1015
+ });
1016
+ };
1017
+ })(jQuery);