Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sortable Behavior Bundle Laravel Package

alex-dwt/sortable-behavior-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require alex-dwt/sortable-behavior-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        AlexDwt\PixSortableBehaviorBundle\AlexDwtPixSortableBehaviorBundle::class => ['all' => true],
    ];
    
  2. Configure Basic Sorting Add the bundle configuration in config/packages/pix_sortable_behavior.yaml:

    pix_sortable_behavior:
        db_driver: orm  # or 'mongodb'
        position_field:
            default: sort
            entities:
                App\Entity\YourEntity: position
    
  3. Integrate with Sonata Admin Extend your Admin class to include sortable actions:

    // src/Admin/YourAdmin.php
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->add('_action', 'actions', [
                'actions' => [
                    'move' => [
                        'template' => 'PixSortableBehaviorBundle:Default:_sort.html.twig', // Default up/down buttons
                    ],
                ],
            ]);
    }
    
  4. Add Position Field to Entity Ensure your entity has a field to store the sort order (e.g., position or sort):

    // src/Entity/YourEntity.php
    /**
     * @ORM\Column(type="integer")
     */
    private $position;
    
  5. Clear Cache

    php bin/console cache:clear
    

First Use Case

Enable sorting for a list of blog posts in Sonata Admin:

  • Configure position_field for App\Entity\BlogPost (e.g., order).
  • Add the _action field to your configureListFields().
  • Refresh the admin page to see up/down arrows for reordering.

Implementation Patterns

Workflow: Enabling Sorting for Multiple Entities

  1. Centralized Configuration Define position_field and sortable_groups in config/packages/pix_sortable_behavior.yaml for all entities at once:

    pix_sortable_behavior:
        position_field:
            entities:
                App\Entity\Post: order
                App\Entity\Category: priority
    
  2. Dynamic Sorting in Admin Classes Reuse the same _action field across multiple admins:

    // src/Admin/PostAdmin.php
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper->add('_action', 'actions', ['actions' => ['move' => []]]);
    }
    
  3. Group-Based Sorting Use sortable_groups to restrict sorting to specific groups (e.g., by category):

    pix_sortable_behavior:
        sortable_groups:
            entities:
                App\Entity\Post: [category_id]  # Sort only within the same category
    

Integration Tips

  • Custom Templates: Override _sort.html.twig or _sort_drag_drop.html.twig in your bundle to customize UI.
  • Event Listeners: Hook into pixSortableBehaviorBundle.success (jQuery event) to trigger post-sort actions (e.g., notifications or API calls).
  • MongoDB Support: Configure db_driver: mongodb and ensure your Doctrine MongoDB entities use Sortable behavior (e.g., via Gedmo extensions).
  • Batch Updates: For large datasets, batch updates to the position field may improve performance:
    // src/EventListener/SortListener.php
    public function onSort(PostSortEvent $event)
    {
        $em = $event->getEntityManager();
        $em->flush(); // Flush after every few updates
    }
    

Drag-and-Drop Implementation

  1. Update Admin Class:

    $listMapper->add('_action', null, [
        'actions' => [
            'move' => [
                'template' => 'PixSortableBehaviorBundle:Default:_sort_drag_drop.html.twig',
                'enable_top_bottom_buttons' => false, // Disable default buttons
            ],
        ],
    ]);
    
  2. Add JavaScript: Include in config/packages/twig.yaml or your theme:

    twig:
        paths: ['%kernel.project_dir%/templates']
    

    Then reference the JS in your base template:

    <script src="{{ asset('bundles/pixsortablebehavior/js/jquery-ui.min.js') }}"></script>
    <script src="{{ asset('bundles/pixsortablebehavior/js/init.js') }}"></script>
    
  3. Custom Styling: Use the is-dragging body class to adjust UI during drag operations:

    body.is-dragging #sidebar { opacity: 0.5; }
    

Gotchas and Tips

Pitfalls

  1. Missing Position Field

    • Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sort' in 'order clause'.
    • Fix: Ensure your entity has a field matching the configured position_field (e.g., sort or order).
  2. Cache Issues

    • Error: Sorting changes not reflected until cache is cleared.
    • Fix: Always run php bin/console cache:clear after configuration changes.
  3. JavaScript Conflicts

    • Error: Drag-and-drop fails with Uncaught TypeError: $(...).sortable is not a function.
    • Fix: Ensure jQuery UI is loaded before init.js and jQuery is available globally.
  4. Doctrine Event Conflicts

    • Error: Sorting triggers other lifecycle callbacks (e.g., prePersist) unexpectedly.
    • Fix: Use @ORM\HasLifecycleCallbacks selectively or disable unwanted events.
  5. MongoDB Specifics

    • Error: Sorting fails with Call to a member function getId() on null.
    • Fix: Ensure your MongoDB entities implement getId() and use Gedmo’s Sortable behavior.

Debugging Tips

  1. Check AJAX Requests Inspect network requests in DevTools for failed POST /admin/your_entity/sort calls. Common issues:

    • Missing CSRF token (ensure Sonata’s security is configured).
    • Invalid JSON payload (verify position field names match the config).
  2. Log Sort Events Add a listener to debug sorting logic:

    // src/EventListener/SortLogger.php
    public function onSort(PostSortEvent $event)
    {
        $this->logger->info('Sorting entity', [
            'entity' => $event->getObject()->getId(),
            'new_position' => $event->getNewPosition(),
        ]);
    }
    
  3. Template Overrides If custom templates break, verify:

    • The template path is correct (e.g., AppBundle:Admin:_sort.html.twig).
    • Variables like action and objectId are passed to the template.

Extension Points

  1. Custom Sort Logic Override the PixSortableBehaviorBundle\Event\SortEvent to add validation or business logic:

    // src/EventSubscriber/SortSubscriber.php
    public function onSort(SortEvent $event)
    {
        if ($event->getNewPosition() < 0) {
            $event->setNewPosition(0); // Prevent negative positions
        }
    }
    
  2. Add Sortable Groups Dynamically Extend the bundle’s configuration loader to fetch sortable_groups from the database:

    # config/packages/pix_sortable_behavior.yaml
    pix_sortable_behavior:
        sortable_groups:
            dynamic: true  # Enable dynamic loading
    
  3. Integrate with API Platform Expose the position field in API responses and add a PATCH endpoint for sorting:

    # config/api_platform/resources.yaml
    App\Entity\Post:
        collectionOperations:
            sort: { method: 'PATCH', path: '/posts/sort', ... }
    
  4. Bulk Sorting Add a bulk-sort action to the list view:

    // src/Admin/PostAdmin.php
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper->add('_action', 'actions', [
            'actions' => [
                'move' => [],
                'bulk_sort' => [
                    'type' => 'url',
                    'label' => 'Bulk Sort',
                    'route' => 'admin_bulk_sort',
                ],
            ],
        ]);
    }
    

Configuration Quirks

  1. Default Values

    • If position_field.default is not set, the bundle defaults to sort.
    • If db_driver is not specified, it defaults to orm.
  2. Case Sensitivity

    • Entity class names in position_field.entities must match exactly (including namespace).
  3. Template Paths

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware