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

Laravel Reorderable Laravel Package

atomcoder/laravel-reorderable

View on GitHub
Deep Wiki
Context7

Getting Started

To begin using atomcoder/laravel-reorderable, follow these minimal steps:

  1. Install the package:

    composer require atomcoder/laravel-reorderable
    php artisan reorderable:install
    

    This publishes the config, views, and migration stub.

  2. Add a sort column to your target table (e.g., sort_order):

    Schema::table('tasks', function (Blueprint $table) {
        $table->unsignedInteger('sort_order')->default(0)->index();
    });
    
  3. Make your model reorderable:

    use Atomcoder\LaravelReorderable\Contracts\ReorderableContract;
    use Atomcoder\LaravelReorderable\Traits\HasSortOrder;
    
    class Task extends Model implements ReorderableContract
    {
        use HasSortOrder;
        protected $fillable = ['title', 'sort_order'];
        public function getReorderLabel(): string { return $this->title; }
    }
    
  4. Whitelist your model in config/reorderable.php:

    'allowed_models' => [
        App\Models\Task::class,
    ],
    
  5. Fetch and render items:

    $tasks = Task::ordered()->get();
    
    @include('reorderable::components.list', [
        'items' => $tasks,
        'modelClass' => App\Models\Task::class,
    ])
    

First use case: Implement drag-and-drop sorting for a list of tasks in a project. Use the ordered() scope to fetch tasks and render them with the Blade component.


Implementation Patterns

Core Workflow

  1. Model Setup:

    • Use HasSortOrder trait and implement ReorderableContract.
    • Define getReorderLabel() for UI display text.
    • Optionally override $sortColumn or getDefaultReorderGroupColumn().
  2. Fetching Data:

    • Always use ordered() scope to ensure correct sort order:
      $items = Model::where('group_column', $value)->ordered()->get();
      
  3. Rendering UI:

    • Blade: Include the package view with required props:
      @include('reorderable::components.list', [
          'items' => $items,
          'modelClass' => Model::class,
          'groupColumn' => 'project_id',
          'groupValue' => $project->id,
      ])
      
    • Livewire: Use the component directly:
      <livewire:reorderable-list
          :items="$items"
          model-class="Model"
          group-column="project_id"
          :group-value="$project->id"
      />
      
  4. Grouped Reordering:

    • For nested structures (e.g., tasks in projects), specify groupColumn and groupValue in both the query and UI.
  5. Programmatic Reordering:

    • Move a single item:
      $item->moveToPosition(3, 'project_id', $projectId);
      
    • Bulk reorder:
      Model::reorderFromArray([5, 1, 3], 'project_id', $projectId);
      

Integration Tips

  • Authorization: Use the authorize config callback to restrict reordering:
    'authorize' => function ($request, $modelClass) {
        return $request->user()->can('reorder-' . $modelClass);
    },
    
  • Events: Listen for ItemsReordered to trigger side effects (e.g., cache updates):
    Event::listen(ItemsReordered::class, function ($event) {
        Cache::forget("reorderable-{$event->modelClass}");
    });
    
  • Custom Styling: Override the package’s Blade views in resources/views/vendor/reorderable/components/list.blade.php.

Gotchas and Tips

Pitfalls

  1. Missing CSRF Token:

    • The Blade component requires <meta name="csrf-token"> in the <head> and @stack('scripts') in the layout. Forgetting this breaks drag-and-drop functionality.
  2. Incorrect Grouping:

    • If groupColumn/groupValue are misconfigured, reordering may affect items outside the intended group. Always verify with:
      $items = Model::where('group_column', $value)->ordered()->get();
      
  3. Sort Column Conflicts:

    • Ensure $sortColumn matches the database column name. Defaults to sort_order but can be customized per model.
  4. Livewire Hydration:

    • Livewire components may require public properties for props:
      public $items;
      public $modelClass;
      
  5. Demo Route:

    • The /reorderable/demo route is disabled by default (demo.enabled = false). Enable only for testing.

Debugging

  • Check Payload: Inspect the POST request to /reorderable/update (default route) to verify the payload structure:
    {
        "model": "App\\Models\\Task",
        "items": [1, 3, 2],
        "group_column": "project_id",
        "group_value": 5
    }
    
  • Event Listeners: Use php artisan event:listen to debug ItemsReordered events:
    php artisan event:listen Atomcoder\LaravelReorderable\Events\ItemsReordered
    
  • Database Updates: Verify sort values are updated correctly with:
    Model::where('project_id', $projectId)->ordered()->get();
    

Extension Points

  1. Custom UI:

    • Extend the Blade/Livewire components by copying vendor/atomcoder/laravel-reorderable/resources/views to resources/views/vendor/reorderable.
  2. Custom Sort Logic:

    • Override moveToPosition() or reorderFromArray() in your model for custom behavior:
      public function moveToPosition($position, $groupColumn = null, $groupValue = null)
      {
          // Custom logic here
          parent::moveToPosition($position, $groupColumn, $groupValue);
      }
      
  3. API Integration:

    • Reuse the reorderFromArray() logic in API endpoints:
      public function updateOrder(Request $request)
      {
          $this->validate($request, ['items' => 'required|array']);
          Model::reorderFromArray($request->items, 'group_column', $request->group_value);
          return response()->json(['success' => true]);
      }
      
  4. Testing:

    • Use the reorderFromArray() method in tests to set up sorted data:
      public function testReordering()
      {
          Model::reorderFromArray([3, 1, 2]);
          $this->assertDatabaseHas('tasks', ['id' => 1, 'sort_order' => 2]);
      }
      

Configuration Quirks

  • Route Prefix: Changing route_prefix in config affects all package routes (e.g., /custom/reorderable/update).
  • Middleware: Ensure middleware in config includes web for CSRF protection. Add auth if reordering should be restricted:
    'middleware' => ['web', 'auth'],
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity