Click here to Skip to main content
15,894,291 members
Articles / All Topics

Display Checkbox Group Properly in Twig

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
14 Apr 2017CPOL2 min read 5.6K  
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:

  1. Rending in Twig is not easy
  2. 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:

TwigRender

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>&emsp;{{ 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>&emsp;{{ form_widget(form.employ[0],{'attr':{'onchange':'changeJobHours()'}}) }}
   {{ form_label(form.employ[0]) }}&emsp;
   {{ 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>&emsp;{{ form_widget(form.employ[0],{'attr':{'onchange':'changeJobHours()'}}) }}
      {{ form_label(form.employ[0]) }}&emsp;
      {{ form_label(form.job_hours) }}{{ form_widget(form.job_hours) }}</td></tr>
   {% for i in 1..8 %}
      <tr><td>&emsp;{{ form_widget(form.employ[i]) }}{{ form_label(form.employ[i]) }}</td></tr>
   {% endfor %}
   <tr><td>&emsp;{{ form_widget(form.employ[9],{'attr':{'onchange':'changeEmploy()'}}) }}
      {{ form_label(form.employ[9]) }}&emsp;
      {{ 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.

Employment


License

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


Written By
Software Developer Taft College
United States United States
I’m a software developer. Currently I’m working at Taft College as a Programmer.

Comments and Discussions

 
-- There are no messages in this forum --