什么是实现动态HTML表单最干净的方法?

时间:2017-01-06 15:00:49

标签: javascript php jquery forms laravel

我想创建一个HTML表单,用户可以一次编辑一组元素。用户必须能够删除元素,编辑元素和添加新元素。我使用PHP(Laravel)作为后端,使用jQuery作为动态表单。

我最初的想法基本上是这样做的:

<form id="bars">
    @foreach($foo as $bar)
        <input type="text" name="name[]" value="{{$bar->name}}" required>
        <input type="color" name="color[]" value="{{$bar->color}}" required>
        <input type="checkbox" name="completed[]"{{$bar->completed ? ' checked' : ''}}>
        <span class="deleteRow"></span>
    @endforeach
</form>

<div id="template" style="display:none;">
        <input type="text" name="name[]" required>
        <input type="color" name="color[]" required>
        <input type="checkbox" name="completed[]"{{$bar->completed ? ' checked' : ''}}>
        <span class="deleteRow"></span>
</div>

<script>
    $(document).ready(function() {
    // Remove rows
        $('form').on('click', '.deleteRow', function() {
            $(this).closest('tr').remove();
        });

        // Clone new rows from template
        $('#addRow').click(function() {
            $('#template tr')
                .clone()
                .appendTo('#bars');
        });
    });
</script>

这是Blade模板,我从中删除了所有不相关的代码和样式。该方法使用以下概念:

    输入名称中的
  • [],以便将POSTed数据放入数组中。在处理过程中,我最终会得到三个数组namecolorcompleted,它们将包含POSTed数据。
  • 现有元素由Blade模板
  • 在表单中呈现为服务器端
  • 从“表单模板”克隆新行。并在用户点击&#34;新行&#34;时添加到表单中按钮。

这很简单,并且在大多数情况下都有效(之前我已经使用过它),但在这种情况下它不起作用,因为它有一个小东西:复选框。未选中的复选框将不会被POST,这意味着completed[]数组的大小将小于其他数组,我无法检查哪些元素已选中复选框。

现在我可以通过这样的方式修改我的JS,它跟踪索引并在每个输入名称中显式插入索引(所以name[0]name[1]等),但这种方法很复杂事实上,表格必须预先填写数据,并且不会空出来。

我可以,而不是通过Blade模板填充数据,让JS也处理(通过JSON API),但也快速复杂,因为JS现在必须解析&#39;表单模板并填写所有值。

以干净的方式实现这一目标的最佳做法是什么?

1 个答案:

答案 0 :(得分:0)

我最终得到的是:

<form id="bars">
    @foreach($foo as $i => $bar)
        <input type="hidden" name="id[{{$i}}]" value="{{$status->id}}">
        <input type="text" class="form-control" name="name[{{$i}}]" value="{{$status->name}}" required>
        <input type="color" name="color[{{$i}}]" value="{{$bar->color}}" required>
        <input type="checkbox" name="completed[{{$i}}]"{{$bar->completed ? ' checked' : ''}}>
        <span class="deleteRow"></span>
    @endforeach
</form>

<div id="template" style="display:none;">
        <input type="text" name="name[$i]" required>
        <input type="color" name="color[$i]" required>
        <input type="checkbox" name="completed[$i]"{{$bar->completed ? ' checked' : ''}}>
        <span class="deleteRow"></span>
</div>

<script>
    $(document).ready(function() {
    // Remove rows
        $('form').on('click', '.deleteRow', function() {
            $(this).closest('tr').remove();
        });

        // Clone new rows from template
        $('#addRow').click(function() {
            $('#template tr')
                .clone()
                .html(function(i, oldHTML) {
                    return oldHTML.replace(/\$i/g, $('#bars tr').length);
                })
                .appendTo('#bars');
        });
    });
</script>

这主要是@MagnusEriksson建议我做的事情(非常感谢!)但是通过不必保留计数器而只是使用表单内的行数作为克隆行的索引,以稍微更清晰的方式解决了。