Symfony:尝试定制一个集合表单原型(prototype)

标签 symfony

我有这个表格:

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 字段,您将需要浏览模板并进行相同的更改,否则您的表单将无法呈现。

我喜欢做的是为该特定字段创建自定义模板,然后对其进行适当的自定义。所以,看看你的代码,我会做这样的事情:

  1. 创建页面模板 - 将用于呈现整个页面(包括表单)的模板。

    {# 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 %}
    
  2. 现在您需要创建模板 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/

相关文章:

forms - 如何在一处显示所有表格错误

Symfony2 删除并保存多对多关系

symfony - 在ElasticSearch中管理关系的最佳方法是什么?

php - 使用 Symfony 和 FOSRestBundle 保存多对一关系

symfony - 从命令类访问参数

Symfony2 phpunit 功能测试自定义用户身份验证在重定向后失败( session 相关)

php - 如何在 Symfony2 Twig 模板中调用静态函数

Symfony 信使和邮件程序 : how to add a binding_key?

testing - Symfony2 演示测试问题

php - Symfony2 和 Doctrine2 - 具有关系实体的 QueryBuilder