1/* 2* File: jquery.dataTables.editable.js 3* Version: 1.3. 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 delete 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 if (sNewCellValue == sValue) { 151 var aPos = oTable.fnGetPosition(this); 152 oTable.fnUpdate(sNewCellDisplayValue, aPos[0], aPos[2]); 153 status = "success"; 154 } else { 155 var aPos = oTable.fnGetPosition(this); 156 oTable.fnUpdate(sOldValue, aPos[0], aPos[2]); 157 properties.fnShowError(sValue, "update"); 158 status = "failure"; 159 } 160 161 properties.fnOnEdited(status, sOldValue, sNewCellDisplayValue, aPos[0], aPos[1], aPos[2]); 162 if (settings.fnOnCellUpdated != null) { 163 settings.fnOnCellUpdated(status, sValue, settings); 164 } 165 _fnSetDisplayStart(); 166 167 }, 168 "onsubmit": function (settings, original) { 169 var input = $("input,select,textarea", this); 170 sOldValue = original.revert; 171 sNewCellValue = $("input,select,textarea", $(this)).val(); 172 if (input.length == 1) { 173 var oEditElement = input[0]; 174 if (oEditElement.nodeName.toLowerCase() == "select" || oEditElement.tagName.toLowerCase() == "select") 175 sNewCellDisplayValue = $("option:selected", oEditElement).text(); //For select list use selected text instead of value for displaying in table 176 else 177 sNewCellDisplayValue = sNewCellValue; 178 } 179 180 if (!properties.fnOnEditing(input)) 181 return false;
182 var x = settings; 183 if (settings.cssclass != null) { 184 input.addClass(settings.cssclass); 185 if (!input.valid() || 0 == input.valid()) 186 return false; 187 else 188 return true; 189 } 190 }, 191 "submitdata": function (value, settings) { 192 iDisplayStart = _fnGetDisplayStart(); 193 properties.fnStartProcessingMode(); 194 var id = fnGetCellID(this); 195 var rowId = oTable.fnGetPosition(this)[0]; 196 var columnPosition = oTable.fnGetPosition(this)[1]; 197 var columnId = oTable.fnGetPosition(this)[2]; 198 var sColumnName = oTable.fnSettings().aoColumns[columnId].sName; 199 if (sColumnName == null || sColumnName == "") 200 sColumnName = oTable.fnSettings().aoColumns[columnId].sTitle; 201 return { 202 "id": id, 203 "rowId": rowId, 204 "columnPosition": columnPosition, 205 "columnId": columnId, 206 "columnName": sColumnName 207 }; 208 }, 209 "onerror": function () { 210 properties.fnEndProcessingMode(); 211 properties.fnShowError("Cell cannot be updated(Server error)", "update"); 212 properties.fnOnEdited("failure"); 213 }, 214 "height": properties.sEditorHeight, 215 "width": properties.sEditorWidth 216 }; 217 218 var cells = null; 219 if (properties.aoColumns != null) { 220 for (var i = 0; i < properties.aoColumns.length; i++) { 221 if (properties.aoColumns[i] != null) { 222 cells = $("td:nth-child(" + (i + 1) + ")", aoNodes); 223 var oColumnSettings = oDefaultEditableSettings; 224 oColumnSettings = $.extend({}, oDefaultEditableSettings, properties.aoColumns[i]); 225 var sUpdateURL = properties.sUpdateURL; 226 try { 227 if (oColumnSettings.sUpdateURL != null) 228 sUpdateURL = oColumnSettings.sUpdateURL; 229 } catch (ex) { 230 } 231 cells.editable(sUpdateURL, oColumnSettings); 232 } 233 234 235 } 236 } else { 237 cells = $('td:not(.' + properties.sReadOnlyCellClass + ')', aoNodes); 238 cells.editable(properties.sUpdateURL, oDefaultEditableSettings); 239 240 } 241 242 } 243 244 //Called when user confirm that he want to add new record 245 function _fnOnRowAdding(event) { 246 if (properties.fnOnAdding()) { 247 if (oAddNewRowForm.valid()) { 248 iDisplayStart = _fnGetDisplayStart(); 249 properties.fnStartProcessingMode(); 250 var params = oAddNewRowForm.serialize(); 251 $.ajax({ 'url': properties.sAddURL, 252 'data': params, 253 'type': properties.sAddHttpMethod, 254 "dataType": "text", 255 success: _fnOnRowAdded, 256 error: function (response) { 257 properties.fnEndProcessingMode(); 258 properties.fnShowError(response.responseText, "add"); 259 properties.fnOnAdded("failure"); 260 } 261 }); 262 } 263 } 264 event.stopPropagation(); 265 event.preventDefault(); 266 } 267 268 function _fnOnNewRowPosted(data) { 269 270 return true; 271 272 } 273 ///Event handler called when a new row is added and response is returned from server 274 function _fnOnRowAdded(data) { 275 properties.fnEndProcessingMode(); 276 277 if (properties.fnOnNewRowPosted(data)) { 278 279 var oSettings = oTable.fnSettings(); 280 var iColumnCount = oSettings.aoColumns.length; 281 var values = new Array(); 282 283 $("input:text[rel],input:radio[rel][checked],input
283:hidden[rel],select[rel],textarea[rel],span.datafield[rel]", oAddNewRowForm).each(function () { 284 var rel = $(this).attr("rel"); 285 var sCellValue = ""; 286 if (rel >= iColumnCount) 287 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"); 288 else { 289 if (this.nodeName.toLowerCase() == "select" || this.tagName.toLowerCase() == "select") 290 sCellValue = $("option:selected", this).text(); 291 else if (this.nodeName.toLowerCase() == "span" || this.tagName.toLowerCase() == "span") 292 sCellValue = $(this).html(); 293 else 294 sCellValue = this.value; 295 296 sCellValue = sCellValue.replace(properties.sIDToken, data); 297 values[rel] = sCellValue; 298 } 299 }); 300 301 //Add values from the form into the table 302 var rtn = oTable.fnAddData(values); 303 var oTRAdded = oTable.fnGetNodes(rtn); 304 //Apply editable plugin on the cells of the table 305 _fnApplyEditable(oTRAdded); 306 //add id returned by server page as an TR id attribute 307 properties.fnSetRowID($(oTRAdded), data); 308 //Close the dialog 309 oAddNewRowForm.dialog('close'); 310 $(oAddNewRowForm)[0].reset(); 311 $(".error", $(oAddNewRowForm)).html(""); 312 313 _fnSetDisplayStart(); 314 properties.fnOnAdded("success"); 315 } 316 } 317 318 //Called when user cancels adding new record in the popup dialog 319 function _fnOnCancelRowAdding(event) { 320 //Clear the validation messages and reset form 321 $(oAddNewRowForm).validate().resetForm(); // Clears the validation errors 322 $(oAddNewRowForm)[0].reset(); 323 324 $(".error", $(oAddNewRowForm)).html(""); 325 $(".error", $(oAddNewRowForm)).hide(); // Hides the error element 326 327 //Close the dialog 328 oAddNewRowForm.dialog('close'); 329 event.stopPropagation(); 330 event.preventDefault(); 331 } 332 333 334 335 function _fnDisableDeleteButton() { 336 if (properties.oDeleteRowButtonOptions != null) { 337 //oDeleteRowButton.disable(); 338 oDeleteRowButton.button("option", "disabled", true); 339 } else { 340 oDeleteRowButton.attr("disabled", "true"); 341 } 342 } 343 344 function _fnEnableDeleteButton() { 345 if (properties.oDeleteRowButtonOptions != null) { 346 //oDeleteRowButton.enable(); 347 oDeleteRowButton.button("option", "disabled", false); 348 } else { 349 oDeleteRowButton.removeAttr("disabled"); 350 } 351 } 352 353 function _fnDeleteRow(id, sDeleteURL) { 354 var sURL = sDeleteURL; 355 if (sDeleteURL == null) 356 sURL = properties.sDeleteURL; 357 properties.fnStartProcessingMode(); 358 var data = $.extend(properties.oDeleteParameters, { "id": id }); 359 $.ajax({ 'url': sURL, 360 'type': properties.sDeleteHttpMethod, 361 'data': data, 362 "success": _fnOnRowDeleted, 363 "dataType": "text", 364 "error": function (response) { 365 properties.fnEndProcessingMode(); 366 properties.fnShowError(response.responseText, "delete"); 367 properties.fnOnDeleted("failure"); 368 369 } 370 }); 371 } 372 373 //Called when user deletes a row 374 function _fnOnRowDelete(event) { 375 iDisplayStart = _fnGetDisplayStart(); 376 if ($('tr.' + properties.sSelectedRowClass + ' td', oTable).length == 0) { 377 //oDeleteRowButton.attr("disabled", "true"); 378 _fnDisableDeleteButton(); 379 return; 380 } 381 var id = fnGetCellID($('tr.' + properties.sSelectedRowClass + ' td', oTable)[0]); 382 if (properties.fnOnDeleting($('tr.' + properties.sSelectedRowClass, oTable), id, _fnDeleteRow)) { 383 _fnDeleteRow(id); 384 } 385 } 386 387 //Called when record is deleted on the server 388 function _fnOnRowDeleted(response) { 389 properties.fnEndProcessingMode(); 390 var oTRSelected = $('tr.' + properties.sSelectedRowClass, oTable)[0]; 391 if (response == "ok" || response == "") { 392 oTable.fnDeleteRow(oTRSelected); 393 //oDeleteRowButton.attr("disabled", "true"); 394 _fnDisableDeleteButton(); 395 _fnSetDisplayStart(); 396 properties.fnOnDeleted("success"); 397 } 398 else { 399 properties.fnShowError(response, "delete"); 400 properties.fnOnDeleted("failure"); 401 } 402 } 403 404 //Called before row is deleted 405 //Returning false will abort delete 406 /* 407 * Function called before row is deleted 408 * @param tr JQuery wrapped around the TR tag that will be deleted 409 * @param id id of the record that wil be deleted 410 * @return true if plugin should continue with deleting row, false will abort delete. 411 */ 412 function fnOnDeleting(tr, id, fnDeleteRow) { 413 return confirm("Are you sure that you want to delete this record?"); ; 414 } 415 416 /* Function called after delete action 417 * @param result string 418 * "success" if row is actually deleted 419 * "failure" if delete failed 420 * @return void 421 */ 422 function fnOnDeleted(result) { } 423 424 function fnOnEditing(input) { return true; } 425 function fnOnEdited(result, sOldValue, sNewValue, iRowIndex, iColumnIndex, iRealColumnIndex) { 426 427 } 428 429 function fnOnAdding() { return true; } 430 function fnOnAdded(result) { } 431 432 var oSettings; 433 function _fnGetDisplayStart() { 434 return oSettings._iDisplayStart; 435 } 436 437 function _fnSetDisplayStart() { 438 if (oSettings.oFeatures.bServerSide === false) { 439 oSettings._iDisplayStart = iDisplayStart; 440 oSettings.oApi._fnCalculateEnd(oSettings); 441 //draw the 'current' page 442 oSettings.oApi._fnDraw(oSettings); 443 } 444 } 445 446 447 oTable = this; 448 449 var defaults = { 450 451 sUpdateURL: "UpdateData", 452 sAddURL: "AddData", 453 sDeleteURL: "DeleteData", 454 sAddNewRowFormId: "formAddNewRow", 455 oAddNewRowFormOptions: { autoOpen: false, modal: true }, 456 sAddNewRowButtonId: "btnAddNewRow", 457 oAddNewRowButtonOptions: null, 458 sAddNewRowOkButtonId: "btnAddNewRowOk", 459 sAddNewRowCancelButtonId: "btnAddNewRowCancel", 460 oAddNewRowOkButtonOptions: { label: "Ok" }, 461 oAddNewRowCancelButtonOptions: { label: "Cancel" }, 462 sDeleteRowButtonId: "btnDeleteRow", 463 oDeleteRowButtonOptions: null, 464 sSelectedRowClass: "row_selected", 465 sReadOnlyCellClass: "read_only", 466 sAddDeleteToolbarSelector: ".add_delete_toolbar", 467 fnShowError: fnShowError, 468 fnStartProcessingMode: fnStartProcessingMode, 469 fnEndProcessingMode: fnEndProcessingMode, 470 aoColumns: null, 471 fnOnDeleting: fnOnDeleting, 472 fnOnDeleted: fnOnDeleted, 473 fnOnAdding: fnOnAdding, 474 fnOnNewRowPosted: _fnOnNewRowPosted, 475 fnOnAdded: fnOnAdded, 476 fnOnEditing: fnOnEditing, 477 fnOnEdited: fnOnEdited, 478 sAddHttpMethod: 'POST', 479 sDeleteHttpMethod: 'POST', 480 fnGetRowID: _fnGetRowIDFromAttribute, 481 fnSetRowID: _fnSetRowIDInAttribute, 482 sEditorHeight: "100%", 483 sEditorWidth: "100%", 484 bDisableEditing: false, 485 oDeleteParameters: {}, 486 sIDToken: "DATAROWID" 487 488 }; 489 490 properties = $.extend(defaults, options); 491 oSettings = oTable.fnSettings(); 492 493 return this.each(function () { 494 495 if (oTable.fnSettings().sAjaxSource != null) { 496 oTable.fnSettings().aoDrawCallback.push({ 497 "fn": function () { 498 //Apply jEditable plugin on the table cells 499 _fnApplyEditable(oTable.fnGetNodes()); 500 $(oTable.fnGetNodes()).each(function () { 501 var position = oTable.fnGetPosition(this); 502 var id = oTable.fnGetData(position)[0]; 503 properties.fnSetRowID($(this), id); 504 } 505 ); 506 }, 507 "sName": "fnApplyEditable" 508 }); 509 510 } else { 511 //Apply jEditable plugin on the table cells 512 _fnApplyEditable(oTable.fnGetNodes()); 513 } 514 515 //Setup form to open in dialog 516 oAddNewRowForm = $("#" + properties.sAddNewRowFormId); 517 if (oAddNewRowForm.length != 0) { 518 if (properties.oAddNewRowFormOptions != null) { 519 properties.oAddNewRowFormOptions.autoOpen = false;
520 } else { 521 properties.oAddNewRowFormOptions = { autoOpen: false }; 522 } 523 oAddNewRowForm.dialog(properties.oAddNewRowFormOptions); 524 525 //Add button click handler on the "Add new row" button 526 oAddNewRowButton = $("#" + properties.sAddNewRowButtonId); 527 if (oAddNewRowButton.length != 0) { 528 oAddNewRowButton.click(function () { 529 oAddNewRowForm.dialog('open'); 530 }); 531 } else { 532 if ($(properties.sAddDeleteToolbarSelector).length == 0) { 533 throw "Cannot find a button with an id '" + properties.sAddNewRowButtonId + "', od placeholder with an id '" + properties.sAddDeleteToolbarSelector + "' that should be used for adding new row although form for adding new record is specified"; 534 } else { 535 oAddNewRowButton = null; //It will be auto-generated later 536 } 537 } 538 539 //Prevent Submit handler 540 if (oAddNewRowForm[0].nodeName.toLowerCase() == "form") { 541 oAddNewRowForm.unbind('submit'); 542 oAddNewRowForm.submit(function (event) { 543 _fnOnRowAdding(event); 544 return false; 545 }); 546 } else { 547 $("form", oAddNewRowForm[0]).unbind('submit'); 548 $("form", oAddNewRowForm[0]).submit(function (event) { 549 _fnOnRowAdding(event); 550 return false; 551 }); 552 } 553 554 // array to add default buttons to 555 var aAddNewRowFormButtons = []; 556 557 oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId, oAddNewRowForm); 558 if (oConfirmRowAddingButton.length == 0) { 559 //If someone forgotten to set the button text 560 if (properties.oAddNewRowOkButtonOptions.text == null 561 || properties.oAddNewRowOkButtonOptions.text == "") { 562 properties.oAddNewRowOkButtonOptions.text = "Ok"; 563 } 564 properties.oAddNewRowOkButtonOptions.click = _fnOnRowAdding; 565 properties.oAddNewRowOkButtonOptions.id = properties.sAddNewRowOkButtonId; 566 // push the add button onto the array 567 aAddNewRowFormButtons.push(properties.oAddNewRowOkButtonOptions); 568 } else { 569 oConfirmRowAddingButton.click(_fnOnRowAdding); 570 } 571 572 oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId); 573 if (oCancelRowAddingButton.length == 0) { 574 //If someone forgotten to the button text 575 if (properties.oAddNewRowCancelButtonOptions.text == null 576 || properties.oAddNewRowCancelButtonOptions.text == "") { 577 properties.oAddNewRowCancelButtonOptions.text = "Cancel"; 578 } 579 properties.oAddNewRowCancelButtonOptions.click = _fnOnCancelRowAdding; 580 properties.oAddNewRowCancelButtonOptions.id = properties.sAddNewRowCancelButtonId; 581 // push the cancel button onto the array 582 aAddNewRowFormButtons.push(properties.oAddNewRowCancelButtonOptions); 583 } else { 584 oCancelRowAddingButton.click(_fnOnCancelRowAdding); 585 } 586 // if the array contains elements, add them to the dialog 587 if (aAddNewRowFormButtons.length > 0) { 588 oAddNewRowForm.dialog('option', 'buttons', aAddNewRowFormButtons); 589 } 590 //Issue: It cannot find it with this call: 591 //oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId, oAddNewRowForm); 592 //oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId, oAddNewRowForm); 593 oConfirmRowAddingButton = $("#" + properties.sAddNewRowOkButtonId); 594 oCancelRowAddingButton = $("#" + properties.sAddNewRowCancelButtonId); 595 } else { 596 oAddNewRowForm = null; 597 } 598 599 //Set the click handler on the "Delete selected row" button 600 oDeleteRowButton = $('#' + properties.sDeleteRowButtonId); 601 if (oDeleteRowButton.length != 0) 602 oDeleteRowButton.click(_fnOnRowDelete); 603 else { 604 oDeleteRowButton = null; 605 } 606 607 //If an add and delete buttons does not exists but Add-delete toolbar is specificed 608 //Autogenerate these buttons 609 oAddDeleteToolbar = $(properties.sAddDeleteToolbarSelector); 610 if (oAddDeleteToolbar.length != 0) { 611 if (oAddNewRowButton == null && properties.sAddNewRowButtonId != "" 612 && oAddNewRowForm != null) { 613 oAddDeleteToolbar.append("<button id='" + properties.sAddNewRowButtonId + "' class='add_row'>Add</button>"); 614 oAddNewRowButton = $("#" + properties.sAddNewRowButtonId); 615 oAddNewRowButton.click(function () { oAddNewRowForm.dialog('open'); }); 616 } 617 if (oDeleteRowButton == null && properties.sDeleteRowButtonId != "") { 618 oAddDeleteToolbar.append("<button id='" + properties.sDeleteRowButtonId + "' class='delete_row'>Delete</button>"); 619 oDeleteRowButton = $("#" + properties.sDeleteRowButtonId); 620 oDeleteRowButton.click(_fnOnRowDelete); 621 } 622 } 623 624 //If delete button exists disable it until some row is selected 625 if (oDeleteRowButton != null) { 626 if (properties.oDeleteRowButtonOptions != null) { 627 oDeleteRowButton.button(properties.oDeleteRowButtonOptions); 628 } 629 _fnDisableDeleteButton(); 630 } 631 632 //If add button exists convert it to the JQuery-ui button 633 if (oAddNewRowButton != null) { 634 if (properties.oAddNewRowButtonOptions != null) { 635 oAddNewRowButton.button(properties.oAddNewRowButtonOptions); 636 } 637 } 638 639 640 //If form ok button exists convert it to the JQuery-ui button 641 if (oConfirmRowAddingButton != null) { 642 if (properties.oAddNewRowOkButtonOptions != null) { 643 oConfirmRowAddingButton.button(properties.oAddNewRowOkButtonOptions); 644 } 645 } 646 647 //If form cancel button exists convert it to the JQuery-ui button 648 if (oCancelRowAddingButton != null) { 649 if (properties.oAddNewRowCancelButtonOptions != null) { 650 oCancelRowAddingButton.button(properties.oAddNewRowCancelButtonOptions); 651 } 652 } 653 654 //Add handler to the inline delete buttons 655 $(".table-action-deletelink", oTable).live("click", function (e) { 656 657 e.preventDefault(); 658 e.stopPropagation(); 659 var sURL = $(this).attr("href"); 660 661 if (sURL == null || sURL == "") 662 sURL = properties.sDeleteURL; 663 664 iDisplayStart = _fnGetDisplayStart(); 665 var oTD = ($(this).parents('td'))[0]; 666 var oTR = ($(this).parents('tr'))[0]; 667 668 $(oTR).addClass(properties.sSelectedRowClass); 669 670 var id = fnGetCellID(oTD); 671 if (properties.fnOnDeleting(oTD, id, _fnDeleteRow)) { 672 _fnDeleteRow(id, sURL); 673 } 674 675 676 } 677 ); 678 679 //Set selected class on row that is clicked 680 //Enable delete button if row is selected, disable delete button if selected class is removed 681 $("tbody", oTable).click(function (event) { 682 if ($(event.target.parentNode).hasClass(properties.sSelectedRowClass)) { 683 $(event.target.parentNode).removeClass(properties.sSelectedRowClass); 684 if (oDeleteRowButton != null) { 685 _fnDisableDeleteButton(); 686 } 687 } else { 688 $(oTable.fnSettings().aoData).each(function () { 689 $(this.nTr).removeClass(properties.sSelectedRowClass); 690 }); 691 $(event.target.parentNode).addClass(properties.sSelectedRowClass); 692 if (oDeleteRowButton != null) { 693 _fnEnableDeleteButton(); 694 } 695 } 696 }); 697 698 699 700 }); 701 }; 702})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.