首页 > 解决方案 > 为什么当我在同一行中编辑另一个单元格时,此数据表单元格会恢复为旧值?

问题描述

我正在使用以前的开发人员设置的 jQuery 数据表。对于可编辑的列,每当您双击该值、更改它并按回车键时,数据库表中的相应记录都会通过 AJAX 更新。但是,当这种情况发生时,数据表中的一个字段似乎总是恢复为旧的、明显存储的值。

此列是错误消息。发生的情况是,数据表最初是从数据库查询中填充的,该查询获得了提交时验证失败的记录。因此,可能电子邮件地址无效,数据表将向您显示记录,以及错误的电子邮件地址,以及来自 API 的错误消息“错误的电子邮件地址”。因此,您可以通过单击 dbl 来更新电子邮件地址,更改它,然后按回车键。这会更新数据库中临时表中的记录,现在可以重新提交给 API。

我设置了一个按钮和一个 jQuery 函数来重新提交给 API。因此,您单击该按钮,该数据库临时表中的更正记录被提取并提交。但是说记录还有另一个问题,比如SSN无效。API 将捕获它并以新的错误消息进行回复,我的函数捕获 API 的响应并相应地更新 DB 暂存表和数据表。现在在屏幕上,您会看到更新了该行的数据表;它有一条新的错误消息,我的函数在<td>元素中使用$('#errorMessageTD').text(newErrorMessageFromAPI).

这就是问题发生的地方——现在,如果您 dbl-click 进入 SSN 值,将其更改为有效的 SSN,然后按回车键,那么旧的“无效电子邮件地址”消息会立即替换其中的 SSN 错误消息<td>。在 DB staging 表中,错误消息仍然是 SSN 错误消息,因此不会从那里提取值。所以我认为必须发生的事情是,使用上面的 text() 函数替换了用户在该<td>元素内看到的错误消息,但不会替换 jQuery 数据表为该列和行存储的文本。或者,并不是该值本身存储在数据表中,而是显然该值存储在某处。因此,当您编辑该行中的另一个单元格并按回车键时,<td>替换为表格首次呈现到屏幕时的原始文本。

td所以我想知道的是,当编辑字段并按下回车按钮时,如何使新的错误消息保留在其中?当行中的所有其他 ' 保持不变时,即使它们已被编辑,为什么这个会<td>恢复?<td>

相关代码如下。在这种情况下,错误消息列是 aoColumnDefs 中的列 [0],并且不是可编辑字段。该数据表最初是从临时数据库表的查询中填充的,并且似乎是<td>当您按 Enter 键编辑同一行中的字段时返回的初始值。

// Data Table Scripts for Mass Uploader
var oTable;
var editRowID;
var editText;

$(document).ready(function() {
    $('#myTable').dataTable({
        // Set the column names for saving to the database
        // The number of these settings need to be the same as the number of TRs and TDs in the table
        "aoColumnDefs": [
            {"sWidth": "150px", "aTargets":[0]},
            {"sWidth": "60px","sName": "appl_fname", "aTargets":[1]},
            {"sWidth": "50px","sName": "appl_mname","aTargets":[2]},
            {"sWidth": "70px","sName": "appl_lname","aTargets":[3]},
            {"sWidth": "75px","sName": "appl_street","aTargets":[4]},
            {"sWidth": "60px","sName": "appl_street2","aTargets":[5]},
            {"sWidth": "60px","sName": "appl_city","aTargets":[6]},
            {"sWidth": "45px","sName": "appl_state","aTargets":[7]},
            {"sWidth": "45px","sName": "appl_zip","aTargets":[8]},
            {"sWidth": "80px","sName": "appl_dob","aTargets":[9]},
            {"sWidth": "80px","sName": "appl_ssn","aTargets":[10]},
            {"sWidth": "80px","sName": "appl_phone","aTargets":[11]},
            {"sWidth": "120px","sName": "appl_email_box","aTargets":[12]},
            {"sWidth": "120px","aTargets":[13]},
            {"sWidth": "120px","aTargets":[14]},
            {"sWidth": "120px","aTargets":[15]},
            {"sWidth": "50px","sName": "job_id","aTargets":[16]},
            {"sWidth": "80px","sName": "start_date","aTargets":[17]},
            {"sWidth": "60px","sName": "pay_rate","aTargets":[18]},
            {"sWidth": "70px","sName": "base_salary","aTargets":[19]},
            {"sWidth": "70px","sName": "position_type","aTargets":[20]},
            {"sWidth": "100px","sName": "benefit_status","aTargets":[21]},
            {"sWidth": "80px","sName": "status","aTargets":[22]},
            {"sWidth": "80px","sName": "reportsToRecLoginId","aTargets":[23]},
            {"sWidth": "80px","sName": "Send_Welcome_Email","aTargets":[24]},
            {"sWidth": "80px","sName": "Stage_To_Save_To_ID","aTargets":[25]},
            {"sWidth": "120px","aTargets":["SSCustomField"]}
        ],
        //"sPaginationType": "full_numbers"
        "sScrollXInner": "120%",
        "bPaginate": false,
        "bAutoWidth": false,
        "bScrollCollapse": false,
        "bAutoWidth": false,
        "bFilter": false
    }).makeEditable({
        // Set what columns are editable
        // The number of these settings need to be the same as the number of TRs and TDs in the table
        "aoColumns": [
            null,
                {},
                {},
            {},
            {},
            {},
            {},
            {},
            {},
            {},
            {},
            {},
            {},
            null,
            null,
            null,
            {},
            {},
            {type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', '1':'Per Hour','2':'Per Year'}",
                event: 'dblclick'},
            {},
            {type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', '1':'Full Time','2':'Part Time','-1':'Other'}",
                event: 'dblclick'},
            {type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', '1':'Full Company Benefits','2':'Employee Contribution Benefits','3':'Employee Paid Benefits','4':'No Benefits','-1':'Other'}",
                event: 'dblclick'},
            {type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', '1':'Exempt','2':'Non-Exempt','-1':'Other'}",
                event: 'dblclick'},
            /*{},*/
            null,//make ReportsTo not editable
            null,//make Send Welcome Email not editable
            /*{type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', 'true':'Yes','false':'No'}",
                event: 'dblclick'},*/
            /*{type: 'select',
                onblur: 'submit',
                data: "{'':'Please select...', '9':'Completed','8':'Onboarding'}",
                event: 'dblclick'},*/
            null,//make Status to Save To Not Editable
            {}
            /*{}*/
        ],
        fnOnDeleted: function(status) {
            oTable.fnDraw();
        },
        fnOnEditing: function(input, oEditableSettings, sOriginalText, id) {
            editRowID = id;
            editText = sOriginalText;
            return true;
        },
        fnOnEdited: function(status, sOldValue, sNewCellDisplayValue, aPos0, aPos1, aPos2) {
            if(aPos2 == 16 && editText == sOldValue && sNewCellDisplayValue.trim() != '') {
                $.ajax({
                    url: "Admin/MassUpload/GetLocationDepartmentPosition.cfm",
                    type: "POST",
                    dataType: "json",
                    data: {JobID: sNewCellDisplayValue, ErrorRowID: editRowID},
                    success: function (data) {
                        var stringData = data.DATA.toString();
                        if (stringData.length > 0) {
                            var locationPosition, departmentPosition, positionPosition;
                            locationPosition = 'Row'+editRowID+'Location';
                            $('#'+locationPosition).text(data.DATA[0][4]);
                            departmentPosition = 'Row'+editRowID+'Department';
                            $('#'+departmentPosition).text(data.DATA[0][2]);
                            positionPosition = 'Row'+editRowID+'Position';
                            $('#'+positionPosition).text(data.DATA[0][6]);
                        }
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        console.log(xhr.status);
                        console.log(thrownError);
                    }
                });
            }
        },
        sUpdateURL: "Admin/MassUpload/UpdateDataTableRow.cfm",
        sDeleteURL: "Admin/MassUpload/DeleteDataTableRow.cfm"
    });

    $('#demo').submit( function() {
        var sData = $('input', oTable.fnGetNodes()).serialize();
        this.submit();
        return false;
    });

    /* Add a click handler to the rows - this could be used as a callback */
    $("#example tbody tr").click( function( e ) {
        if ( $(this).hasClass('row_selected') ) {
            $(this).removeClass('row_selected');
        } else {
            oTable.$('tr.row_selected').removeClass('row_selected');
            $(this).addClass('row_selected');
        }
    });

    /* Add a click handler for the delete row */
    $('#delete').click( function() {
        var anSelected = fnGetSelected( oTable );
        oTable.fnDeleteRow( anSelected[0] );
    });

    oTable = $('#myTable').dataTable();
    setTimeout(function(){
        oTable.fnAdjustColumnSizing();
    },100);
});

此外,以下是我编写的函数,用于向 API 重新提交更正的错误,并使用来自 API 的新错误消息更新 td:

processData = function() {
    $.ajax({
        url: "Admin/MassUpload/processErrorsThroughAPI.cfm",
        type: "POST",
        dataType: "json",
        success: function (data) {
            console.log("data stringified: " + JSON.stringify(data));
            if (data.length > 0) {//There are rows in the table to delete or error messages to update
                $.each(data, function(index, item){
                    if (item.ERRORMESSAGE == "") {//Record passed validation. Remove this row from the data table.
                        oTable.fnDeleteRow($('#'+item.IMPORTERRORID)[0]);
                        oTable.fnDraw();
                    }
                    else {//Record did not pass validation, display new error message in the data table
                        $('#Row'+item.IMPORTERRORID+'ErrorMsg').text(item.ERRORMESSAGE);
                    }
                    //console.log(index);
                    console.log("item.IMPORTERRORID = " + item.IMPORTERRORID);
                    console.log("item.ERRORMESSAGE = " + item.ERRORMESSAGE);
                });
            }
            else {//No items to process, so nothing to display
                var divInfo = '<div class="container-fluid"> <div class="row-fluid"> <div class="well well-clear span6 offset3">';
                divInfo += 'Any errors associated with the uploading of the spreadsheet have been corrected.<br/>';
                divInfo += '<button type="button" onclick="selectExcelFile()">Go back to hire import</button><br/>';
                divInfo += '</div> </div> </div>';
                $('#hireImportTab').html(divInfo);
            }
        },
        error: function (xhr, ajaxOptions, thrownError) {
            console.log(xhr.status);
            console.log(thrownError);
        }
    });
}

标签: jquerydatatables

解决方案


好的,在完全被难住了几个星期之后,这就是解决方法。

首先,使该数据表可编辑的代码似乎来自 GitHub 上的一个分支 - https://github.com/ansballard/jquery-datatables-editable

其次,这篇文章中描述的不良行为似乎是与生俱来的。对于表格中的给定行,您可以使用 jQuery 更改 td 元素的文本:

$('#myTDCell_row1').text('Here is some new text');

但在那之后,如果您通过双击单元格的内容、键入新内容并按“enter”键来编辑该 td 同一行中的任何其他单元格,则该单元格的文本将恢复为之前的任何内容。

我不确定为什么会这样,但幸运的是,在定义 dataTable 的 jQuery 代码中,有一个名为“makeEditable()”的 dataTable 对象函数,在该函数中还有几个其他可选函数,“fnOnEditing ()”和“fnOnEdited()”。这些函数可用于保存 td 单元格中的新文本。

我所做的是首先定义一个全局变量,以便可以在单元格的文本更改之前捕获新文本并将其存储在 fnOnEditing() 中,然后在 fnOnEdited() 中可以检索并放回该单元格的文本.

有关总体思路,请参见下面的代码。

    //define global variables
    var latestText;
    var editRowID;
    
    $(document).ready(function() {
        $('#myTable').dataTable({
            [ColumnDefs, other config options]
             }).makeEditable({
                  [settings for if/how each column can be edited],
                  fnOnEditing: function(input, oEditableSettings, sOriginalText, id) {
                       //this function is run right before the edit is executed
                       //capture the edited row's id and the text in the cell 
                       editRowID = id;
                       latestText = $('#myTDCell_row' + editRowID).text();
                  },
                  fnOnEdited: function(status, sOldValue, sNewCellDisplayValue, aPos0, aPos1, aPos2) {
                       //this function runs after the edit has been made
                      /* the edit has been made to some cell in the row, and the text in our cell (which is another cell in that same row) has reverted to what it was before we changed it. So now we immediately change it back */
                      $('#myTDCell_row' + editRowID).text(latestText);
                  },
                  sUpdateURL: [path to page that handles the actual back-end DB update; a request is made to this page as soon as you click the enter key]
});

推荐阅读