实现动态 HTML 表单的最简洁方法是啥?

Posted

技术标签:

【中文标题】实现动态 HTML 表单的最简洁方法是啥?【英文标题】:What's the cleanest way to implement a dynamic HTML form?实现动态 HTML 表单的最简洁方法是什么? 【发布时间】:2017-05-21 08:56:02 【问题描述】:

我想制作一个 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 模板,我从中删除了所有不相关的代码和样式。此方法使用以下概念:

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

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

现在我可以修改我的 JS,使其跟踪索引并在每个输入名称中显式插入索引(例如 name[0]name[1] 等),但这种方法很复杂,因为表格必须预先填写数据,并且一开始不能为空。

我可以,而不是通过 Blade 模板填充数据,让 JS 也处理它(通过 JSON API),但这也会很快变得复杂,因为 JS 现在必须“解析”表单模板并填写所有内容值。

以干净的方式完成此任务的最佳做法是什么?

【问题讨论】:

(document).ready( ... )更改为$(document).ready( ... ) 啊,我当然是那个意思;)这只是复制粘贴代码时的错误。我已经编辑了问题。 哦,哈哈:D 我正在查看您的代码,一切似乎都很好:/您确定您已包含必要的所有内容吗? 在什么方面看起来不错?并不是代码没有运行。这是我要问的一个实施问题;这个提议的解决方案在我的情况下不起作用,因为我的复选框破坏了输入名称中的 [] 方法。 (未选中的复选框未发布)所以我正在寻找另一种没有此问题的干净方法。 您可以为动态字段设置索引,例如:name[1]checkbox[1](添加某种关系)。然后当你在后端循环你的数组时,你可以看到哪个复选框(如果有的话)是相关的。您需要在初始循环中打印该索引,然后在从模板中添加新元素时动态添加它。 【参考方案1】:

我最终得到的是以下内容:

<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 建议我做的(非常感谢!),但通过不必保留计数器而只需使用表单内的行数作为克隆行的索引,以一种稍微干净的方式解决了。

【讨论】:

以上是关于实现动态 HTML 表单的最简洁方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 创建帖子表单并提交它的最短方法是啥? [复制]

实现 Django 3 模态表单的最佳方法是啥?

使用 Twitter Bootstrap 切换单选按钮,获取表单输入的简洁方式是啥?

使用 SWIG 包装对象从 C++ 调用 Python 函数的最简洁方法是啥

使随机标签位置适应窗口大小的最有效方法是啥?

在 R Shiny 中实现 CRUD 工作流的最简洁方法是啥?