Search code examples
symfonysonata-adminsymfony-sonata

How to create a custom form using CRUD controller in sonata admin bundle?


I'm a beginner in sonata admin, I need to know how to create custom form using route and controller and index.html.twig.

   app.admin.category:
        class: AppBundle\Admin\CategoryAdmin
        arguments: [~, AppBundle\Entity\Category, SonataAdminBundle:CRUD]
        tags:
            - { name: sonata.admin, manager_type: orm, group: adminn, label: Category }
        public: true

Solution

  • You need to create CRUD controller. For each admin service you have default one and you can overwrite it. In your case, service is app.admin.category

    How to create CRUD controller? I am going to explain the most simple way.

    1. Create class in your AppBundle/Controller/Admin/folder and call it CategoryAdminController. Here is code of your class:

      <?php
      
      namespace AppBundle\Controller\Admin;
      
      use Sonata\AdminBundle\Controller\CRUDController;
      
      /**
       * Class CategoryAdminController
       * @package AppBundle\Controller\Admin\
       */
      class CategoryAdminController extends CRUDController
      {
      }
      

      As you can see this class extends default SonataAdminCRUDController.

    2. Then point to your sonata service that it has to use this class as it's CRUDContoller. In your service.yml change the stndard CRUD controller:

      app.admin.category: class: AppBundle\Admin\CategoryAdmin arguments: [~, AppBundle\Entity\Category, AppBundle:Admin\CategoryAdmin] tags: - { name: sonata.admin, manager_type: orm, group: adminn, label: Category } public: true

    3. Now you are ready to make your new action in your new Controller. Let's call it changeAction.

       /**
        * @param int $id
        *
        * @return Response
        */
       public function changeAction($id = null)
       {
           try {
              if ($id !== null) {
                  $category = $this->admin->getObject($id);
              }
          } catch (NotFoundHttpException $e) {
              error_log($e->getMessage());
          }
      
          // .. Here is a code of creating your custom form with variable $form
      
      
          return $this->render('@App/Admin/CRUD/index.html.twig', [
              'custom_form' => $form->createView(),
          ]);
       }
      
    4. Make the route to your new action! In your CategoryAdmin service overwrite configureRoutes() method

      /**
       * @param RouteCollection $collection
       */
      protected function configureRoutes(RouteCollection $collection)
      {
          $collection->add('change', $this->getRouterIdParameter().'/change');
      }
      
    5. Finally - we can make the button to our route:

      /**
       * @param ListMapper $listMapper
       */
      protected function configureListFields(ListMapper $listMapper)
      {
          $listMapper
              //.. Your fields...
              ->add('_action', 'actions', [
                  'label' => ' ',
                  'actions' => [
                      //'show' => array(),    // I removed show action button, but you can uncomment
                      //'edit' => array(),    // I removed edit action button, but you can uncomment
                      //'delete' => array(),  // I removed delete action button, but you can uncomment
                  'change' => [
                          'template' => 'AppBundle::Admin\CRUD\Buttons\change_category_button.html.twig',
                      ]
                  ]
              ])
          ;
      }
      

    And of course don't forget to create a twig template for your new button and place it in right place AppBundle/Resources/views/Admin/CRUD/Buttons/:

    //'AppBundle::Admin\CRUD\Buttons\change_category_button.html.twig':
    
    {% if admin.isGranted('EDIT', object) and admin.hasRoute('change') %}
        <a href="{{ admin.generateObjectUrl('change', object) }}" class="btn btn-sm btn-primary edit_link" title="Your title here"  style="display: inline-block">
            <i class="fa fa-toggle-on"> </i>
            Change Button
        </a>
    {% endif %}