Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 3 using the delete action in Twig

Tags:

php

symfony

So I've copied the basic delete action from the CRUD generator:

   /**
    * @Route("category/delete/{id}", name="category_delete")
    * @Method("DELETE")
    */
    public function deleteAction(Request $request, $id)
    {
        $repository = $this->getDoctrine()->getRepository('AppBundle:Category');
        $category = $repository->find($id);

        $form = $this->createDeleteForm($category);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($category);
            $em->flush();
        }

        return $this->redirectToRoute('category_index');
    }

    /**
     *
     * @param Category $category
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(Category $category)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('category_delete', array('id' => $category->getId())))
            ->setMethod('DELETE')
            ->getForm()
            ;
    } 

However, I'm not sure how to actually use the action itself. I want to do deletes in two places, and I'm not sure the correct way to do either:

  1. Deletes in the edit action - How do I add a delete button to the form builder? I do I have to do it in the twig template itself?
  2. Deletes in the index - I know how to call actions (e.g. <a href="{{ path('category_edit', {'id': cat.id}) }}" class="btn btn-default">Edit</a>), but this doesn't work with the delete action.

I've tried looking at the Symfony demo application, but I still don't fully grasp how the delete action is meant to work - and I can't find anything in the docs.

Can someone provide a brief of explanation of how the delete action works in regard to 1 and 2?

like image 425
Darkstarone Avatar asked Nov 22 '16 03:11

Darkstarone


1 Answers

The delete script in Symfony CRUD works with a form submission. So, you have to render a form to show the delete button.

You may hesitate to render a form for each of the items in a list. Its also, not convenient to embed a from inside edit form.

With a bit of help from Bootstrap modal (confirm box for delete) and ajax submission, I came across this solution :

  1. Make your deleteAction to support GET so that it can render the form when necessary.
  2. Wherever you need delete link, give it as a link to the modal which in turn will load deleteAction controller to render a form in side the modal body. You can have your confirmation message in the modal as well.
  3. When modal form submitted, handle your deleteAction script accordingly, and redirect.

EDIT : Added script for Controller and Template

/**
 * @Route("category/delete/{id}", name="category_delete")
 * @Method({"GET", "DELETE"})
 */
public function deleteAction(Request $request, $id)
{
    /*
     * Check Permission.
     */
    $response = array(
        'success' => true,
        'message' => '',
        'html' => '',
    );

    $repository = $this->getDoctrine()->getRepository('AppBundle:Category');
    $category = $repository->find($id);

    $form = $this->createDeleteForm($category);
    if ($request->getMethod() == 'DELETE') {
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($category);
            $em->flush();

            // Get response ready as per your need.
            $response['success'] = true;
            $response['message'] = 'Deleted Successfully!';
        } else {
            $response['success'] = false;
            $response['message'] = 'Sorry category could not be deleted!';
        }
        return new JsonResponse($response);

        // In case you want to redirect.
        // $this->addFlash('notice', 'Deleted Successfully!');
        // return $this->redirectToRoute('category_index');
    }
    $render = $this->render(':category:delete_confirm.html.twig', array(
        'delete_form' => $form->createView(),
        'category' => $category,
    ));

    $response['html'] = $render->getContent();

    return new JsonResponse($response);
}

Twig HTML code to return Modal (I'm using UIKIT modal)

{{ form_start(delete_form) }}
<div class="uk-modal-header">
    <h3 class="uk-modal-title">Delete this Category?</h3>
</div>
<p>
    Are you sure you want to delete  '{{ category.name }}'?<br/>
    This cannot be undone.
</p>
<div class="uk-modal-footer uk-text-right">
    <div>
        <button type="submit" class="md-btn md-btn-danger" title="Click to proceed!">
            <i class="uk-icon-trash"></i> Delete
        </button>
        <button type="button" class="md-btn md-btn-warning uk-modal-close">Cancel</button>
    </div>
</div>
{{ form_end(delete_form) }}

Hope this helps!

like image 109
Jeet Avatar answered Oct 19 '22 15:10

Jeet