Plugins
Adjacency List
A package to manage adjacency lists.
Form Builder
Form Field
Dark theme support
Yes
Multi language support
Yes
Compatible with the latest version
Supported versions: 3.x
Documentation

Latest Version on Packagist Total Downloads

A Filament package to manage adjacency lists (aka trees).

Banner

#Installation

You can install the package via composer:

composer require saade/filament-adjacency-list

#Usage

use Saade\FilamentAdjacencyList\Forms\Components\AdjacencyList;
 
AdjacencyList::make('subjects')
->form([
Forms\Components\TextInput::make('label')
->required(),
])

#Configuration

#Customizing the label key used to display the item's label

AdjacencyList::make('subjects')
->labelKey('name') // defaults to 'label'

#Customizing the children key used to gather the item's children.

Note: This is only used when not using relationships.

AdjacencyList::make('subjects')
->childrenKey('children') // defaults to 'children'

#Customizing the MaxDepth of the tree.

AdjacencyList::make('subjects')
->maxDepth(2) // defaults to -1 (unlimited depth)

#Creating items without a modal.

AdjacencyList::make('subjects')
->modal(false) // defaults to true

#Disabling creation, edition, deletion, and reordering.

AdjacencyList::make('subjects')
->addable(false)
->editable(false)
->deletable(false)
->reorderable(false)

#Customizing actions

use Filament\Forms\Actions\Action;
 
AdjacencyList::make('subjects')
->addAction(fn (Action $action): Action => $action->icon('heroicon-o-plus')->color('primary'))
->addChildAction(fn (Action $action): Action => $action->button())
->editAction(fn (Action $action): Action => $action->icon('heroicon-o-pencil'))
->deleteAction(fn (Action $action): Action => $action->requiresConfirmation())
->reorderAction(fn (Action $action): Action => $action->icon('heroicon-o-arrow-path-rounded-square'))

Important: Reorder Action

If you want to add ->extraAttributes() to the action, you need to add the 'data-sortable-handle' => 'true' to the array, as the action serves as a handle for SortableJS.

By default, clicking on the action will do anything. If you want to trigger some action on click, you need to chain ->livewireClickHandlerEnabled() on the action.

#Relationships

In this example, we'll be creating a Ticketing system, where tickets can be assigned to a department, and departments have subjects.

#Building the relationship

// App/Models/Department.php
 
class Department extends Model
{
public function subjects(): HasMany
{
return $this->hasMany(Subject::class)->whereNull('parent_id')->with('children')->orderBy('sort');
}
}
// App/Models/Subject.php
 
class Subject extends Model
{
protected $fillable ['parent_id', 'name', 'sort']; // or whatever your columns are
 
public function children(): HasMany
{
return $this->hasMany(Subject::class, 'parent_id')->with('children')->orderBy('sort');
}
}

Now you've created a nested relationship between departments and subjects.

#Using the relationship

// App/Filament/Resources/DepartmentResource.php
 
AdjacencyList::make('subjects')
->relationship('subjects') // Define the relationship
->labelKey('name') // Customize the label key to your model's column
->childrenKey('children') // Customize the children key to the relationship's method name
->form([ // Define the form
Forms\Components\TextInput::make('name')
->label(__('Name'))
->required(),
]);

That's it! Now you're able to manage your adjacency lists using relationships.

#Working with Staudenmeir's Laravel Adjacency List

This package also supports Staudenmeir's Laravel Adjacency List package.

First, install the package:

composer require staudenmeir/laravel-adjacency-list:"^1.0"
  1. Use the HasRecursiveRelationships trait in your model, and override the default path separator.
// App/Models/Department.php
 
class Department extends Model
{
use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
 
public function getPathSeparator()
{
return '.children.';
}
}

If you're already using the HasRecursiveRelationships trait for other parts of your application, it's probably not a good idea to change your model's path separator, since it can break other parts of your application. Instead, you can add as many path separators as you want:

class Department extends Model
{
use \Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
 
public function getCustomPaths()
{
return [
[
'name' => 'tree_path',
'column' => 'id',
'separator' => '.children.',
],
];
}
}
  1. Use the relationship method to define the relationship:
AdjacencyList::make('subdepartments')
->relationship('descendants') // or 'descendantsAndSelf', 'children' ...
->customPath('tree_path') // if you're using custom paths

That's it! Now you're able to manage your adjacency lists using relationships.

#Customizing the query

AdjacencyList::make('subdepartments')
->relationship('descendants', fn (Builder $query): Builder => $query->where('enabled', 1))

#Ordering

If your application needs to order the items in the list, you can use the orderColumn method:

AdjacencyList::make('subdepartments')
->orderColumn('sort') // or any other column

#Changelog

Please see CHANGELOG for more information on what has changed recently.

#Contributing

Please see CONTRIBUTING for details.

#Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

#Credits

#License

The MIT License (MIT). Please see License File for more information.

Sponsor Saade

Saade

CTO, TALL Stack Developer at a Brazilian startup. Creating top-tier technology for public sector applications, making information and services universally accessible.

4
Plugins
351
Stars
More from this author
Featured Plugins