I have a List of entries coming from a database. I would like to have a "Delete-Button" at the end of every row, so that the user won't have to first go to the edit/show page to delete the entry.
I tried creating a hidden input field with the csrf token like so:
return $this->createFormBuilder()
->getForm()
;
this will output:
<div id="form">
<input type="hidden" id="form__token" name="form[_token]" value="6c98ebfa9df07.....">
</div>
The rest of the Form i put around in the twig template so that every form has its own action path according the the id of the entry.
unfortunately in the twig template only the first
{{ form_widget(delete_form) }}
will get rendered.
How can i use this hidden field more often? OR is there any way to do this whole thing differently?
Thanks for any help
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$deleteForm = $this->createDeleteForms();
$entities = $em->getRepository('IntranetServicesBundle:Laender')->findAll();
return $this->render('IntranetServicesBundle:Laender:index.html.twig', array(
'entities' => $entities,
'delete_form' => $deleteForm->createView(),
));
}
private function createDeleteForms()
{
return $this->createFormBuilder()
->add('id', 'hidden')
->getForm()
;
}
You may render individual tokens with:
{{ form_widget(form._token) }}
or specifically for your case:
{{ form_widget(delete_form._token) }}
But, I think you are better served making an array of forms and fully rendering each one:
In your controller:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$rep= $em->getRepository('IntranetServicesBundle:Laender')
->createQueryBuilder('l');
var_dump($rep->getQuery()->getDql());
$entities=$rep->getQuery()->getResult();
$delete_forms = array_map(
function($element){
return $this->createDeleteForm($element->getId());}
,$entities->toArray()
);
return $this->render('IntranetServicesBundle:Laender:index.html.twig'
, array(
'entities' => $entities,
'delete_forms' => $delete_forms
));
}
private function createDeleteForms($id)
{
return $this->createFormBuilder(array('id' => $id)))
->add('id', 'hidden')
->getForm()
;
}
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('IntranetServicesBundle:Laender')
->find($id);
// this line might need to be changed to point to the proper repository
if (!$entity) {
throw $this->createNotFoundException('Unable to find Laender entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('laender_index'));
// this line might need to be changed to point to the proper
// post-delete route
}
In your twig do something along the lines of:
{% for form in delete_forms %}{{form_widget(form)}}{% endfor %}
The answer of @Lighthart led me to the correct answer:
In your controller generate an array of form views and had it over to the view:
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('AppBundle:Entity')->findAll();
$delete_forms = array_map(
function ($element) {
return $this->createDeleteForm($element->getId())->createView();
}
, $entities
);
return $this->render('AppBundle:Entity:index.html.twig', array(
'entities' => $entities,
'delete_forms' => $delete_forms
));
}
Now you have to access this in your view. Therefore you can use the form functions and the special loop variables:
{% extends '::base.html.twig' %}
{% block body %}
{% for entity in entities %}
{# Access the delete form for this entity using the loop index ... #}
{% set delete_form = delete_forms[loop.index0] %}
{# ... and display the form using the form tags. #}
{{ form_start(delete_form) }}
<input type="submit" value="Delete" />
{{ form_end(delete_form) }}
{% endfor %}
{% endblock %}
That's it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With