Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PHP

Symfony Form Rendering Woes

0.00/5 (No votes)
14 Dec 2016CPOL3 min read 3.8K  
Symfony Form Rendering Woes

Introduction

Recently for Taft College, I’ve been working on a TRIO program application which is built with Symfony PHP framework. I have various forms that need to be filled out and submitted by students, and this post is about how I had rending issues of one of the forms and how I solve the problem.

The Form

In one of the forms I created, I used a Form class to create the form. On the form, there is a checkbox that when selected needs to show a date selection. There are two checkboxes by the High School area, namely “Diploma” and “G.E.D.” test. Below is a sample of the code I started with:

PHP
->add('hs_diploma', ChoiceType::class, array(
   'mapped' => false,
   'expanded' => true,
   'multiple' => true,
   'choices' => array(
      'Diploma' => 'diploma',
   ),
))
->add('hs_dip_date', DateType::class, array(
   'mapped' => false,
   'format' => 'dd MMM y',
   'label' => 'date:',
   'years' => range(2017,1960,1),
))
->add('ged', ChoiceType::class, array(
   'mapped' => false,
   'expanded' => true,
   'multiple' => true,
   'choices' => array(
      'G.E.D.' => 'ged_checked',
   ),
))
->add('ged_date', DateType::class, array(
   'mapped' => false,
   'format' => 'dd MMM y',
   'label' => 'date:',
   'years' => range(2017,1960,1),
))

And here is what the rendering looks like:

1st_render

The elements are in an HTML table and notice the way that the date label appears on one row and on the next row is the date picker, followed by the G.E.D. checkbox (and label and date picker). So the problem is that I need both of the checkboxes, labels and date pickers to all appear in one row.

Fixing in Twig?

Then my next thought would be could this be fixed in the Twig template? Twig is a great templating engine which allows you to customize the form rendering using certain markup. I figured I could customize it by specifying in this format:

Diploma checkbox widget:Diploma date label:Diploma date picker widget:GED checkbox widget:
GED date label:GED date picker widget

All the above in one HTML table data () element, within a table row (). This would look like the following code in Twig:

XML
<tr><td>{{ form_widget(form.hs_diploma) }}{{ form_label(form.hs_dip_date) }}
 {{ form_widget(form.hs_dip_date) }}{{ form_widget(form.ged) }}{{ form_label(form.ged_date) }}
 {{ form_widget(form.ged_date) }}</td></tr>

However this doesn’t even change the way it renders as in the image above. I used FireFox browser tools and right-clicked on the table element and selected Inspect Element, which shows that within the element, each checkbox and date picker is with a tag and the labels are outside of the div tags. This is why they don’t render properly.

So the end answer to my question is: It would be possible to fix this in Twig, but it would be a lot of code, and I was looking for an easier way.

Setting Attributes of Symfony Field Types

Symfony has a number of different Field Types, and in my form I use ChoiceType and DateType (as per the above code). I also use other types (of course), but in this blog I only will reference changes to these types.

In FireFox, I experimented with the browser tools by using the Inspector tab and adjusting the style attribute of the tags, and then I found that if I used style=”float:left”, this fixed the problem of rendering on different rows in the table.

This is the code I used to properly render the checkboxes:

PHP
->add('hs_diploma', ChoiceType::class, array(
   'mapped' => false,
   'expanded' => true,
   'multiple' => true,
   'choices' => array(
      'Diploma' => 'diploma',
   ),
   'attr' => array(
      'style' => 'float:left',
   ),
))

Notice that I add an attribute of style and set to “float:left”. Then for a date picker, I use the following code:

PHP
->add('hs_dip_date', DateType::class, array(
   'mapped' => false,
   'format' => 'dd MMM y',
   'label' => 'date:',
   'label_attr' => array(
      'style' => 'float:left;margin-left:8px',
   ),
   'years' => range(2017,1960,1),
   'attr' => array(
      'style' => 'float:left',
   ),
))

Notice there are attributes for both the label and the date picker. Both attributes are needed. Notice also for the label_attr, I added a “margin-left:8px”; this was to add a space between (for example) Diploma and the label date.

Below is a render of what the changes look like after adding the styling changes:

2nd_render

Notice everything all appears on one row exactly as I need it.

Since I set the attributes in the form class, it’s very easy to support, since I merely only need to change the class file should I need to have to make any changes. I should mention that this would really be a lot of work if I had to make the changes in Twig; so I highly recommend you use the field type attributes when it is possible.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)