Version

Documentation » Admin

5. Modifying form fields dynamically depending on edited object »

« 3. Row templates

4. Sortable behavior in admin listing

This is a full working example of how to implement a sortable feature in your Sonata admin listing

4.1. Background

A sortable behavior is already available for one-to-many relationships. However there is no packaged solution to have some up and down arrows to sort your records such as showed in the following screen.

Sortable listing

4.2. Pre-requisites

  • you already have SonataAdmin and DoctrineORM up and running
  • you already have an Entity class for which you want to implement a sortable feature. For the purpose of the example we are going to call it Client.
  • you already have an Admin set up, in this example we will call it ClientAdmin
  • you already have gedmo/doctrine-extensions bundle in your project (check stof/doctrine-extensions-bundle or knplabs/doctrine-behaviors for easier integration in your project) with the sortable feature enabled
  • you already have pixassociates/sortable-behavior-bundle bundle in your project

4.3. The recipe

First of are going to add a position field in our Client entity.

/**
 * @Gedmo\SortablePosition
 * @ORM\Column(name="position", type="integer")
 */
private $position;

In ClientAdmin our we are going to add in the configureListFields method a custom action and use the default twig template provided in the PixSortableBehaviorBundle

$listMapper
->add('_action', 'actions', array(
        'actions' => array(
            'move' => array('template' => 'PixSortableBehaviorBundle:Default:_sort.html.twig'),
        )
    ));

In order to add new routes for these actions we are also adding the following method

protected function configureRoutes(RouteCollection $collection)
{
    $collection->add('move', $this->getRouterIdParameter() . '/move/{position}');
}

Now you can update your admin.yml to use the handler provider by the PixSortableBehaviorBundle

services:
    acme.admin.client:
        class: Acme\DemoBundle\Admin\ClientAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, label: "Clients" }
        arguments:
            - ~
            - Acme\DemoBundle\Entity\Client
            - 'PixSortableBehaviorBundle:SortableAdmin' # define the new controller via the third argument
        calls:
            - [ setTranslationDomain, [AcmeDemoBundle]]

Last tricky part, in order to get the last position available in our twig template we inject the service container in our admin class, define a public variable $last_position and retrieve the value from our service in the configureListFields method. We also define the sort by field to be position

class ClientAdmin extends Admin
{

 public $last_position = 0;

 private $container;
 private $positionService;

 public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container)
 {
     $this->container = $container;
 }

 public function setPositionService(\Pix\SortableBehaviorBundle\Services\PositionHandler $positionHandler)
 {
     $this->positionService = $positionHandler;
 }

 protected $datagridValues = array(
     '_page' => 1,
     '_sort_order' => 'ASC',
     '_sort_by' => 'position',
 );

 protected function configureListFields(ListMapper $listMapper)
 {
     $this->last_position = $this->positionService->getLastPosition($this->getRoot()->getClass());
     $listMapper
         ->addIdentifier('name')
         ->add('enabled')
         ->add('_action', 'actions', array(
             'actions' => array(
                 'move' => array('template' => 'AcmeDemoBundle:Admin:_sort.html.twig'),
             )
         ));
 }

And in the admin.yml add the following call

- [ setContainer, [ @service_container ] ]
- [ setPositionService, [@pix_sortable_behavior.position]]

You should now have in your listing a new action column with 4 arrows to sort your records.

Enjoy ;)

4.4. Further work

  • handle ajax request
  • interface for SonataAdminBundle

Found a typo? Something is wrong in this documentation? Just fork and edit it!