简体   繁体   English

Symfony2 Embedded表单删除按钮功能

[英]Symfony2 Embedded forms delete button functionality

I have created an embedded form in Symfony2 which has many "Employees" in one "Department". 我在Symfony2中创建了一个嵌入式表单,在一个“部门”中有许多“员工”。 Now, the Addition of many employees with their "Firstname" and "Lastname" is working fine on the "Department" form (I have used jQuery for this purpose). 现在,添加许多员工的“名字”和“姓氏”在“部门”表格上工作得很好(我已经为此目的使用了jQuery)。 I want the "Delete" button functionality on the form, which I am unable to figure out. 我想要表单上的“删除”按钮功能,我无法弄清楚。 Can anyone help me with the delete button function? 任何人都可以帮我删除按钮功能吗?

DepartmentType.php DepartmentType.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 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 - This file contains the "add employees" button functionality in jQuery. index.html.twig - 此文件包含jQuery中的“添加员工”按钮功能。 Here I want the "delete employees" button + functionality. 在这里,我想要“删除员工”按钮+功能。 I don't know javascript or jQuery properly, so I need help in adding the "delete employees" button + the code for it. 我不能正确地了解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>

Following the instructions found in the docs : 按照文档中的说明操作:

In your DepartmentType form class, set the EmployeeType collection's allow_delete attribute to true : 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
         )
    );

Next, add the delete button (either through the builder in your EmployeeType form ( ->add('delete', 'button') ), or manually (using JS in the tempalte). Then attach an event listener to the form. Assuming you've added the delete button like so: 接下来,添加删除按钮(通过EmployeeType表单中的构建器( ->add('delete', 'button') ),或手动(在tempalte中使用JS)。然后将事件监听器附加到表单。你已经添加了删除按钮,如下所示:

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

If you're adding the buttons using JS in the view, then this code should do the trick: 如果您在视图中使用JS添加按钮,那么此代码应该可以解决问题:

$('#department-form-selector').children('employee-form-selector').each(function(i)
{
    $(this).append('<button name="delete' + i + '" class="delete-employee">Delete</button>');
});

When the buttons have been added (or are about to be added), attach a listener using jQ. 当添加(或即将添加)按钮时,使用jQ附加一个监听器。 The buttons needn't be in the DOM at this stage, because we're using event delegation, instead of direct binding: 在这个阶段,按钮不需要在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
});

Now, to handle the form (assuming the entities are set up properly): 现在,要处理表单(假设实体设置正确):

//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();
}

Note that this code is untested . 请注意,此代码未经测试 It's the basic flow of a worst-case-scenario deletion (bi-directional, one to many relation that is inversed, but no ondelete cascade restrictions have been set). 这是最坏情况场景删除的基本流程(双向,一对多关系被反转,但没有设置删除级联限制)。
Using this code as a reference, you should be able to work it out, though 但是,使用此代码作为参考,您应该能够解决这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM