Symfony2 Настройка выбора поля по умолчанию - PullRequest
68 голосов
/ 10 ноября 2011

Я создаю форму следующим образом:

$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 выглядят так:

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

Ответы [ 12 ]

109 голосов
/ 13 февраля 2012

Вы можете определить значение по умолчанию из атрибута data.Это часть абстрактного типа «field» (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();

. В этом примере в качестве выбранного по умолчанию значения будет использоваться «Черновик».

58 голосов
/ 02 июля 2013

Если вы используете решение Кристиана , вам нужно добавить 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);

// ...

От Документы Doctrine :

Метод EntityManager#getReference ($ entityName, $ identifier) ​​позволяет получить ссылку на объект, для которого известен идентификатор, без загрузки этого объекта из базы данных.Это полезно, например, для повышения производительности, когда вы хотите установить связь с сущностью, для которой у вас есть идентификатор.

23 голосов
/ 10 апреля 2012

решение: для типа объекта используйте опцию «данные», но значение - это объект. то есть:

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

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

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

))
6 голосов
/ 05 декабря 2011

Я думаю, что вы должны просто использовать $breed->setSpecies($species), например, в моей форме у меня есть:

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

, и это устанавливает мой выбор по умолчанию на текущую дату.Должен работать так же для внешних объектов ...

3 голосов
/ 23 марта 2017

Я не думаю, что вам следует использовать опцию 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
     ]
 );
3 голосов
/ 07 марта 2015

Если вы хотите передать массив сущностей 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,
    ]);
}
2 голосов
/ 31 августа 2015

Настройка выбора по умолчанию для переключателя 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 голосов
/ 10 декабря 2012

Из документов:

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

mixed $ data = null - это параметры по умолчанию.Так, например, у меня есть поле с именем status, и я реализовал его так:

$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 голосов
/ 18 ноября 2011

Я не уверен, что вы делаете неправильно, когда я создаю форму, используя классы форм, 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(),
    ));

Класс типа объекта кампании (src: 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';
    }
}
1 голос
/ 01 ноября 2013

Форма должна автоматически сопоставить значение видов-> идентификатор с выбранным полем выбора объекта. Например, если у вас есть объект Breed, который имеет отношение OnetoOne к объекту Species в объединительной таблице с именем 'breed_species':

class Breed{

    private $species;

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

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

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

Поле 'видов' в классе формы должно брать значение вида-> 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()
            )
    );
...