Symfony2 Form Type - how to set form CSS class as attribute?


Tags: css,forms,symfony2

Problem :

When I set CSS class in form controller and pass it as $options array element it works.

private function createEditForm(OrderCard $entity)
{
    $form = $this->createForm(new OrderCardType($this->get('security.context')
                                       ->isGranted('ROLE_SUPER_ADMIN')), $entity, array(
        'action' => $this->generateUrl('ordercard_update', array('id' => $entity->getId())),
        'attr'=>array(
                 'class'=>'form-horizontal'
                )
    ));

    return $form;
}

But when I want to have same effect using formType it is not added to form:

public function buildForm(FormBuilderInterface $builder, array $options)
{
      $builder
          // not works
          ->setAttribute('attr', array('class' => 'form-horizontal'))
          // not works either
          ->setAttribute('class', 'form-horizontal')
//...

What I do wrong? How to make it work?



Solution :

This can be done from several places:

  1. define in setDefaultOptions method of Form Type class
  2. As a parameter of $this->createForm function called from controller.
  3. define in buildView method of Form Type class
  4. In template while rendering form

You just to know which option has precedence over another, and how they work.

Option 1: Here is the place to set default options. If no where else set the value this default value will be used.

Example Implementation (As Pivot provided):

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'attr' => array(
            'class' => 'form-horizontal-from-default'
        ),
    ));
}

Option 2: You already know this, you can provide the attr value while calling $this->createForm from controller(which is actually a shortcut for $this->container->get('form.factory')->create function). When you provide this value, the value set from previous option will overridden.

Example Implementation (As You provided):

$this->createForm($formTypeObject, $entity, array(
    'action' => 'URL,
    'attr'=>array('class'=>'form-horizontal')
));

Option 3: You can set or override the value set by previous two option here. setting the value in buildView method. Declare following method in your Form Type Class:

/**
 * {@inheritdoc}
 */
public function buildView(FormView $view, FormInterface $form, array $options)
{              
    $options['attr']['class'] = 'form-horizontal-from-build-view';
    //If you like to keep value set from previous methods you can define like
    //$options['attr']['class'] = isset($options['attr']['class'])? $options['attr']['class'] :'';
    //$options['attr']['class'] .= ' form-horizontal-from-build-view';

    $view->vars = array_replace($view->vars, array(
        'attr'  => $options['attr'],
    ));
}

Option 4:: Now the final and ultimate way to set attributes. This has the height priority over other options, as it is done in the final stage while rendering the form.

You can define as follow in your template:

{{ form_start(form, {'method': 'POST', 'attr': {'class': 'form-horizontal-ultimate' }}) }}

    CSS Howto..

    How do I change a specific css element with javascript?

    How to find number of style classes defined in a CSS file

    How to set the path to compile my CSS with Compass SASS

    How can I write a complex fraction using HTML/CSS/jQuery?

    How to get right sidebar up on main content on resize of flexible with page?

    How to make HTML pages print at a consistent size from Chrome?

    How to remove scroll bar using overflow CSS HTML (Possible Positioning Conflict)

    CSS 100vw causing scrollbar to show, cant use 100% unfortunately

    How can I exclude some images from being preloaded

    How to change background image based on screen size, possibly with Bootstrap

    How to align div objects in rows

    CSS - How to make position:absolute work not on all 100% screens area

    CSS + Bootstrap: How to dynamically stretch subdiv width to fit container (with image)?

    How to keep transparent radial background smooth in browsers other than Chrome?

    How to specify another font size for IE7 and IE8

    How to get the max width of my css element using javascript

    Hide/Show menu with increase/decrease of width

    How to customize the size of JCoverFlip?

    Once nav bar reached top of window, how to keep it there?

    How do I make this responsive layout with CSS?

    CSS : How to add an absolute div to a scrollable background? [closed]

    How can I refactor some repetitive HTML and CSS?

    How to remove the blue border around ImageMap control in the Internet Explorer?

    How can I get a label to right align in a table “cell” (td)?

    How do I provide navigation options on the sides of a centered logo?

    How to get ratio of scale image, when it's autoscaled by background-cover?

    Toggle radio button on javascript hide/show of div

    How to re-animate CSS3 animations on class change

    How to start an css effect when website open

    How to programmatically download all contents of webpage, not only the source code in Java