实现动态 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 模板,我从中删除了所有不相关的代码和样式。此方法使用以下概念:
[]
在输入名称中,以便将发布的数据放入数组中。在处理过程中,我最终得到三个数组 name
、color
和 completed
,它们将包含 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 创建帖子表单并提交它的最短方法是啥? [复制]
使用 Twitter Bootstrap 切换单选按钮,获取表单输入的简洁方式是啥?