3

I want all form types to have width property, and to use it like this:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('product_name', 'text', array('width' => "small"));
}

public function buildView(FormView $view, FormInterface $form, array $options)
{
    parent::buildView($view, $form, $options);
    if (array_key_exists(self::OPTION_WIDTH, $options)) {
        $view->vars["attr"]["class"] .= " class_1 class_2 "
    }
}
George V.
  • 43
  • 5

2 Answers2

6

A more generic solution is to create a new Form Type Extension and register it for all types.

The Symfony documentation describes very well how to create a new Form Type Extension: http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html

But it fails to mention how to register that extension for all types.

The "trick" is to specify "field" (or "form" from Symfony 2.3 and next) as the extended type (as a result in getExtendedType() and as the alias in the service configuration)

// src/Acme/DemoBundle/Form/Extension/SpecialWidthTypeExtension.php
namespace Acme\DemoBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class SpecialWidthTypeExtension extends AbstractTypeExtension
{
    /**
     * Returns the name of the type being extended.
     *
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return 'field'; // extend all types
    }

    /**
     * Add the width option
     *
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setOptional(array('width'));
    }

    /**
     * Pass the extra parameters to the view
     *
     * @param FormView $view
     * @param FormInterface $form
     * @param array $options
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        if (array_key_exists('width', $options)) {
            // set an "width" variable that will be available when rendering this field
            $view->vars['width'] = $options['width'];
        }
    }
}

The service configuration:

services:
    acme_demo_bundle.special_width_type_extension:
        class: Acme\DemoBundle\Form\Extension\SpecialWidthTypeExtension
        tags:
            - { name: form.type_extension, alias: field }

In Twig you must check whether the new option was set or not:

{% if width is not null %}
    <div class='col-sm-{{ width }}'>
{% endif %}
sdespont
  • 13,915
  • 9
  • 56
  • 97
  • 2
    FYI: for Symfony 2.3, you must extend "form" and use the alias of "form" in your service configuration. – Andrew Mar 27 '15 at 22:52
0

Add it as an attribute...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('product_name', 'text', array(
        'attr' => array(
            'width' => "small",
        )
    );
}

Then it will be on your fields as width="small".

qooplmao
  • 17,622
  • 2
  • 44
  • 69