jquery-datatables-rails 0.1.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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);