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

本文概述

  • A.使用remove方法删除字段
  • B.使用buildForm中的选项进行过滤
表单类型的所有字段通常在任何地方使用, 但是在某些情况下, 出于某些原因, 字段不应出现在应用程序的某些部分中。显然, 你不会在前端中渲染字段并使用CSS隐藏它们, 请不要这样做。在这种情况下, 你可以轻松地从” 表单类型” 中删除字段, 因此无需创建不完整的” 表单类型” , 然后在控制器中写入条件字段。
例如, 在本文中, 我们将使用以下FormType即UserType:
< ?phpnamespace 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方法:
< ?phpnamespace userBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; // Classes of the exampleuse 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中的选项进行过滤【如何以编程方式从Symfony 3表单(表单类型)中删除字段】你可能(或可能不知道)知道, createForm方法期望将带有选项的数组作为第三个参数:
/** * Creates and returns a Form instance from the type of the form. * * @param string $typeThe fully qualified class name of the form type * @param mixed$dataThe initial data for the form * @param array$options Options for the form * * @return Form */protected function createForm($type, $data = http://www.srcmini.com/null, array $options = array()){}

作为Form Type类中的第二个参数发送到buildForm函数:
public function buildForm(FormBuilderInterface $builder, array $options)

因此, 你可以使用一个简单的” flag” 参数来指定(仅在定义时)是否呈现密码字段, 例如, 你将需要修改类型并使用以下选项添加条件:
< ?phpnamespace 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:
< ?phpnamespace userBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; // Classes of the exampleuse 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 ...}// .. //}

编码愉快!

    推荐阅读