67

How can I set the HTML class attribute to a form <input> using the FormBuilder in Symfony2 ?

Something like this:

->add('birthdate', 'date',array(
      'input' => 'datetime',
      'widget' => 'single_text',
      'attr' => array(
          'class' => 'calendar'
      )
 ))

 {{ form_widget(form.birthdate) }}

I want this inputfield with the attribute class set to calendar

Nickolaus
  • 4,785
  • 4
  • 38
  • 60
Jean-Philippe Bond
  • 10,089
  • 3
  • 34
  • 60

8 Answers8

121

You can do this from the twig template:

{{ form_widget(form.birthdate, { 'attr': {'class': 'calendar'} }) }}

From http://symfony.com/doc/current/book/forms.html#rendering-each-field-by-hand

j0k
  • 22,600
  • 28
  • 79
  • 90
Problematic
  • 17,567
  • 10
  • 73
  • 85
  • 50
    This really isn't an answer for the question-- the whole point of the FormBuilder is to avoid hand-coding the Twig template. – Acyra Mar 13 '12 at 12:53
  • 26
    @Acyra It depends... throwing loads of view-related stuff into the form builder isn't the best way either. – Eugene Oct 31 '13 at 15:15
  • 6
    I agree, form customization should live in the view, and not in the controller. The controllers should be as light as possible, While it is pretty awesome that Symfony2 create the forms for you, and that's a huge time saver, when you're working with "fancy" UIs, sometimes the form builder gets in the way. – ILikeTacos Jan 16 '14 at 21:18
  • 1
    @numerah: old comment, but for others that may see your comment: yes we do! You can set all kind of attributes using `'attr'`. – Quentin S. Jun 02 '15 at 09:02
  • 1
    @Acyra What about form theme templates? You'll have to do this once if you want to keep a style going on for all your forms.. – axelvnk Mar 17 '16 at 14:44
  • @Acyra I initially thought the same, but if you think about it, adding a class to an input almost always belongs in the view. It's either JS or CSS related, which is usually specific to that view. The idea of FormBuilder is that it allows forms to be reusable. Adding a class like `input-lg` might be fine for one use but not another. – rybo111 Jul 24 '17 at 19:57
116

You can do it with FormBuilder. Add this to the array in your FormBuilder:

'attr'=> array('class'=>'span2')
Acyra
  • 15,864
  • 15
  • 46
  • 53
30

The answer by Acyra lead the right way if you want to set attributes inside the controller, but has many inaccuracies.

Yes, you can do it directly with the FormBuilder by using the attr attribute (introduced here for the 2.1 version and here for the 2.0) to the array of options as follows:

->add('birthdate', 'date',array(
      'input' => 'datetime',
      'widget' => 'single_text',
      'attr' => array('class'=>'calendar')
 ))

It is not true that the "functionality is broken". It works very well!

It is not true that Symfony2 applies the HTML class attribute to both the label and the input (at least from the 2.1 version).

Moreover, since the attr attribute is an array itself, you can pass any HTML attribute you want to render for the field. It is very helpful if you wanna pass the HTML5 data- attributes.

JeanValjean
  • 17,172
  • 23
  • 113
  • 157
10

You can add it in the options of your form class:

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\MyEntity',
        'attr' => array(
            'class' => 'form-horizontal'
        )
    ));
}
segli
  • 230
  • 2
  • 6
  • 3
    This should be the correct answer, best to do this in the form class and not in twig. – Kim Dec 30 '18 at 11:53
4
{{ form_widget(form.content, { 'attr': {'class': 'tinyMCE', 'data-theme': 'advanced'} })  }}
Kiran
  • 1,176
  • 2
  • 14
  • 27
2

Like this:

{{ form_widget(form.description, { 'attr': {'class': 'form-control', 'rows': '5', 'style': 'resize:none;'} }) }}
Alexandre Velo
  • 115
  • 1
  • 10
1

You can to this in Twig or the FormClass as shown in the examples above. But you might want to decide in the controller which class your form should get. Just keep in mind to not have much logic in the controller in general!

    $form = $this->createForm(ContactForm::class, null, [
        'attr' => [
            'class' => 'my_contact_form'
        ]
    ]);
Kim
  • 1,757
  • 1
  • 17
  • 32
0

Renders the HTML widget of a given field. If you apply this to an entire form or collection of fields, each underlying form row will be rendered.

{# render a field row, but display a label with text "foo" #} {{ form_row(form.name, {'label': 'foo'}) }}

The second argument to form_row() is an array of variables. The templates provided in Symfony only allow to override the label as shown in the example above.

See "More about Form Variables" to learn about the variables argument.