Symfony2设置默认选择字段选择


69

我以以下方式创建表单:

$form = $this->createFormBuilder($breed)
             ->add('species', 'entity', array(
                  'class' => 'BFPEduBundle:Item',
                  'property' => 'name',
                  'query_builder' => function(ItemRepository $er){
                      return $er->createQueryBuilder('i')
                                ->where("i.type = 'species'")
                                ->orderBy('i.name', 'ASC');
                  }))
             ->add('breed', 'text', array('required'=>true))
             ->add('size', 'textarea', array('required' => false))
             ->getForm()

如何为物种列表框设置默认值?


谢谢您的回应,对不起,我想改写我的问题。一旦有了从模型中检索到的值,如何为物种选择列表中的相应值将该值设置为SELECTED =“ yes”?

因此,TWIG视图中的select选项输出将如下所示:

<option value="174" selected="yes">Dog</option>

@Mat我不确定所选答案(看我在那里做的吗?)是最好的答案?
crmpicco

Answers:


60

如果使用Cristian的解决方案,则需要将注入EntityManager到您的FormType类中。这是一个简化的示例:

class EntityType extends AbstractType{
    public function __construct($em) {
        $this->em = $em;
    }

    public function buildForm(FormBuilderInterface $builder, array $options){
         $builder
             ->add('MyEntity', 'entity', array(
                     'class' => 'AcmeDemoBundle:Entity',
                     'property' => 'name',
                     'query_builder' => function(EntityRepository $er) {
                         return $er->createQueryBuilder('e')
                             ->orderBy('e.name', 'ASC');
                     },
                     'data' => $this->em->getReference("AcmeDemoBundle:Entity", 3)
        ));
    }
}

和您的控制器:

 // ...    

 $form = $this->createForm(new EntityType($this->getDoctrine()->getManager()), $entity);

// ...

学说文档

使用EntityManager#getReference($ entityName,$ identifier)方法,您可以获取对已知标识符的实体的引用,而无需从数据库中加载该实体。例如,当您想与您拥有标识符的实体建立关联时,这对于提高性能非常有用。


5
Symfony2中预选选择字段的完美答案
Ajay Patel

1
这也将有助于创建一个数组,该数组可用于实体字段类型的“ preferred_choices”
j_goldman 2013年

在symfony2.0中,该选项的替代方案是什么data
smarber 2014年

1
如果此解决方案有帮助,请确保给克里斯蒂安的解决方案以投票:)
Carrie Kendall

您将如何在Symfony3中做到这一点?您不能再注入实体管理器了,不是吗?
鲁比

113

您可以从“数据”属性中定义默认值。这是抽象“字段”类型的一部分(http://symfony.com/doc/2.0/reference/forms/types/field.html

$form = $this->createFormBuilder()
            ->add('status', 'choice', array(
                'choices' => array(
                    0 => 'Published',
                    1 => 'Draft'
                ),
                'data' => 1
            ))
            ->getForm();

在此示例中,“草稿”将设置为默认选定值。


这对我有用。我在'data'属性中提供了一组默认值,这也起作用。谢谢!
尼尔斯·卢克斯顿,2012年

3
这似乎不适用于单选按钮。可能只是我。
杰森·斯威特

2
数据必须引用选择数组的键。如果您有多种选择:array('foo1'=>'bar1','foo2'=>'bar2',...),则必须指定'data'=> array('foo1','foo2',。 ..)。杰森,也许那就是你的问题所在。
朱利安

我认为这应该是首选的答案。它很容易使用。
阿尔文·邦克

如果您将任何实体传递给表单(例如,用于编辑页面),这将覆盖从实体获取的值,而不是一个好方法
Vincent Decaux

23

解决方案:对于类型实体,使用选项“数据”,但值是一个对象。即:

$em = $this->getDoctrine()->getEntityManager();

->add('sucursal', 'entity', array
(

    'class' => 'TestGeneralBundle:Sucursal',
    'property'=>'descripcion',
    'label' => 'Sucursal',
    'required' => false,
    'data'=>$em->getReference("TestGeneralBundle:Sucursal",3)           

))

7

我认为您应该简单地使用$breed->setSpecies($species),例如以我的形式使用:

$m = new Member();
$m->setBirthDate(new \DateTime);
$form = $this->createForm(new MemberType, $m);

并将我的默认选择设置为当前日期。对于外部实体应该以相同的方式工作...


我的问题与DateType完全一样,但我的故事是添加“” =>“选择...”作为默认选择选项,以强制为生日进行合理选择。我可以在选项中显示“选择”,只是不使用默认值。每尝试一次,Symfony都会抱怨它期望使用DateTime类型的参数。我使用的是Symfony2的旧版本;我认为他们使用新的占位符选项对其进行了改进。
phpguru

4

如果要传递一组Doctrine实体,请尝试以下类似的方法(Symfony 3.0+):

protected $entities;
protected $selectedEntities;

public function __construct($entities = null, $selectedEntities = null)
{
    $this->entities = $entities;
    $this->selectedEntities = $selectedEntities;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('entities', 'entity', [
        'class' => 'MyBundle:MyEntity',
        'choices' => $this->entities,
        'property' => 'id',
        'multiple' => true,
        'expanded' => true,
        'data' => $this->selectedEntities,
    ]);
}

1
不错的解决方案,当将实体呈现为复选框时,以及当我需要根据实体的某个属性值将它们设置为选中状态时,效果很好。
TheGhost

如果您需要提供类名而不是对象,则无法在Symfony 2.8+中使用

3

我认为您不应该使用该data选项,因为这不仅仅是设置默认值。您还将覆盖在创建过程中传递给表单的所有数据。因此,基本上,您正在破坏对该功能的支持。-当您让用户创建数据时,这可能并不重要,但是当您想要(某天)使用表单更新数据时,这并不重要。

看到 http://symfony.com/doc/current/reference/forms/types/choice.html#data

我相信最好在表单创建过程中传递任何默认数据。在控制器中。

例如,您可以传入一个类并在类本身中定义默认值。(使用默认值时Symfony\Bundle\FrameworkBundle\Controller\Controller

$form = $this->createForm(AnimalType::class, [
    'species' => 174 // this id might be substituted by an entity
]);

或使用对象时:

$dog = new Dog();
$dog->setSpecies(174); // this id might be substituted by an entity

$form = $this->createForm(AnimalType::class, $dog);

使用工厂时甚至更好:(狗可能来自动物)

$form = $this->createForm(AnimalType::class, DogFactory::create());

这将使您能够将表单结构和内容彼此分开,并使表单在更多情况下可重复使用。


或者,使用 preferred_choices选项,但这具有将默认选项移至表单顶部的副作用。

请参阅:http : //symfony.com/doc/current/reference/forms/types/choice.html#preferred-choices

$builder->add(
    'species', 
    'entity', 
    [
        'class' => 'BFPEduBundle:Item',
        'property' => 'name',
        'query_builder' => ...,
        'preferred_choices' => [174] // this id might be substituted by an entity
     ]
 );

2

我不确定您在这里做错了什么,当我使用表单类构建表单时,Symfony会在列表中选择正确的选项。这是我的一种有效形式的示例。

在控制器中进行编辑操作:

$entity = $em->getRepository('FooBarBundle:CampaignEntity')->find($id);

if (!$entity) {
throw $this->createNotFoundException('Unable to find CampaignEntity entity.');
}


$editForm = $this->createForm(new CampaignEntityType(), $entity);
$deleteForm = $this->createDeleteForm($id);

return $this->render('FooBarBundle:CampaignEntity:edit.html.twig', array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    ));

广告系列实体类型类(源:Foo \ BarBundle \ Form \ CampaignEntityType.php):

namespace Foo\BarBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Doctrine\ORM\EntityRepository;

class CampaignEntityType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
        ->add('store', 'entity', array('class'=>'FooBarBundle:Store', 'property'=>'name', 'em'=>'my_non_default_em','required'  => true, 'query_builder' => function(EntityRepository $er) {return $er->createQueryBuilder('s')->orderBy('s.name', 'ASC');}))
        ->add('reward');
    }
    public function getName()
    {
        return 'foo_barbundle_campaignentitytype';
    }
}

我想我可能会错误地构建表格,非常感谢您的示例,我将尝试一下,让您知道它的进展!
Matt G

克里斯,您好,我有点困惑您如何在一个视图中创建两个表单,您是否有可能张贴树枝模板的示例以及如何在树枝模板中处理这两个表单?
Matt G

抱歉,回复延迟...没有看到您的评论:(对于这里的编辑/删除表格,这是我的细枝内容<form action="{{ path('myroute_campaign_entity__update', { 'campaignId':campaignId,'id': entity.id }) }}" method="post" {{ form_enctype(edit_form) }}> {{ form_widget(edit_form) }} <p> <button type="submit">Edit</button> </p> </form> <form action="{{ path('myroute_campaign_entity__delete', { 'campaignId':campaignId,'id': entity.id }) }}" method="post"> {{ form_widget(delete_form) }} <button type="submit">Delete</button> </form>
Chris

这也是createDeleteForm函数private function createDeleteForm($id) { return $this->createFormBuilder(array('id' => $id)) ->add('id', 'hidden') ->getForm() ; }
克里斯,克里斯,

2

从文档:

public Form createNamed(string|FormTypeInterface $type, string $name, mixed $data = null, array $options = array())

混合$ data = null是默认选项。因此,例如,我有一个名为状态的字段,并按如下方式实现了它:

$default = array('Status' => 'pending');

$filter_form = $this->get('form.factory')->createNamedBuilder('filter', 'form', $default)
        ->add('Status', 'choice', array(
            'choices' => array(
                '' => 'Please Select...',
                'rejected' => 'Rejected',
                'incomplete' => 'Incomplete',
                'pending' => 'Pending',
                'approved' => 'Approved',
                'validated' => 'Validated',
                'processed' => 'Processed'
            )
        ))->getForm();

2

设置symfony2单选按钮的默认选择

            $builder->add('range_options', 'choice', array(
                'choices' => array('day'=>'Day', 'week'=>'Week', 'month'=>'Month'),
                'data'=>'day', //set default value 
                'required'=>true,
                'empty_data'=>null,
                'multiple'=>false,
                'expanded'=> true                   
        ))

2
如果您编辑现有实体不起作用,那么将始终选择该选项
the_nuts

使用empty_data而不是data设置默认值,并且仍然能够编辑实体。
Ryguydg

不,empty_data不显示任何默认值,仅在提交表单时使用
Vincent Decaux

1

该表格应将物种-> id值自动映射到所选实体选择字段。例如,如果在名为“ breed_species”的联接表中有一个Breed实体与一个Species实体具有OnetoOne关系:

class Breed{

    private $species;

    /**
    * @ORM\OneToOne(targetEntity="BreedSpecies", mappedBy="breed")
    */
    private $breedSpecies;

    public function getSpecies(){
       return $breedSpecies->getSpecies();
    }

    private function getBreedSpecies(){
       return $this->$breedSpecies;
    }
}

表单类中的字段'species'应​​该从传递给表单的Breed类中的'species'属性对象中选取种类-> id值。

另外,您可以通过使用SetData()将种类实体显式传递到表单中来显式设置值:

    $breedForm = $this->createForm( new BreedForm(), $breed );
    $species   = $breed->getBreedSpecies()->getSpecies();

    $breedForm->get('species')->setData( $species );

    return $this->render( 'AcmeBundle:Computer:edit.html.twig'
                        , array( 'breed'     => $breed
                               , 'breedForm' => $breedForm->createView()
            )
    );

0

您可以使用此表单在要编辑的模型中定义正确的默认值,也可以指定empty_data选项,以便代码变为:

$form = $this
    ->createFormBuilder($breed)
    ->add(
        'species',
        'entity',
        array(
            'class'         => 'BFPEduBundle:Item',
            'property'      => 'name',
            'empty_data'    => 123,
            'query_builder' => function(ItemRepository $er) {
                return $er
                    ->createQueryBuilder('i')
                    ->where("i.type = 'species'")
                    ->orderBy('i.name', 'ASC')
                ;
            }
        )
    )
    ->add('breed', 'text', array('required'=>true))
    ->add('size', 'textarea', array('required' => false))
    ->getForm()
;

'empty_data'属性似乎没有任何作用
Matt G

-1

您可以使用“ preferred_choices”和“ push”您要选择的名称到列表顶部。然后默认情况下将其选中。

'preferred_choices' => array(1), //1 is item number

实体字段类型


4
使用preferred_choices属性确实会将名称推到列表的顶部,但默认情况下不会将其选中。因为我在TWIG模板中设置了默认值,如下所示:{{form_widget(form.species,{'empty_value':'请选择...'})}}'请选择...默认值,如果您单击列表框,则“ preferred_choice”项是该选项下的第一个可用选项
Matt G

是的,很高兴知道这一点,但似乎并不能解决所要求的问题。
杰森·斯威特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.