Display a findAll() result in a form

353 views Asked by At

I'm making an app that handles tags (3 fields : name, description, and color) and I would like to create a single template with a form to add/edit/delete these.

I found multiple answers on internet about many-to-one embedded forms but here, I have no foreign keys, my entity is isolated. I was thinking about making a loop to create my n forms in my controller but this sounds ugly and unoptimized.

I currently have a single form like that :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name',               'text')
        ->add('description',        'textarea')
        ->add('color',              'text')
        ->add('save',               'submit');
}

Now the twig :

{% for thirdPartyTypeForm in thirdPartyTypeForms %}
<div class="col-sm-12">
    {{ form_start(thirdPartyTypeForm, {'attr': {'class': 'form-horizontal realForm'}}) }}
    {{ form_errors(thirdPartyTypeForm) }}

    <div class="row">
        <div class="form-group">
            {{ form_label(thirdPartyTypeForm.name, "Type :", {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
            {{ form_widget(thirdPartyTypeForm.name, {'attr': {'class': 'form-control'}}) }}
        </div>

        <div class="form-group">
            {{ form_label(thirdPartyTypeForm.description, "Description :", {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
            {{ form_widget(thirdPartyTypeForm.description, {'attr': {'class': 'form-control'}}) }}
        </div>

        <div class="form-group">
            {{ form_label(thirdPartyTypeForm.color, "Couleur :", {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
            {{ form_widget(thirdPartyTypeForm.color, {'attr': {'class': 'form-control'}}) }}
        </div>

        {{ form_widget(thirdPartyTypeForm.save, {'attr': {'class': 'btn btn-primary'}, 'label': 'Modifier'}) }}

        {{ form_rest(thirdPartyTypeForm) }}
        {{ form_end(thirdPartyTypeForm) }}
    </div>
</div>
{% endfor %}  

What should I do ?

1

There are 1 answers

0
Richard On

You could use formbuilder without a form class for your parent form with a TagType that you create for the collection field.

E.g. TagType

    class TagType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('name',               'text')
                ->add('description',        'textarea')
                ->add('color',              'text')
                ->add('save',               'submit');
        }

        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'YourNamespace\YourBundle\Entity\YourTagEntity',
            ));
        }

        public function getName()
        {
            return 'tag';
        }
    }

E.g. Form (in controller method)

    $data = ['tags' => $yourTagsFromFindAll];
    $form = $this->createFormBuilder($data)
        ->add('tags', 'collection', ['type' => new TagType()])
        ->add('submit','submit')
        ->getForm();

Then just use the form as normal in your view with $form->createView(). I haven't tested but I believe this approach should work OK.

If you need to add/remove elements on the fly you can do it as per the documentation