johncarter/filament-nested-sortable

A Filament plugin for ordering and nesting model records

v1.0.0 2025-07-24 23:07 UTC

This package is auto-updated.

Last update: 2025-07-24 23:11:36 UTC


README

A Filament Panels plugin for ordering and nesting model records.

Screenshot

Installation

You can install the package via composer:

composer require johncarter/filament-nested-sortable

Usage

Ensure your model has an order integer column and an integer parent_id with a default to -1.

1. Create a new page in your resource

e.g. app/Filament/Resources/PageResource/Pages/TreeListPages.php

Make sure the page extends JohnCarter\FilamentNestedSortable\Pages\NestedSortablePage.

use JohnCarter\FilamentNestedSortable\Pages\NestedSortablePage;

class TreeListPages extends NestedSortablePage
{
    // ...
}

2. Add the page to your main PageResource Page

public static function getPages(): array
{
    return [
        'index' => Pages\TreeListPages::route('/'),
    ];
}

3. Add plugins Tailwind CSS class content

Add the plugin's view paths to your resources/css/filament/cp/theme.css file:

@import '/vendor/johncarter/filament-nested-sortable/resources/views/**/*.blade.php';

4. Modify the create record form:

public function getCreateRecordFormSchema(): array
    {
        return [
            TextInput::make('title')
                ->reactive()
                ->afterStateUpdated(
                    fn($state, callable $set) =>
                    $set('slug', Str::slug($state))
                ),

            TextInput::make('slug')
                ->extraAttributes(['class' => 'font-mono text-gray-500']),
        ];
    }

5. Add actions to the record action group

    public function getRecordActions(): array
    {
        $actions = parent::getRecordActions();

        array_unshift($actions, $this->viewAction());

        return $actions;
    }

    public function viewAction(): Action
    {
        return Action::make('view')
            ->icon('heroicon-o-eye')
            ->openUrlInNewTab()
            ->url(function (array $arguments) {
                return $arguments['record']['url'];
            });
    }