Forms With Checkboxes For Each Entity in Symfony: Difference between revisions
Jump to navigation
Jump to search
(Created page with "== Goal == '''Goal:''' To display a list of records, select the records with checkboxes, then apply a batch update to the records when the form is submitted. == Controller =...") |
No edit summary |
||
| Line 1: | Line 1: | ||
[[Category:Symfony]] [[Category:PHP]] [[Category:Web Development]] | |||
== Goal == | == Goal == | ||
Revision as of 23:51, 5 February 2015
Goal
Goal: To display a list of records, select the records with checkboxes, then apply a batch update to the records when the form is submitted.
Controller
// ...
use Symfony\Component\HttpFoundation\Request;
//...
/**
* @Route("/pending", name="_pending")
*/
public function pendingAction(Request $request)
{
// retrieve pending tutorials from database
$groups = $this->getDoctrine()
->getRepository('AppBundle:TutorialGroupTemp')
->findAll();
$tutorial_data = array();
foreach($groups as $group) {
$group->getTutorials();
foreach ($group->tutorials as $tutorial) {
$tutorial_data[$tutorial->getId()] = $tutorial->getName();
}
}
// define form inputs
$fb = $this->createFormBuilder();
foreach($tutorial_data as $key => $label) {
$fb->add('tutorialId', 'choice', array(
'label' => 'Tutorials',
'multiple' => true,
'expanded' => true,
'choices' => $tutorial_data,
'required' => false
));
}
$fb->add('update', 'submit', array('label' => 'save selected'));
$form = $fb->getForm();
// process form submission
$form->handleRequest($request);
if ($form->isValid()) {
// collect form data
$data = $form->getData();
/** @todo process form data */
}
// display listings view
return $this->render("tutorials/pending.html.twig", array(
'groups' => $groups,
'form' => $form->createView()
));
}
// ...
- Store all the record values in an array to be assigned to the checkbox inputs elements.
- Use a form builder object to define the form.
- Call the
add()method for each checkbox to be added the form.- Checkboxes representing an array of choices are created using
choiceas the form element - The options 'multiple=true' and 'expanded=true' are what make it render as checkboxes as opposed to dropdowns.
- The values of the checkboxes are passed to the form builder with the
choicesoption.
- Checkboxes representing an array of choices are created using
- In this case submit buttons are repeated throughout the form for the convenience of not having to scroll through all the listings to find them.
- The
form_widget()twig routine will only render an input once because generally they are all assignedidattributes. - The submit button must still be added to the form builder in order to validate the form data.
- The
- Call the
- The form data is collected and processed with the
handleRequest()andgetData()calls. (getData()wouldn't be used if the form data was being assigned to an entity class.) - The form is validated with the
isValid()call. If form data is not being submitted, this block is quietly skipped over. - It's necessary to pass the form view to the template when rendering the view.
N.B. There are probably other things that I could do (form class? services?) that would be better practices. As documented here it works. Update with any new practices.
Template
{{ form_start(form) }}
{{ form_errors(form) }}
<button type="submit" class="btn btn-default" name="form[update]">save selected</button>
{% for tutorial in tutorials %}
{{ form_widget(form.tutorialId[loop.index0] ) }}
{% endfor %}
<button type="submit" class="btn btn-default" name="form[update]">save selected</button>
{% do form.update.setRendered %}{# compensates for manually inserting this multiple times in the form #}
{{ form_end(form) }}
- The checkboxes are rendered with
form_widget().tutorialIdcorresponds to the index of the checkbox collection added to the form builder object.- The individual checkboxes in the collection are accessed through a numeric index. Twig provides the
loop.index0helper.
- The html for the submit buttons are is manually inserted into the template. The Symfony helper functions will only render a form element once to avoid duplicate
idvalues. form_end()will render any fields that have not explicitly rendered in the form already.form.update.setRenderedprevents this.
Processing the form data
After the call to $form->getData(), the submitted form data will be accessible through an array:
array (size=1)
'tutorialID' =>
array (size=3)
0 => int 3
1 => int 6
2 => int 9
Examples
- Pending Tutorials, Tutorial Database