Nostradamnit
Nostradamnit

Reputation: 860

symfony2 form rendering customization

At work, we are testing several different PHP frameworks. In order to performance test them, we are implementing the same functionality in each one.

We have a REST specification that defines the routes and the data elements used. For example, for the route POST /sprints/create I need to include several fields in the post data, like csrf, sprint_label, sprint_points.

I've created an entity with Label and Points, and a FormType to create the form, but I cannot find any way to change the generated name attributes in the HTML form, which eventually define the POST data names.

I've tried added an {attr: {'name': 'sprint_label'}} in the twig template, but apparently it is just ignored (reserved word I imagine). I've looked at Data Transformers, but it seems to me that the entity property name are tightly coupled to the generated form field names.

I thought about writing an form entity wrapper to remap the names, but I don't understand the magic that happens (which methods are called, with which parameters) between the form generation after the post, and entity manager persist...

Does anyone have any idea how to customize the generated form field names?

Thanks, Sam

Form Code:

<?php
namespace Blah\AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class SprintType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text')
            ->add('points', 'integer')
            ->add('Save', 'submit');
    }

    public function getName()
    {
        return ''; // this removes the sprint[title] name, leaving just title.
    }
}

Upvotes: 1

Views: 112

Answers (2)

Syjin
Syjin

Reputation: 2810

I don't think that you can directly customize the rendered name of the field. However, you can just add the desired name to the builder. Keep in mind, that you have to correct the property path, if the entity doesn't have a corresponding attribute. Try something like

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('sprint_label', 'text', array('property_path' => 'title'))
        ->add('sprint_points', 'integer', array('property_path' => 'points'))
        ->add('Save', 'submit');
}

As you already found out, returning an empty string in getName() removes the name of the form from the field name. But it seems, that this is not the correct solution. Check out https://stackoverflow.com/a/19379696/733368

Instead you should use the form factory and create a named form. Something like

$form = $this->container->get("form.factory")->createNamed(null, new YourFormType(), $entity);

should work.

For further details about form types check the Symfony Form Types Reference

Upvotes: 1

Bartek
Bartek

Reputation: 1359

Instead of rendering whole form you can do it semi-manually, read more

Example:

Possibly your code looks like:

{{ form(form) }}

I think you're looking for:

{{ form_start(form) }}
   {# ... #}

{{ form_widget(form.label, {'attr': {'class': 'sprint_label_or_something'}}) }}

You can also render it fully manually with HTML tags:

<form action="{{ route('your_route') }}">
    <input name="some_type[label]" />
</form>

Upvotes: 1

Related Questions