Choice field default value
Asked Answered
I

5

36

I have the following form:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('type', ChoiceType::class, array(
        'expanded' => true,
        'multiple' => false,

        'choices' => array(
            'Friend' => 'friend',
            'Guide' => 'guide'
        )
    ));
}

How can I make 'Friend' checkbox to be checked by default when the form is rendered ?

Invert answered 3/3, 2016 at 12:14 Comment(0)
G
37

I think you should try with data option, but it's just in the case where you don't even have a data saved inside your object, because it will override it else.

Important : It's good for create action, but not for edit action.

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('type', ChoiceType::class, array(
            'expanded' => true,
            'multiple' => false,

            'choices' => array(
                'Friend' => 'friend',
                'Guide' => 'guide'
            ),
            'data' => 'friend'
        ));
    }

Official link

Extract :

When you create a form, each field initially displays the value of the corresponding property of the form's domain object (if an object is bound to the form). If you want to override the initial value for the form or just an individual field, you can set it in the data option

UPDATE If YOU NEED EMPTY VALUE:

As the answer below, replace data with empty_data if you need in any case to update default value

Gelderland answered 3/3, 2016 at 12:47 Comment(8)
Thank you, it worked! with lowercased 'data' => 'friend'Invert
You're welcome, I'm updating for futur people in same situation as yours.Gelderland
I don't think this is safe: From symfony's own docs > The data option always overrides the value taken from the domain data (object) when rendering. This means the object value is also overriden when the form edits an already persisted object, causing it to lose it's persisted value when the form is submitted.Insignificance
NOPE NOPE NOPE ! The question was about a default value. If you specify the data not only will it not be safe, but you won't ever be to edit your value :p (expect if you change it dynamically)... As the comment noted above... don't use that ! Use empty_data instead!Apathy
I also think that as @Shadi Akil suggest below the better option is to set the default value on the entity (if using entities for form)Weichsel
This answer is misleading and can lead to wrong behavior. Please read all the above warnings before deciding. @AlexanderLomia you should uncheck this as the answer since it may not help others.Involutional
@Involutional Yes, I consideer it, I'm waiting for the asker to unvalidate this answser, I can't deleted it myself : Cannot delete the accepted answer messageGelderland
Yes, wrong answer, this is not behavior expected from the questionEndor
A
18

Use the empty_data form field option. (not data because it will override any posted data unless you set it dynamically).

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('type', ChoiceType::class, array(
        'expanded' => true,
        'multiple' => false,

        'choices' => array(
            'Friend' => 'friend',
            'Guide' => 'guide'
        ),
        'empty_data' => 'friend'
    ));
}

Another option for complex cases is to use Sf Dynamic Form Events.

Apathy answered 18/7, 2017 at 8:49 Comment(3)
Notice : this will not set a default value in the display, only when you will submit data, if nothing submitted, it will take this valueEndor
I love you, 3 days lost because i use "data" in PRE_SUBMIT for set default data in my fields ... and for my bad when i use $event->setData($event->getForm()->getData()); in last my event PRE_SUBMIT ... all data are whrite and i thinking i'm good but when i submit i have the error "Compound forms expect an array or NULL on submission" So... The good way for the futur dev if you want set default value in your form fields use empty_data ;)Hatteras
Ah ah, no problem, happy to help ! ;-)Apathy
D
11

If you don't want to override value for an edition you can do this :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $form = $event->getForm();

        $form->add(
            'type', 
            ChoiceType::class,
            [
                'expanded' => true,
                'multiple' => false,
                'choices' => [
                    'Friend' => 'friend',
                    'Guide' => 'guide'
                ],
                'data' => $event->getData() ?: 'friend'
            ]);
    });
}
Designed answered 26/7, 2018 at 15:30 Comment(3)
This is the best approach IMHO, as it is the only one that selects the default value in the form, while preserving existing values when editing, whereas empty_value only kicks in when saving the data. To quote the documentation on empty_value: It does not set an initial value if none is provided when the form is rendered in a view.Stuffy
I’ve done something similar in Symfony 5 (with add() outside the event handler), and it worked well until I wanted to put the field in a form with inherited_data, because “Forms with the inherit_data option set cannot have *_SET_DATA event listeners.” [ doc ]. I think that I’m just going to set the default value in JavaScript as I only need it when new objects are createdAmbroseambrosi
There is a method "setData" for this. I create array with data and than call it like this: if(!empty($formData['edit'])) { $form->setData($formData['edit']); }Welbie
M
3

An other solution would be to set placeholder as false.
This would set the first value as default and minimize setup effort.
If the field needs to be nullable you could add one more choice i.e. 'empty' => null

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('type', ChoiceType::class, array(
            'expanded' => true,
            'multiple' => false,

            'choices' => array(
                'Friend' => 'friend',
                'Guide' => 'guide'
            ),
             
            'placeholder' => false
        ));
    }
Merrill answered 14/3, 2022 at 7:58 Comment(0)
Q
2

I think it would be better to set initial values in the Entity constructor:

public function __construct()
{
    $this->exercises = new ArrayCollection();

    $this->setTitle("WOCHE#") ;

    $this->setYear(date('Y'));

    $this->setWeekInCalendar(Week::getCurrentWeekInCalendar());
}
Quean answered 1/8, 2018 at 9:13 Comment(1)
i don't think putting logic in the constructor is a good practice rather use a factory or settersBeater

© 2022 - 2024 — McMap. All rights reserved.