Home > Mobile >  Symfony Forms - Fieldtype label by property of the dataobject within a CollectionType
Symfony Forms - Fieldtype label by property of the dataobject within a CollectionType

Time:01-06

Is it possible to set the label value of a form type to be a property value that is available in the data object using the CollectionType?

Main FormType class:

class ShapeType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {        
        $builder->add('shape_fractions', CollectionType::class, [
            'entry_type' => ShapeFractionType::class,
            'entry_options' => ['label' => false],
        ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Shape::class,
        ]);
    }
}

The Shape data class:

class Shape
{
    public array $shape_fractions;
       
    // ...
}

ShapeFractionType class:

class ShapeFractionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // 'data' index not available in collection mode:
        $shapeFraction = $options['data'];

        $builder
            ->add('value', NumberType::class, [
                'label' => $shapeFraction->name //error
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => ShapeFraction::class,
        ]);
    }
}

The ShapeFraction data class:

class ShapeFraction
{
    public string $name;
    public string $type;
    public float $value;

    // ...
}

Rendering the form:

$shapeFractions = [
    new ShapeFraction('A', 'length', 10),
    new ShapeFraction('B', 'length', 20),
]
$shape = new Shape($shapeFractions)
$form = $formFactory->create(ShapeType::class, $shape);

// Render using Twig...

The result is an error message that the 'data' index is not available within the options. Using the ShapeFractionType directly without the parent layer of of the ShapeType, it works. So it seems that the CollectionType strips out the 'data' index for some reason.

My main goal is to use the 'name' property of the fraction as label for the value field: Shape form: A: <input..> B: <input..>

Thanks in advance!

CodePudding user response:

You can use an event listener to access the "current" item in the collection, this should work:

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

class ShapeFractionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $form = $event->getForm();
            $form->add('value', NumberType::class, [
                'label' => $event->getData()->name
            ]);
        });
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => ShapeFraction::class,
        ]);
    }
}

Credits to this answer: https://stackoverflow.com/a/55352083/3960296

  • Related