Symfony 2 - How to Pass Data to Formbuilder

Passing data to buildForm() in Symfony 2.8, 3.0 and above

This broke some of our forms as well. I fixed it by passing the custom data through the options resolver.

In your form type:

public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->traitChoices = $options['trait_choices'];

$builder
...
->add('figure_type', ChoiceType::class, [
'choices' => $this->traitChoices,
])
...
;
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'trait_choices' => null,
]);
}

Then when you create the form in your controller, pass it in as an option instead of in the constructor:

$form = $this->createForm(ProfileEditType::class, $profile, [
'trait_choices' => $traitChoices,
]);

How do I send extra data to a Symfony 3.2.x form using FormBuilder?

You can create your own custom options for form type like described on http://symfony.com/doc/current/form/create_custom_field_type.html#defining-the-field-type

class CFProgramLevelQuoteType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//$options['entity_id'] contains your id
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('entity_id');
}
}

Pass entity_id:

$form = $this->createForm(CFProgramLevelQuoteType::class, $entity, [
'entity_id' => $entity_id
]);

How can I pass an iteration specific variable to the Form Builder in the Form Collection in Symfony 3?

Likely a CollectionType is not the type you need now to achieve it, because it hides a layer you need to handle (the current item). So the best would be add the answer collection yourself. Something like this:

class AnswerCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach ($options['items'] as $index => $item) {
$builder->add($index + 1, AnswerType::class, [
'item' => $item,
]);
}
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('items');
}
}

class AnswerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$item = $options['item'];

$choices = [];
for ($i = 1; $i <= $item->getNumChoices(); $i++) {
$choices[$i] = $i;
}

$builder->add('value', ChoiceType::class, [
'label' => $item->getLabel(),
'choices' => $choices,
'expanded' => true,
]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired('item');
}
}

Note that AnswerType now requires the item option necessary to build the current choice form correctly.

$formBuilder->add('answers', AnswerCollectionType::class, [
'items' => $items,
])

In the other hand, the CollectionType's workaround is more complex (by using Events) needing a static internal counter to know the current item.

See http://symfony.com/doc/current/form/dynamic_form_modification.html for details.

Passing a parameter to Symfony's FormBuilder add()

Ultimately, the solution was to ensure the initial object graph was correct, rather than messing about with things once the FormBuilder was involved. In terms of getting a custom parameter into the setter, this seems to be the cleanest method:

Symfony form: customize the setter that is called

passing data from controller to Type symfony2

You can pass parameters to the form class as follows:

//PlumeOptionsType.php
protected $profile;

public function __construct (Profile $profile)
{
$this->profile = $profile;
}

Then use it in the query_builder of your buildForm:

$profile = $this->profile;

$builder->add('framePlume', 'entity', array(
'class' => 'DessinPlumeBundle:PhysicalPlume',
'query_builder' => function(EntityRepository $er) use ($profile) {
return $er->createQueryBuilder('pp')
->where("pp.profile = :profile")
->orderBy('pp.index', 'ASC')
->setParameter('profile', $profile)
;
},

));

And finally in your controller:

// fetch $profile from DB
$form = $this->createForm(new PlumeOptionsType($profile), $plumeOptions);

Symfony - pass custom data from Form Builder to form theme

If you put it in your form builder, then you might as well permanently set in your template. If there is some logic required to set the data, then that belongs in your controller anyway, so just put it there to start with.

Controller:

public function someAction()
{

// ....

return $this->render('some_twig_template.twig.html', array(
'attr' => array("test" => "aaa")
);
}

Then in your twig template

{{ dump(attr) }}
{{ dump(attr.test) }}

EDIT:
To render in your template every time, you can set a class on the rendered field directly:

{{ form_label(form.field, 'My label', { 'label_attr': {'class': 'js-hidden-row'} }) }}
{{ form_widget(form.field, { 'attr': {'class': 'js-hidden-row'} }) }}

Then in my javascript you can hide with some simple jQuery:

<script>
jQuery(document).ready(function() {
$('.js-hidden-row').hide();
});
</script>

Pass array of data to form

In your controller :

$form=$this->createForm(YourFormType::class, $yourEntity, array(
'capitals'=>$capitals,
'villages'=>$villages
));

In your form :

public function buildForm(FormBuilderInterface $builder, array $options) {
/** @var array $capitals */
$capitals=$options['capitals'];
/** @var array $villages */
$villages=$options['villages'];

$builder->add('city', EntityType::class, array(...)
->add('vallacap', ChoiceType::class, array(
'mapped'=>false, //Make sure it's not mapped to any entity
'choices'=>array(
'Capitals'=>$capitals,
'Villages'=>$villages
),
'required'=>false,
));
}

public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class'=>Personnalisation::class,
'capitals'=>null, // Set default to null in case argument is not passed
'villages'=>null,
));
}


Related Topics



Leave a reply



Submit