WARNING: You are browsing the documentation for version 2.x which is not maintained anymore. If some of your projects are still using this version, consider upgrading.

4. Sortable behavior in admin listing

2.x version
Maintained Unmaintained
2.x

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.

1
2
3
4
5
/**
 * @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

1
2
3
4
5
6
$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

1
2
3
4
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

1
2
- [ 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

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.