我正在使用Spring,jsp,javascript,jquery开发一个webapp。
我使用数据表显示一个表。 当我点击一个表格行时,我希望它将所有字段更改为内联编辑输入,选择等。此外,我想在下一行显示一些额外的输入字段和一个保存按钮。
现在我看到了几种方法。我不确定要选哪一个。
我可以获取所选行的句柄,然后迭代td并将它们转换为输入/选择字段。然后,我可以为新字段和保存按钮插入一个额外的行。 我不认为这是一个干净的解决方案。我将不得不手动发布Post而不是使用Spring ModelAttribute绑定表单。 (我还可以在这里使用ModelAttribute吗?)
我可以在jsp文件中创建一个编辑表单,如下所示:
<form:form action="" commandName="">
<td> <input ... > </td>
<td> <select ... > </td>
</tr>
<tr>
<td> <label> <input new field> </td>
<td> <button> </td>
</tr>
注意我在jsp文件中没有开头因为我打算重用表中现有行的tr。 这样我就可以使用一个干净的表单,并使用我已经编写的更新方法将表单绑定到Java类。此外,我不必担心输入字段与列名称的对齐。
生成的html看起来像 ...
这种方法的问题是在html中放置表单元素导致整个表单被挤压到表格的一个单元格中,这看起来不太好并且弄乱了整个布局。有出路吗?我应该用一个colspan替换表的内容,然后将div放在这个元素中并微调css以确保输入字段与表中的列名对齐?
您可以建议更好的解决方案吗? 如果问题不是很清楚,我可以填写更多细节。
答案 0 :(得分:3)
这就是我要做的事情(来自服务器端的开发背景,因为我知道开发人员喜欢简单的解决方案)
<tr><td><input type="text" name="text1" ... /></td><td>second row... </td></tr>
<tr><td colspan="2">And hey, here is more, and the save button ... </td></tr>
在jQuery中将tr替换为检索到的内容(myTr.replace($(ajaxResponse)))
或类似内容
现在,“保存”按钮是表单的常规提交
如果你想通过ajax提交,一旦完成,在你的ajax响应中返回旧的html并用旧的tr替换两个trs(你只需要通过给新的trs一个属性你可以挂钩它在jquery中轻松找到)
不要忘记关闭全局密钥以防止双重编辑,用户可以一次编辑一行
更新:在客户端而不是服务器上添加第二个转储加载解决方案
为了避免服务器过载(虽然我不会担心它会成为常规习惯),你可以将表单字段作为HTML中的模板并使用字符串替换(或jQuery模板),在步骤2中获取响应的ajaxing,你调用模板,并用你在每一行保存的属性替换字符串......像这样:
<div id="myTemplate"> // or you can use jQuery script templates
<tr><td><input type="text" name="${Name}" ... /> id is ${Id}</td><td>${SecondRow}... </td></tr>
<tr><td colspan="2">Save button here.... and may be more text ${MoreText}</td></tr>
</div>
在代码的每一行中添加足够的属性或ID以了解您要替换的内容,如下所示:
<tr data-itemid="34"><td ><input type="text" name="text1" id="findme" ... /></td><td data-moretext="here is more text">second column </td></tr>...etc
所以现在在替换脚本中:
$("#myTemplate").html().replace("${Name}", $(thisrow).find("#findme").attr("name"))
.replace("${Id}",$(thisrow).attr("data-itemid"));
等...
当然在提交后它必须是服务器,但如果用户“取消”你可以有另一个只读模板
顺便说一下,这是我通常使用的方式,我使用jQuery模板,并创建编辑和视图模板,但我也重复编辑表单,我手动使用jQuery ajax提交...但是...我的朋友,这不是一个简单的清洁和可维护的解决方案,我害怕
答案 1 :(得分:1)
我在一年前遇到过这样的问题。这是一个混乱的问题。无论哪种方式,如果您遍历每行td并将其转换为文本字段,或者您可以为此创建单独的jsp文件。
但在这种情况下,最好的方法是将td的内容更改为输入字段并手动发布数据。因为在这种情况下你不能在tr周围包装form标签。您必须手动发布每个输入字段的值。
P.S最佳解决方案是创建编辑对话框。
答案 2 :(得分:1)
还有另一个解决方案,但我的印象是你不会非常喜欢它...你可以使用单个表单来表示整个数据表(允许以表格形式包装整个表)生成输入字段对于当前行,如果已更新,则使用javascript同步提交表单并将td内容恢复为原始html,如果您将字段命名为name =“field []”,则还可以一次提交多行(我不是知道你是否想要那个。)
您可以编写HTML代码,例如
<form action="">
<table>
<tr><td><input type="hidden" name="row[]" value="1"/><input name="field[]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input type="hidden" name="row[]" value="3"/><input name="field[]"/></td></tr>
</table>
</form>
您可以使用jquery抓取表单并通过xmlhttprequest提交它,因为我怀疑如果每行都是一个单独的表单(这是非法的),如果您不想要多行,只需删除[]并提交每一行 并且在提交值得到它们正确编号后,不知道它在java中的确切行为,但在php中我会得到以下内容:
$_GET[row][0] = 1;
$_GET[field][0] = 'value typed in row1';
$_GET[row][1] = 3;
$_GET[field][1] = 'value typed in row3';
替代表定义,以避免再次使用相同的名称
<form action="">
<table>
<tr><td><input name="field[1]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input name="field[3]"/></td></tr>
</table>
</form>
与上面相同的表只是为每个条目设置显式索引,从而避免响应中的重复名称,最好使用唯一标识符,该标识符可以描述您在那里修改的表中的行(如果可能,我使用主键)而不是行号,以防万一不够清楚。
答案 3 :(得分:1)
你试过了吗?
答案 4 :(得分:1)
contenteditable
怎么样?
演示:http://jsfiddle.net/SO_AMK/XQekC/
jQuery:
var ctrlDown = false;
$(document).keydown(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = true;
}
}).keyup(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = false;
}
});
$('#example').dataTable();
$("#example tr").click(function() {
if ($(this).hasClass("row_selected") && ctrlDown) {
submitRow($(this));
return false; // Break out so the next if doesn't run
}
else if ($(this).hasClass("row_selected") && ctrlDown == false) {
return false; // Break out so the next if doesn't run
}
if ($(this).siblings(".row_selected").length && ctrlDown == false) {
$(this).siblings(".row_selected").each(function() {
submitRow($(this));
});
}
$(this).addClass("row_selected");
$(this).children("td").each(function() {
$(this).attr("contenteditable", true);
});
});
function submitRow(elm) {
var data = [];
$(elm).removeClass("row_selected").children("td").each(function() {
data.push($(this).text());
});
alert(data); // This will stop the keyup from firing, but you won't (I hope) really be using alerts
}
除了提交服务器功能之外,它还具有所有内容,它也完全内联并支持选择多行。
唯一的错误是,当它显示数据警报时,焦点偏离主窗口,因此keyup事件永远不会触发,因为您可能不会使用警报,这不应该是一个问题。要在小提琴中修复它,请在警报关闭之后按下并释放ctrl,然后再单击一行。
答案 5 :(得分:0)
我看到了几个问题
如果您有完整的数据,则不需要第2点,假设您使用单击的tr作为参数调用函数f
function f(row)
{
var newRow = yourTable.insertRow(parseInt(row.rowIndex,10)+1);
//you can place the above or below the clicked row , or you can even make the row visible false And then show the new row
Var newCell = newRow.insertCell(0);
newCell.colspan = 6;//the count if columns in your table row
NewCell.innerHTML = " put your HTML content here";
}