Search code examples
phpsymfonyoopformbuilder

How can I wrap my input field with a <div> tag when using with Symfony formbuilder?


I am creating an input field with Symfony:

$formBuilder->add($field['fieldName'], TextType::class, array('attr' => array('class' => 'form-control')));

The output is:

<input type="text" id="form_color" name="form[color]" class="form-control">

The output I would need is:

<div class="cp input-group colorpicker-component">
<input type="text" id="form_color" name="form[color]" class="form-control" /> <span class="input-group-addon"><i></i></span>
</div>

This means I somehow have to add a parent to the specific form field. I cannot add it to the actual form, because this parent div is only added to the field in specific cases. Is there a way to do it in the formbuilder?


Solution

  • I'd create my own custom field type to handle these fields.

    First define the field class

    // src/Form/Type/ColorSelectorType.php
    namespace App\Form\Type;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    
    class ColorSelectorType extends AbstractType
    {
        public function getParent()
        {
            return TextType::class;
        }
    }
    

    Then you'll need to create the template for the field:

    {# templates/form/fields.html.twig #}
    {% block color_selector_widget %}
        {% spaceless %}
           <div class="cp input-group colorpicker-component">
                <input{{ block('widget_container_attributes') }} />
                     <span class="input-group-addon"><i></i></span>
           </div>
        {% endspaceless %}
    {% endblock %}
    

    Register your custom templates:

    # config/packages/twig.yaml
    twig:
        form_themes:
            - 'form/fields.html.twig'
    

    And finally use your new field:

    $formBuilder->add($field['fieldName'], ColorSelectorType::class);
    
    

    Logically, you'll need to customize this to suit your needs, but it should be enough to get you going.