Javascript 如何对齐表格中的表单字段以进行内联编辑?

Javascript 如何对齐表格中的表单字段以进行内联编辑?,javascript,jquery,html,css,spring,Javascript,Jquery,Html,Css,Spring,我正在使用Spring、jsp、javascript和jquery开发一个webapp 我使用datatables显示一个表。 单击表格行时,我希望它将所有字段更改为内联编辑输入、选择等。此外,我希望在下一行中显示一些额外的输入字段和保存按钮 现在我看到了几种方法。我不知道该选哪一个 我可以获得所选行的句柄,然后迭代td并将其转换为输入/选择字段。然后,我可以为新字段和“保存”按钮插入额外的行。 我不认为这是一个干净的解决方案。我将不得不手动发布Post,而不是对表单使用SpringModelA

我正在使用Spring、jsp、javascript和jquery开发一个webapp

我使用datatables显示一个表。 单击表格行时,我希望它将所有字段更改为内联编辑输入、选择等。此外,我希望在下一行中显示一些额外的输入字段和保存按钮

现在我看到了几种方法。我不知道该选哪一个

  • 我可以获得所选行的句柄,然后迭代td并将其转换为输入/选择字段。然后,我可以为新字段和“保存”按钮插入额外的行。 我不认为这是一个干净的解决方案。我将不得不手动发布Post,而不是对表单使用SpringModelAttribute绑定。(我还能在这里使用ModelAttribute吗?)

  • 我可以在jsp文件中创建一个编辑表单,如下所示:

    
    

  • 注意,我在jsp文件中没有开头,因为我计划重用表中现有行中的tr。 这样,我就可以拥有一个干净的表单,并且还可以使用我已经编写的更新方法,该方法将表单绑定到Java类。此外,我不必担心输入字段与列名的对齐问题

    生成的html看起来像 ...

    这种方法的问题是表单元素在html中的位置会导致整个表单被压缩到表的一个单元格中,这看起来不好,并且会弄乱整个布局。有出路吗?我是否应该用具有colspan的替换表的内容,然后在该元素中放置div,并微调css以确保输入字段与表中的列名对齐

    你能提出更好的解决方案吗?
    如果问题不太清楚,我可以填写更多细节。

    一年前我就遇到过这样的问题。这是一个棘手的问题。无论哪种方式,如果您遍历行的每个td并将其转换为文本字段,或者您可以为此创建一个单独的jsp文件

    但在这种情况下,最好是将td的内容更改为输入字段并手动发布数据。因为在这种情况下,您不能将表单标记包装在tr上。您必须手动发布每个输入字段的值


    最好的解决方案是创建一个编辑对话框

    还有另一种解决方案,但我觉得你不会很喜欢。。。您可以对整个datatable使用单个表单(允许将整个表包装在表单中)为当前行生成输入字段,如果更新了,则使用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>
    
    替代表定义,以避免再次使用相同的名称

    <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>
    
    
    第2行的字段值
    
    它与上面的表相同,只是您为每个条目设置了显式索引,从而避免了响应中的重复名称,最好使用唯一标识符,该标识符可以描述您在其中修改的表中的行(如果可能,我使用主键)代替行号,以防不够清楚。

    您是否尝试过:

  • 把整张桌子包起来
  • 将数据项作为禁用输入,并通过CSS隐藏其边框
  • 当用户单击“编辑”时,启用输入并显示边框
  • 每个字段可能都需要隐藏元素
  • 当用户提交表单时,通过ajax发布,并将输入设置回带有隐藏边框的禁用状态
  • 这就是我要做的(来自服务器端开发背景,因为我知道开发人员喜欢简单的解决方案)

  • 用一张表格把桌子包起来
  • 在编辑行(单击行)上,打开一个ajax请求,该请求返回的纯html看起来像是确切的tr,只包含您想要包含的任何额外内容:

  • 在代码的每一行中添加足够的属性或ID,以了解要替换的内容,如下所示:

    <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>
    
    <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
    
    等等

    当然,提交后,它必须是一个服务器,但如果用户“取消”,您可以有另一个只读模板


    顺便说一句,这是我通常使用的方法,我使用jQuery模板,创建编辑和查看模板,但我也重复编辑表单,我使用jQuery ajax手动提交……但是……我的朋友,恐怕不是一个简单的干净和可维护的解决方案

    那么
    contenteditable

    演示:

    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键。

    我发现了几个问题

  • 表中的列数和显示的编辑列数不同
  • 您可能没有完整的数据来编辑行,因此可能需要执行Ajax调用并获取它
  • 如果您有关于的完整数据,那么您不需要第2点,让我们假设您有一个函数f,该函数是以单击的tr作为参数调用的

    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";
    }
    

    谢谢Zahid…我很惊讶我发现有人以前也遇到过类似的问题。你是在使用datatables、spring、jsp的情况下吗?你对“黑客”怎么看将包含输入元素的div与表的列对齐-我没有尝试过,因为我是CSS新手,但最终它看起来像是一个可能会工作的黑客。是的,它是一样的。Spring、JSP、Hibernate等。如果你选择div,那么我想使用datatable会很困难。据我所知,datatables有内嵌edi
    $("#myTemplate").html().replace("${Name}", $(thisrow).find("#findme").attr("name"))
        .replace("${Id}",$(thisrow).attr("data-itemid"));
    
    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
    }​
    
    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";
    }