Symfony2 嵌入式表单删除按钮功能

Posted

技术标签:

【中文标题】Symfony2 嵌入式表单删除按钮功能【英文标题】:Symfony2 Embedded forms delete button functionality 【发布时间】:2015-03-07 15:47:17 【问题描述】:

我在 Symfony2 中创建了一个嵌入式表单,它在一个“部门”中有许多“员工”。现在,许多员工的“名字”和“姓氏”的添加在“部门”表单上运行良好(为此我使用了 jQuery)。我想要表单上的“删除”按钮功能,我无法弄清楚。谁能帮我删除按钮功能?

部门类型.php

<?php

namespace InstituteEvents\FormBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class DepartmentType extends AbstractType

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
 public function buildForm(FormBuilderInterface $builder, array $options)

    $builder
        ->add('name')
        ->add('employees','collection', array(
            'type' => new EmployeeType(),
            'prototype' => true,
            'allow_add' => true,
            'by_reference' =>false
         ))    
    ;


/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)

    $resolver->setDefaults(array(
        'data_class' => 'InstituteEvents\FormBundle\Entity\Department'
    ));


/**
 * @return string
 */
public function getName()

    return 'department';


EmployeeType.php

<?php

namespace InstituteEvents\FormBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class EmployeeType extends AbstractType

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)

    $builder
        ->add('firstname')
        ->add('lastname')
    ;


/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)

    $resolver->setDefaults(array(
        'data_class' => 'InstituteEvents\FormBundle\Entity\Employee'
    ));


/**
 * @return string
 */
public function getName()

    return 'employee';


index.html.twig - 此文件包含 jQuery 中的“添加员工”按钮功能。在这里,我想要“删除员工”按钮+功能。我不太懂 javascript 或 jQuery,所以我需要帮助来添加“删除员工”按钮 + 代码。

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(function() 
    var index = 0;
    var prototype = $('ul.form-employees').data('prototype');
    $('#form-employee-btn').on('click', function()  
        var newForm = prototype.replace(/__name__/g, index++);
        var newLi = $('<li></li>');

        newLi.append(newForm);
        $(this).before(newLi);
    );
);
</script>    
<form method = "post">
 form_label(form.name, 'Department Name') 
 form_widget(form.name) 

<ul class="form-employees" data-prototype = " form_widget(form.employees.vars.prototype)|e ">
   <input id="form-employee-btn" type="button" value="Add Employees"/>
</ul>

    form_widget(form._token) 

<input type="submit" value="Submit"/>

</form>

【问题讨论】:

您应该使用文档:symfony.com/doc/current/cookbook/form/…,因为您所需要的都在里面 我无法从食谱转换为上面 index.html.twig 中“删除员工”按钮及其代码的 jQuery 代码。请帮忙 Hey Udan,你能帮我编写“删除员工”按钮的 jQuery 代码吗?因为我不知道 jQuery 您尚未在DepartmentType 表单上设置allow_delete 属性。如何处理删除被广泛覆盖here(PHP + jQ 代码) 谢谢 Elias Van Ootegem 【参考方案1】:

按照in the docs找到的说明进行操作:

在您的DepartmentType 表单类中,将EmployeeType 集合的allow_delete 属性设置为true

    $builder
        ->add('name')
        ->add('employees','collection', array(
            'type' => new EmployeeType(),
            'prototype' => true,
            'allow_add' => true,
            'allow_delete' => true,//add this
            'by_reference' =>false
         )
    );

接下来,添加删除按钮(通过 EmployeeType 表单 (-&gt;add('delete', 'button')) 中的构建器,或手动添加(在模板中使用 JS)。然后将事件侦听器附加到表单。假设您已添加像这样的删除按钮:

//EmployeeType:
$builder->add('delete', 'button', ['attr' => ['class' => 'delete-employee']]);

如果您在视图中使用 JS 添加按钮,那么这段代码应该可以解决问题:

$('#department-form-selector').children('employee-form-selector').each(function(i)

    $(this).append('<button name="delete' + i + '" class="delete-employee">Delete</button>');
);

当按钮已经添加(或即将添加)时,使用 jQ 附加一个监听器。在这个阶段,按钮不需要在 DOM 中,因为我们使用的是事件委托,而不是直接绑定:

$('#department-form-selector').on('click', '.delete-employee', function()

    $(this).closest('form').delete();//remove element
    //optionally submit department form via AJAX call to persist the delete
    return false;//stop event
);

现在,处理表单(假设实体设置正确):

//in the controller that handles the form:
if ($form->isValid())

    //1 => we need to query for the data in the DB, so we know what to delete
    $current = $service->getCurrentDepartmentWithEmployees();
    //get the current employees, that need to be updated
    $oldEmployees = new ArrayCollection();
    foreach ($current->getEmployees() as $employee)
        $oldEmployees->add($employee);
    //2 => get the form data
    $department = $form->getData();
    //3 => check if one or more eployees were deleted
    foreach ($oldEmployees as $employee)
    
        if (!$department->getEmployees()->contains($employee))
        //employee was removed, update entity/entities
            $current->getEmployees()->removeElement($employee);
            //depending on the relations you've specified:
            $employee->setDepartment(null);
            $em->persist($employee);
            $em->persist($current);
        
    
    $em->flush();

请注意,此代码未经测试。这是最坏情况下删除的基本流程(双向、一对多关系被反转,但未设置 ondelete 级联限制)。 使用此代码作为参考,您应该能够解决它,但是

【讨论】:

感谢代码,但我想在“twig”(index.html.twig)中添加“删除员工”按钮,就像我为“添加”按钮而不是在“EmployeeType”中所做的那样" .ie 同样我想有“删除员工”按钮并在“index.html.twig”中有删除功能?你能在“index.html.twig”中提供整个代码吗? 作为“添加”按钮,我没有在“DepartmentType”或“EmployeeType”中提供,但我使用 HTML 在 Twig 中包含了“添加”按钮的代码 @sachintendulkar:我已经添加了两种方法来为每个员工添加一个删除按钮(包含$(this).append() 的位)。 deleteAll 按钮与单个删除基本相同,只需在所有员工表单元素上调用remove(),然后提交该表单,并以相同的方式处理它。这是一个简单的事情,添加一个按钮元素 + 事件处理程序,查询所有员工表单的 DOM,循环它们 ($('emplyee-form-selector').each(function()$(this).remove())),然后提交表单 @sachintendulkar:除此之外:不,我不会向您提供所有代码,那不是我的工作。如果您遇到特定问题,我愿意为您提供帮助,但我不会免费为您完成工作......抱歉 如果您能给我提供 index.html.twig 中“删除员工”按钮的代码及其功能,就像我提供“添加”按钮及其代码一样,我将不胜感激“index.html.twig”作为一个整体,请

以上是关于Symfony2 嵌入式表单删除按钮功能的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - 验证不适用于嵌入式表单类型

Symfony2 Doctrine ODM 嵌入类表单验证

将数据对象传递/绑定到内部/嵌入的 Symfony2 表单

Symfony 2 使用一对多数据库关系的嵌入式表单

阻止 SonataAdmin / Symfony2 使用 sonata_type_admin 嵌入式管理员创建空对象

Symfony 2. 如何为实体的嵌入表单设置默认值?