个性化阅读
专注于IT技术分析

如何以编程方式从Symfony 3表单(表单类型)中删除字段

本文概述

表单类型的所有字段通常在任何地方使用, 但是在某些情况下, 出于某些原因, 字段不应出现在应用程序的某些部分中。显然, 你不会在前端中渲染字段并使用CSS隐藏它们, 请不要这样做。在这种情况下, 你可以轻松地从”表单类型”中删除字段, 因此无需创建不完整的”表单类型”, 然后在控制器中写入条件字段。

例如, 在本文中, 我们将使用以下FormType即UserType:

<?php

namespace userBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

class UserType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class , array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('username', TextType::class, array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('description', TextareaType::class, array(
                "attr" => array(
                    "class" => "form-control", "maxlength" => 255
                )
            ))
            ->add('password', RepeatedType::class, array(
                'type' => PasswordType::class, 'invalid_message' => 'The password fields must match.', 'options' => array(
                    'attr' => array(
                        'class' => 'form-control'
                    )
                ), 'required' => true, 'first_options'  => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat Password'), ))
        ;
    }
 
    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'userbundle_user';
    }
}

该FormType具有4个字段:名称, 用户名, 描述和密码。此表单将用于2个动作:newAction和editAction。在newAction中工作时, 我们不需要删除任何字段, 但是, 当用户进行编辑时, 我们需要删除密码字段, 可以通过两种方式实现:

A.使用remove方法删除字段

通过createForm方法从返回的对象中, 只需调用Form类的remove方法:

<?php

namespace userBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

// Classes of the example
use userBundle\Form\UserType;
use userBundle\Entity\User;


class UserController extends Controller
{
    // .. //

    public function editAction(Request $request, $id){
        $em = $this->getDoctrine()->getManager();
        
        $user = $em->getRepository("userBundle:User")->find($id);
        
        if(!$user){
            throw $this->createNotFoundException("The providen user doesn't exist with id $id");
        }
        
        // Prepare Form
        $editForm = $this->createForm(UserType::class, $user);

        // Remove the password field !
        $editForm->remove('password'); 

        // Rest of the code ...
    }
    
    // .. //
}

这将仅从表单中删除字段, 仅此而已。

B.使用buildForm中的选项进行过滤

你可能(或可能不知道)知道, createForm方法期望将带有选项的数组作为第三个参数:

/**
 * Creates and returns a Form instance from the type of the form.
 *
 * @param string $type    The fully qualified class name of the form type
 * @param mixed  $data    The initial data for the form
 * @param array  $options Options for the form
 *
 * @return Form
 */
protected function createForm($type, $data = null, array $options = array()){}

作为Form Type类中的第二个参数发送到buildForm函数:

public function buildForm(FormBuilderInterface $builder, array $options)

因此, 你可以使用一个简单的” flag”参数来指定(仅在定义时)是否呈现密码字段, 例如, 你将需要修改类型并使用以下选项添加条件:

<?php

namespace userBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

class UserType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class , array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('username', TextType::class, array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('description', TextareaType::class, array(
                "attr" => array(
                    "class" => "form-control", "maxlength" => 255
                )
            ))
        ;

        // If the usePassword options is set to true, if($options["usePassword"]){
            $builder->add('password', RepeatedType::class, array(
                'type' => PasswordType::class, 'invalid_message' => 'The password fields must match.', 'options' => array(
                    'attr' => array(
                        'class' => 'form-control'
                    )
                ), 'required' => true, 'first_options'  => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat Password'), ));
        }
    }
    
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        // Set by default when the options aren't providen, use the password
        $resolver->setDefaults(array(
            'usePassword' => true
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'userbundle_user';
    }
}

请注意, 如果在创建表单时未提供第三个参数, 则需要使用setDefaultOptions来指定值。最后, 在你的控制器中指定一个带有选项的数组, 在这种情况下, 该数组仅是ona, 即具有布尔值的usePassword:

<?php

namespace userBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

// Classes of the example
use userBundle\Form\UserType;
use userBundle\Entity\User;


class UserController extends Controller
{
    // .. //

    public function editAction(Request $request, $id){
        $em = $this->getDoctrine()->getManager();
        
        $user = $em->getRepository("userBundle:User")->find($id);
        
        if(!$user){
            throw $this->createNotFoundException("The providen user doesn't exist with id $id");
        }
        
        // Prepare Form and remove the password field
        $editForm = $this->createForm(UserType::class, $user , [
            'usePassword' => false
        ]);
        
        // Rest of the code ...
    }
    
    // .. //
}

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何以编程方式从Symfony 3表单(表单类型)中删除字段

评论 抢沙发

评论前必须登录!