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 ?

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you, it worked! with lowercased 'data' => 'friend'
You're welcome, I'm updating for futur people in same situation as yours.
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.
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!
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)
|
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.

3 Comments

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
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 ;)
Ah ah, no problem, happy to help ! ;-)
13

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'
            ]);
    });
}

3 Comments

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.
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 created
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']); }
4

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
        ));
    }

Comments

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());
}

1 Comment

i don't think putting logic in the constructor is a good practice rather use a factory or setters

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.