我有这个表格:
class BillType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user')
->add('numberPlate')
->add('servicesPerformed', CollectionType::class, array(
'label' => false,
'entry_type' => ServicePerformedType::class,
'allow_add' => true,
))
->add('Save', SubmitType::class)
;
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'DefaultBundle\Entity\Bill'
));
}
作为 ServicePerformedType
类:
class ServicePerformedType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('description', TextareaType::class, array('label' => false))
->add('price', TextType::class, array('label' => false))
->add('quantity', TextType::class, array('label' => false));
}
}
此模板用于呈现表单:
{{ form(form) }}
<a href="#">Add service</a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script type="text/javascript">
var index = 0;
$('a').on('click', function() {
var prototype = $('#bill_servicesPerformed').data('prototype');
prototype = prototype.replace(/_name_/g, index.toString());
$('#bill_servicesPerformed').html(prototype);
index++;
})
</script>
正如 docs 中所述,要获得自定义原型(prototype),我应该在模板顶部添加以下行:
{% form_theme form _self %}
{% block _servicesPerformed_entry_widget %}
I WILL WRITE MY CUSTOM PROTOTYPE HERE
{% endblock %}
但是当我按添加服务
时,我没有收到文本我将在此处编写我的自定义原型(prototype)
,但收到描述
,与之前一样,与
和 ServicePerformedType
类相关的字段quantity
..
注意:也许还有其他方法来自定义表单原型(prototype),但我对此很感兴趣,所以非常感谢有人提供与这种方式自定义表单原型(prototype)相关的解决方案,谢谢。
最佳答案
我必须警告您,自定义原型(prototype)可能有点棘手。如果您更改 FormType
字段,您将需要浏览模板并进行相同的更改,否则您的表单将无法呈现。
我喜欢做的是为该特定字段创建自定义模板,然后对其进行适当的自定义。所以,看看你的代码,我会做这样的事情:
创建页面模板 - 将用于呈现整个页面(包括表单)的模板。
{# MyBundle/Resources/views/myPage.html.twig #} {% extends "::base.html.twig" %} {# This will tell the form_theme to apply the `MyBundle:form/fields/servicePerformed.html.twig` template to your "form" #} {% form_theme form with [ 'MyBundle:form/fields/servicePerformed.html.twig' ] %} {% block body %} <div> {{ form_start(form) }} {{ form_rest(form) }} {{ form_end(form) }} </div> {% endblock %}
现在您需要创建模板
MyBundle/Resources/views/form/fields/servicePerformed.html.twig
。它将仅用于自定义servicePerformed
字段。模板应该看起来像这样{% macro service_template(fields) %} <tr> <td>I WILL WRITE MY CUSTOM PROTOTYPE HERE</td> </tr> {% endmacro %} {# The block name must match your field name! You can find it by going into the debug toolbar -> Forms -> click on your form field and then search for "unique_block_prefix". Copy that and add "_widget" at the end. #} {% block _service_performed_widget %} <table data-prototype="{{ _self.service_template(form.vars.prototype)|e }}"> {% for fields in form.children %} {{ _self.service_template(fields) }} {% endfor %} </table> {% endblock %}
我想指出,在字段模板中,我传递了原始原型(prototype)_self.service_template(form.vars.prototype)
。通过这样做,您可以使用原始字段并将它们呈现在您的自定义原型(prototype)中。例如这段代码:
{% macro service_template(fields) %}
<tr>
<td>{{ form_widget(fields.description) }}</td>
</tr>
{% endmacro %}
将产生类似于以下渲染原型(prototype)的结果:
<tr>
<td>
<input type="text" id="service_performed___name___description" name="service[__name__][description]"/>
</td>
</tr>
然后您可以使用 JavaScript 对其进行操作。
希望这对您有帮助。
关于Symfony:尝试定制一个集合表单原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35489540/