为啥当我在同一行中编辑另一个单元格时,此数据表单元格会恢复为旧值?
Posted
技术标签:
【中文标题】为啥当我在同一行中编辑另一个单元格时,此数据表单元格会恢复为旧值?【英文标题】:Whys is this data table cell reverting to old value when I edit another cell in the same row?为什么当我在同一行中编辑另一个单元格时,此数据表单元格会恢复为旧值? 【发布时间】:2021-06-06 20:35:01 【问题描述】:我正在使用以前的开发人员设置的 jQuery 数据表。对于可编辑的列,无论何时双击该值、更改它并按回车,数据库表中的相应记录都会通过 AJAX 更新。但是当这种情况发生时,数据表中的一个字段似乎总是恢复为旧的、明显存储的值。
此列是一条错误消息。发生的情况是,数据表最初是从数据库查询中填充的,该查询获得了提交时验证失败的记录。因此,可能电子邮件地址无效,数据表将向您显示记录,以及错误的电子邮件地址,以及来自 API 的错误消息“错误的电子邮件地址”。因此,您可以通过单击 dbl 来更新电子邮件地址,更改它,然后按回车键。这会更新数据库中临时表中的记录,现在可以重新提交给 API。
我设置了一个按钮和一个 jQuery 函数来重新提交给 API。因此,您单击该按钮,该数据库临时表中的更正记录被提取并提交。但是说记录还有另一个问题,比如SSN无效。 API 将捕获它并回复一条新的错误消息,我的函数捕获 API 的响应并相应地更新 DB 暂存表和数据表。现在在屏幕上,您会看到更新了该行的数据表;它有一条新的错误消息,我的函数在 <td>
元素中使用 $('#errorMessageTD').text(newErrorMessageFromAPI)
进行了更改。
这就是问题所在 - 现在,如果您 dbl 单击 SSN 值,将其更改为有效的 SSN,然后按回车键,那么旧的“无效电子邮件地址”消息会立即替换该 @987654323 中的 SSN 错误消息@。在 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);
);
【问题讨论】:
我们需要查看相关的代码段。 【参考方案1】:好的,在完全被难住了几个星期之后,这就是解决方法。
首先,使该数据表可编辑的代码似乎来自 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]
);
【讨论】:
以上是关于为啥当我在同一行中编辑另一个单元格时,此数据表单元格会恢复为旧值?的主要内容,如果未能解决你的问题,请参考以下文章
为啥当我滚动我的 tabelview 单元格时我的 imageview 正在缩小?
在单元格编辑模式下,单击其他行时,不会更新kendo(可排序)网格值