35

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 ?

Alex Lomia
  • 6,705
  • 12
  • 53
  • 87

5 Answers5

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

BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105
  • 1
    Thank you, it worked! with lowercased `'data' => 'friend'` – Alex Lomia Mar 03 '16 at 12:56
  • 2
    You're welcome, I'm updating for futur people in same situation as yours. – BENARD Patrick Mar 03 '16 at 12:58
  • 9
    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.__ – user2268997 Jul 08 '17 at 10:38
  • 3
    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! – Romain Bruckert Jul 18 '17 at 08:44
  • 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) – Quisse Jan 22 '19 at 10:22
  • 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. – mr1031011 Feb 12 '19 at 16:36
  • @mr1031011 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` message – BENARD Patrick Feb 12 '19 at 16:48
  • Yes, wrong answer, this is not behavior expected from the question – Vincent Decaux Sep 07 '19 at 12:19
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.

Romain Bruckert
  • 2,546
  • 31
  • 50
  • 7
    Notice : this will not set a default value in the display, only when you will submit data, if nothing submitted, it will take this value – Vincent Decaux Sep 07 '19 at 12:12
  • 1
    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 ;) – Sinelc Feb 17 '21 at 10:32
  • Ah ah, no problem, happy to help ! ;-) – Romain Bruckert Mar 05 '21 at 10:23
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'
            ]);
    });
}
Fabien Salles
  • 1,101
  • 15
  • 24
  • 1
    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.` – krom Aug 29 '18 at 13:06
  • 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](https://symfony.com/doc/current/form/inherit_data_option.html) ]. I think that I’m just going to set the default value in JavaScript as I only need it when new objects are created – user1738984 May 27 '20 at 14:17
  • 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']); } – Patryk Godowski Apr 09 '21 at 08:55
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());
}
Shadi Akil
  • 373
  • 3
  • 11
  • 1
    i don't think putting logic in the constructor is a good practice rather use a factory or setters – medunes Jul 26 '20 at 15:54
2

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
        ));
    }
pok_net
  • 358
  • 3
  • 12