我有以下情况:CVCFormType是BenefiItemsFormType的集合。每个BenefitItemFormType都有一个字段,它是BenefitGroupFormType的集合。
我希望能够动态添加和删除元素。
我按照说明here。当然,在讨论嵌套集合时,必须对它们进行调整。
在“固定”方面一切正常。在动态方面(添加和删除元素)到目前为止,我只实现了内侧(添加了BenefitGroups),仅用于添加字段。
这是我得到的(这是不对的)。我在最佳福利项目上有一个双重链接(我应该只有一个),再加上两组链接(第一个好处) 项目和第二个项目不是独立的(我点击上面的第二个,它将一个字段添加到下面的一个)。我想我必须动态更改ul类名。
任何帮助?
以下是截图:
以下是代码:
{% extends "internal.html.twig" %}
{% block content %}
{{ form_start(form) }}
<br><b>CVC</b>
{% for benefititem in form.benefititems %}
<br><b>Benefit Item</b>
{{ form_row(benefititem.comment) }}
<br><b>Benefit Groups</b>
{# <ul class="benefitgroups"> #}
<ul class="benefitgroups" data-prototype="{{ form_widget(benefititem.benefitgroups.vars.prototype)|e }}">
{% for benefitgroup in benefititem.benefitgroups %}
<li>{{ form_row(benefitgroup.name) }}</li>
{% endfor %}
</ul>
{% endfor %}
{{ form_end(form) }}
{% block javascripts %}
<script>
var $collectionHolder;
// setup an "add a benefitgroup" link
var $addBenefitGroupLink = $('<a href="#" class="add_benefitgroup_link">Add a Group</a>');
var $newLinkLi = $('<li></li>').append($addBenefitGroupLink);
jQuery(document).ready(function() {
// Get the ul that holds the collection of benefit groups
$collectionHolder = $('ul.benefitgroups');
// add the "add a benefitgroup" anchor and li to the benefitgroups ul
$collectionHolder.append($newLinkLi);
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
$addBenefitGroupLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new tag form (see next code block)
addBenefitGroupForm($collectionHolder, $newLinkLi);
});
});
function addBenefitGroupForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
// Replace '__name__' in the prototype's HTML to
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a BenefitGroup" link li
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
}
</script>
{% endblock %}
{% endblock content %}
如果它可以帮助这里是生成的HTML:
<html>
<head>
<meta charset="UTF-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<title>Welcome!</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
</head>
<body>
<h1>Here you are inside</h1>
<form name="CVC" method="post" action="">
<br><b>CVC</b>
<br><b>Benefit Item</b>
<div> <label for="CVC_benefititems_0_comment" class="required">Comment</label> <input type="text" id="CVC_benefititems_0_comment" name="CVC[benefititems][0][comment]" required="required" maxlength="400" value="b1" /></div>
<br><b>Benefit Groups</b>
<ul class="benefitgroups" data-prototype="<div id="CVC_benefititems_0_benefitgroups___name__"><div> <label for="CVC_benefititems_0_benefitgroups___name___name" class="required">Name</label> <input type="text" id="CVC_benefititems_0_benefitgroups___name___name" name="CVC[benefititems][0][benefitgroups][__name__][name]" required="required" maxlength="100" /></div></div>">
<li><div> <label for="CVC_benefititems_0_benefitgroups_0_name" class="required">Name</label> <input type="text" id="CVC_benefititems_0_benefitgroups_0_name" name="CVC[benefititems][0][benefitgroups][0][name]" required="required" maxlength="100" value="c1b1" /></div></li>
<li><div> <label for="CVC_benefititems_0_benefitgroups_1_name" class="required">Name</label> <input type="text" id="CVC_benefititems_0_benefitgroups_1_name" name="CVC[benefititems][0][benefitgroups][3][name]" required="required" maxlength="100" value="c2b1" /></div></li>
</ul>
<br><b>Benefit Item</b>
<div> <label for="CVC_benefititems_1_comment" class="required">Comment</label> <input type="text" id="CVC_benefititems_1_comment" name="CVC[benefititems][4][comment]" required="required" maxlength="400" value="b2" /></div>
<br><b>Benefit Groups</b>
<ul class="benefitgroups" data-prototype="<div id="CVC_benefititems_1_benefitgroups___name__"><div> <label for="CVC_benefititems_1_benefitgroups___name___name" class="required">Name</label> <input type="text" id="CVC_benefititems_1_benefitgroups___name___name" name="CVC[benefititems][5][benefitgroups][__name__][name]" required="required" maxlength="100" /></div></div>">
<li><div> <label for="CVC_benefititems_1_benefitgroups_0_name" class="required">Name</label> <input type="text" id="CVC_benefititems_1_benefitgroups_0_name" name="CVC[benefititems][6][benefitgroups][0][name]" required="required" maxlength="100" value="c2b2" /></div></li>
</ul>
<div><button type="submit" id="CVC_submit" name="CVC[submit]">Do Something</button></div><input type="hidden" id="CVC__token" name="CVC[_token]" value="MEUAU3VawkCDJ5jTHo5hSTGrgrWS6XUm-UXeEI9onT8" /></form>
而不是列表,我希望用表格做所有这些(所以在表格中添加和删除行)。
最终目标(添加额外的图层)将如下:
答案 0 :(得分:1)
好吧,正如您所说,您的问题出在动态方面,即客户端。
我要发布你想要做的事情here。
但之前,一个专家提示:永远不会在属性上打印html,使用其他技术,例如我正在使用的技术,模板(替换你的prototype
attr)使用。有更多的技术可以做到这一点,我只是解释一下。
var $outerTemplate;
var $innerTemplate;
var $outerContainer;
jQuery(document).ready(function($) {
$outerTemplate = $('#top-form-template');
$innerTemplate = $('#inner-form-template');
$outerContainer = $("#row-container");
$("#addRow").on('click', function(e){
addOuterForm();
});
$outerContainer.on('click', '.addItem', function (e) {
addInnerForm(e.target.dataset.rowId);
})
$outerContainer.on('click', '.destroy-row', function (e) {
destroyRow(e.target.dataset.rowId);
});
$outerContainer.on('click', '.destroy-item', function (e) {
destroyItem(e.target.dataset.itemId);
});
});
function addOuterForm () {
var compiled = _.template($outerTemplate.html());
var html = compiled({
outerId: _.uniqueId(),
innerId: _.uniqueId()
});
$outerContainer.append(html);
}
function addInnerForm (outerId) {
var compiled = _.template($innerTemplate.html());
var html = compiled({
outerId: outerId,
innerId: _.uniqueId()
});
$outerContainer.find('#row-'+outerId).find('.benefitgroups').append(html);
}
function destroyRow(id){
$("#row-"+id).remove();
}
function destroyItem(id){
$("#item-"+id).remove();
}
我所做的是创建2个模板,一个用于外部表单(一个带有福利项目&amp; group),另一个带有内部表单(额外的好处)项目)。然后附上&amp;使用一些按钮删除它们。我邀请你去看看客户端的模板引擎(我注意到你知道如何使用Twig模板引擎,Handlebars可能很容易找到你。)
我正在使用lodash模板引擎,因为它非常简单且lodash工具非常强大且有用。
答案 1 :(得分:0)
要嵌入多个表单集合,我通常使用自我控件来控制模板。例如:
{{form.name}}
<ul id="benefit-items" data-prototype="{{_self.widget_prototype(form.benefitItems.vars.prototype}|e}}">
{% for benefitItem in form.benefitItems %}
{{_self.widget_prototype(benefitItem)}}
{% endfor %}
<li id="add-benefit-item" onclick="addBenefitItem(this);">add benefit</li>
</ul>
{% macro widget_prototype(form) %}
<li class="benefitItem">
{{form.title}}
<ul class="benefit-group" data-prototype="{{form_widget(form.benefitGroups.vars.prototype)|e}}">
</ul>
</li>
{% endmacro %}
这就是我用来创建多个集合表单的方式。