0
votes

I trying to implement a sortable system in my sonata admin list. I'm following this documentation: https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_sortable_listing.html But it'z not working.

Here is my config: My entity field

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

My service.yml:

services:
    gedmo.listener.sortable:
        class: Gedmo\Sortable\SortableListener
        tags:
            - { name: doctrine.event_subscriber, connection: default }
        calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]

  app.admin.client:
          class: AppBundle\Admin\ClientAdmin
          tags:
              - { name: sonata.admin, manager_type: orm, label: "Clients" }
          arguments:
              - ~
              - AppBundle\Entity\Client
              - 'PixSortableBehaviorBundle:SortableAdmin' 

stof_doctrine_extensions:
    orm:
        default:
        sortable: true

My QuestionAdmin for Sonata EDIT:

class Question extends Admin
{
    public $last_position = 0;

    private $positionService;

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

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

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

    /**
     * @param DatagridMapper $datagridMapper
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('headline')
            ->add('body')
            ->add('category')
            ->add('slug');
    }
    /**
     * @param ListMapper $listMapper
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->add('headline', null, array(
                'identifier' => true,
                'label' => 'Titres',
            ))
            ->add('category', null, array(
                'label' => 'Catégories',
            ))
            ->add('position')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'edit' => array(),
                    'delete' => array(),
                    'move' => array('template' => 'PixSortableBehaviorBundle:Default:_sort.html.twig'),
                ),
                'label' => 'Actions',
            ));
    }
    /**
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('headline', null, array(
                'attr' => array('class' => 'span12'),
                'label' => 'Questions',
            ))
            ->add('body', null, array(
                'required' => false,
                'label' => 'Réponses',
                'attr' => array('class' => 'span12'),
            ))
            ->add('category', null, array(
                'expanded' => true,
                'required' => true,
                'label' => 'Catégories',
                'attr' => array('class' => 'radio-list vertical'),
            ))
            ->add('position', 'hidden', array(
                'required' => true,
                'attr' => array('class' => 'span12'),
                'label' => 'Rang',
                'data' => 1,
            ))
            ->add('slug', null, array(
                'required' => false,
                'attr' => array('class' => 'span12'),
            ))
            ->end();
    }
}

I have this error: Call to undefined method AppBundle\Entity\Faq\Question::getPosition()

1
Have you tried naming your field position instead of rank ?paulgv
I just did it. It works now. I see the buttons but when I click in the arrow button I have this error. Controller "Sonata\AdminBundle\Controller\CRUDController::moveAction" for URI "/admin/fm/app/faq-question/4/move/up" is not callableKevin
According to the doc, you need to add the following methods and properties to the admin class : $last_position, $positionService, datagridValues, setPositionService() and configureRoutes().paulgv
I did it. I have edited mi post to show you the QuestionAdmin file ;)Kevin
I found it. It was a problem with my yaml file. I have 2 of themKevin

1 Answers

2
votes

1. You have to name your DB field position

2. In your entity use Gedmo\Mapping\Annotation as Gedmo;

3.

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

4. create setter and getter for it

5. Install and configure with composer StofDoctrineExtensionsBundle and PixSOrtableBehaviorBundle

6. and use them in AppKernel to be available

$bundles = array(
    ...
    new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
    new Pix\SortableBehaviorBundle\PixSortableBehaviorBundle(),
);

7. In services.yaml enable the gedmo listener

gedmo.listener.sortable:
    class: Gedmo\Sortable\SortableListener
    tags:
      - { name: doctrine.event_subscriber, connection: default }
    calls:
      - [ setAnnotationReader, [ "@annotation_reader" ] ]

(stick to the right indentation else your listener will not work)

8. In your admin service connect the new sortable behavior and activate calls

admin.something:
    class: AppBundle\Admin\SomethingAdmin
    tags:
      - { name: sonata.admin, manager_type: orm, label: Articles }
    arguments:
      - ~
      - AppBundle\Entity\Something
      - 'PixSortableBehaviorBundle:SortableAdmin'
    calls:
      - [setPositionService, ["@pix_sortable_behavior.position"]]

(follow the proper indentation else it will not work and will throw some strange error)

9. in config.yml configure your stof-doctrine-extenstions bundle:

    stof_doctrine_extensions:
        orm:
            default:
                sortable: true

(sortable is indented under default in tutorial it is shown wrong)

Enjoy :)