Display Checkbox Group Properly in Twig





0/5 (0 vote)
Display Checkbox Group Properly in Twig
Introduction
In a form I’ve recently worked on using Symfony, I had to show a group of selectable checkboxes. In this case, the user can select any number of checkboxes also in one group, two of the checkboxes I needed to use JavaScript to detect when the box was selected. I wrote about that in my JavaScript Code Refactoring article.
There are two types of problems when using a ChoiceType built-in Field Type set to element type of checkboxes in Symfony:
- Rending in Twig is not easy
- Setting attributes is not easy, and may not work as you expect
The above two reasons are why I decided to write this article.
Example Code
Below is an example checkbox group that I created in a form class for some employment questions that are asked in a form:
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ... // Employment ->add('employ', ChoiceType::class, array( 'mapped' => false, 'required' => false, 'expanded' => true, 'multiple' => true, 'label' => 'Employment', 'choices' => array( 'I have a job. # of hours/week:' => 'have_job', 'I am work study eligible' => 'work_study', 'I need assistance in finding a job' => 'find_work', 'I need to learn interviewing skills' => 'interview', 'I have no employment needs at this time' => 'no_needs', 'I volunteer for a non-profit organization' => 'non_profit', 'I need assistance with my resume' => 'resume', 'I need assistance finding an internship' => 'intern', 'I am undecided about my career or major' => 'major', 'Other:' => 'other', ), )) ... }
Then when I tried to render in a single HTML table row in Twig, using code like this:
<tr><td>{{ form_widget(form.employ) }}</td></tr>
Then this appears like this rendering in a web page:
Notice the problem in that each checkbox
appears inline directly after each other. I tried to use the Twig nl2br filter together with “\n
” in my choice values, but that didn’t work since I really need another table row to show each of the checkboxes and labels.
Adding Checkboxes to TR
Since a ChoiceType in a Symfony form is an array of checkboxes, then we can use a Twig for loop to properly show the widget and label in a HTML table row. The Twig code needed is as follows:
{% for i in 1..8 %} <tr><td> {{ form_widget(form.employ[i]) }}{{ form_label(form.employ[i]) }}</td></tr> {% endfor %}
The unfortunate part of the above code is, in order to add an attribute like a JavaScript onchange, this has do be done in Twig on the particular element like so:
<tr><td> {{ form_widget(form.employ[0],{'attr':{'onchange':'changeJobHours()'}}) }} {{ form_label(form.employ[0]) }}  {{ form_label(form.job_hours) }}{{ form_widget(form.job_hours) }}</td></tr>
The above adds an onchange
attribute for the first checkbox. I also have a job hours and label, but those are hidden and shown when an onchange
event is triggered and box is selected.
Resultant Code
The overall resultant code looks like the following:
<table id='6th' style='border: 1px solid; margin-left: auto; margin-right: auto; width: 50%; display: none;' background="{{ asset('images/indneeds_assess/employment2.png') }}"> <tr><td colspan="2"><b>{{ form_label(form.employ) }}</b></td></tr> <tr><td>{{ form_widget(form.employ) }}</td></tr> <tr><td> {{ form_widget(form.employ[0],{'attr':{'onchange':'changeJobHours()'}}) }} {{ form_label(form.employ[0]) }}  {{ form_label(form.job_hours) }}{{ form_widget(form.job_hours) }}</td></tr> {% for i in 1..8 %} <tr><td> {{ form_widget(form.employ[i]) }}{{ form_label(form.employ[i]) }}</td></tr> {% endfor %} <tr><td> {{ form_widget(form.employ[9],{'attr':{'onchange':'changeEmploy()'}}) }} {{ form_label(form.employ[9]) }}  {{ form_label(form.employ_other) }}{{ form_widget(form.employ_other) }}</td></tr> </table>
The above code puts each checkbox in on HTML tr
elements. The resultant web page looks like the following and appears much better than the original.