alex-dwt/sortable-behavior-bundle
Install the Bundle
composer require alex-dwt/sortable-behavior-bundle
Enable the bundle in config/bundles.php:
return [
// ...
AlexDwt\PixSortableBehaviorBundle\AlexDwtPixSortableBehaviorBundle::class => ['all' => true],
];
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
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
],
],
]);
}
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;
Clear Cache
php bin/console cache:clear
Enable sorting for a list of blog posts in Sonata Admin:
position_field for App\Entity\BlogPost (e.g., order)._action field to your configureListFields().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
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' => []]]);
}
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
_sort.html.twig or _sort_drag_drop.html.twig in your bundle to customize UI.pixSortableBehaviorBundle.success (jQuery event) to trigger post-sort actions (e.g., notifications or API calls).db_driver: mongodb and ensure your Doctrine MongoDB entities use Sortable behavior (e.g., via Gedmo extensions).position field may improve performance:
// src/EventListener/SortListener.php
public function onSort(PostSortEvent $event)
{
$em = $event->getEntityManager();
$em->flush(); // Flush after every few updates
}
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
],
],
]);
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>
Custom Styling:
Use the is-dragging body class to adjust UI during drag operations:
body.is-dragging #sidebar { opacity: 0.5; }
Missing Position Field
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'sort' in 'order clause'.position_field (e.g., sort or order).Cache Issues
php bin/console cache:clear after configuration changes.JavaScript Conflicts
Uncaught TypeError: $(...).sortable is not a function.init.js and jQuery is available globally.Doctrine Event Conflicts
prePersist) unexpectedly.@ORM\HasLifecycleCallbacks selectively or disable unwanted events.MongoDB Specifics
Call to a member function getId() on null.getId() and use Gedmo’s Sortable behavior.Check AJAX Requests
Inspect network requests in DevTools for failed POST /admin/your_entity/sort calls. Common issues:
position field names match the config).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(),
]);
}
Template Overrides If custom templates break, verify:
AppBundle:Admin:_sort.html.twig).action and objectId are passed to the template.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
}
}
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
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', ... }
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',
],
],
]);
}
Default Values
position_field.default is not set, the bundle defaults to sort.db_driver is not specified, it defaults to orm.Case Sensitivity
position_field.entities must match exactly (including namespace).Template Paths
How can I help you explore Laravel packages today?