PHPackages                             codewithdennis/filament-select-tree - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. codewithdennis/filament-select-tree

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

codewithdennis/filament-select-tree
===================================

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

v4.0.18(2mo ago)320392.1k—5.6%53[1 issues](https://github.com/CodeWithDennis/filament-select-tree/issues)[1 PRs](https://github.com/CodeWithDennis/filament-select-tree/pulls)15MITPHPPHP ^8.2CI passing

Since Sep 17Pushed 1mo ago4 watchersCompare

[ Source](https://github.com/CodeWithDennis/filament-select-tree)[ Packagist](https://packagist.org/packages/codewithdennis/filament-select-tree)[ Docs](https://github.com/codewithdennis/filament-select-tree)[ GitHub Sponsors](https://github.com/CodeWithDennis)[ RSS](/packages/codewithdennis-filament-select-tree/feed)WikiDiscussions 4.x Synced 1mo ago

READMEChangelog (10)Dependencies (16)Versions (88)Used By (15)

Filament Select Tree
====================

[](#filament-select-tree)

[![Latest Version on Packagist](https://camo.githubusercontent.com/a6c1bed8af3fcd3037a7ac8f4f06b05ef65ef2879d43c13cabbb5b8e96a766a9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f636f64657769746864656e6e69732f66696c616d656e742d73656c6563742d747265652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/codewithdennis/filament-select-tree)[![Total Downloads](https://camo.githubusercontent.com/af431823329515f811c4cea866605e5f434fd6825695186d6fe89d4fc94aa505/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f636f64657769746864656e6e69732f66696c616d656e742d73656c6563742d747265652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/codewithdennis/filament-select-tree)

If you're using Filament 3.x, check out the compatible version of this package [here](https://github.com/CodeWithDennis/filament-select-tree/tree/3.x).

This package adds a dynamic select tree field to your Laravel / Filament application, allowing you to create interactive hierarchical selection dropdowns based on relationships. It's handy for building selection dropdowns with various customization options.

[![thumbnail](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/thumbnail.jpg)](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/thumbnail.jpg)

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require codewithdennis/filament-select-tree:4.x
```

```
php artisan filament:assets
```

Relationships
-------------

[](#relationships)

Use the tree for a `BelongsToMany` relationship

```
SelectTree::make('categories')
    ->relationship('categories', 'name', 'parent_id')
```

Use the tree for a `BelongsTo` relationship

```
SelectTree::make('category_id')
    ->relationship('category', 'name', 'parent_id')
```

Usage without relationships
---------------------------

[](#usage-without-relationships)

Use the tree without relationship

```
SelectTree::make('category_id')
    ->query(fn() => Category::query(), 'name', 'parent_id')
```

Custom Query
------------

[](#custom-query)

Customize the parent query

```
SelectTree::make('categories')
    ->relationship(relationship: 'categories', titleAttribute: 'name', parentAttribute: 'parent_id', modifyQueryUsing: fn($query) => $query));
```

Customize the child query

```
SelectTree::make('categories')
    ->relationship(relationship: 'categories', titleAttribute: 'name', parentAttribute: 'parent_id', modifyChildQueryUsing: fn($query) => $query));
```

Methods
-------

[](#methods)

Set a custom placeholder when no items are selected

```
->placeholder(__('Please select a category'))
```

Enable the selection of groups

```
->enableBranchNode()
```

Customize the label when there are zero search results

```
->emptyLabel(__('Oops, no results have been found!'))
```

Display the count of children alongside the group's name

```
->withCount()
```

Keep the dropdown open at all times

```
->alwaysOpen()
```

Add the list as a static DOM element so that it doesn't overlap content

```
->staticList()
```

Set nodes as dependent

```
->independent(false)
```

Expand the tree with selected values (only works if field is dependent)

```
->expandSelected(false)
```

Set the parent's null value to -1, allowing you to use -1 as a sentinel value (default = null)

```
->parentNullValue(-1)
```

All groups will be opened to this level

```
->defaultOpenLevel(2)
```

Specify the list's force direction. Options include: auto (default), top, and bottom.

```
->direction('top')
```

Display individual leaf nodes instead of the main group when all leaf nodes are selected

```
->grouped(false)
```

Return parent node value if all of its children are selected, instead of individual leaf nodes.

```
->isGroupedValue()
```

Hide tags and display a count of selected items instead

```
->showTags(false)
```

Customize the text shown if `showTags` is set to `false`, e.g. "{count} {tagsCountText}"

```
->tagsCountText('elements selected')
```

Hide the clearable icon

```
->clearable(false)
```

Activate the search functionality

```
->searchable();
```

Disable specific options in the tree

```
->disabledOptions([2, 3, 4])
```

Hide specific options in the tree

```
->hiddenOptions([2, 3, 4])
```

Allow soft deleted items to be displayed

```
->withTrashed()
```

Specify a different key for your model. For example: you have id, code and parent\_code. Your model uses id as key, but the parent-child relation is established between code and parent\_code

```
->withKey('code')
```

Store fetched models for additional functionality

```
->storeResults()
```

Now you can access the results in `disabledOptions` or `hiddenOptions`

```
->disabledOptions(function ($state, SelectTree $component) {
    $results = $component->getResults();
})
```

By default, the type of selection in the tree (single or multiple) is determined by the relationship type: `BelongsTo` for single selection and `BelongsToMany` for multiple selection. If you want to explicitly set the selection type, use:

```
->multiple(false)
```

you can change the tree key with the following method.

```
->treeKey('my-cool-tree')
```

If you need to prepend an item to the tree menu, use the `prepend` method. This method accepts an array or a closure. It is useful when the tree-select is used as a filter (see example below).

```
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
use CodeWithDennis\FilamentSelectTree\SelectTree;
```

```
->filters([
    Filter::make('tree')
        ->form([
            SelectTree::make('category')
                ->relationship('categories', 'name', 'parent_id')
                ->enableBranchNode()
                ->multiple(false)
                ->prepend([
                    'name' => 'Uncategorized Records',
                    'value' => -1,
                    'parent' => null, // optional
                    'disabled' => false, // optional
                    'hidden' => false, // optional
                    'children' => [], // optional
                ])
        ])
        ->query(function (Builder $query, array $data) {
            return $query->when($data['categories'], function (Builder $query, $categories) {
                if (collect($categories)->contains('-1')) {
                    $query->whereDoesntHave('categories');
                }
                return $query->orWhereHas('categories',
                    fn(Builder $query) => $query->whereIn('id', $categories));
            });
        })
])
```

If you need to append an item to the tree menu, use the `append` method. This method also accepts an array or a closure.

```
->schema([
    SelectTree::make('category')
        ->relationship('categories', 'name', 'parent_id')
        ->enableBranchNode()
        ->multiple(false)
        ->append([
            'name' => 'Uncategorized Records',
            'value' => -1,
            'parent' => null, // optional
            'disabled' => false, // optional
            'hidden' => false, // optional
            'children' => [], // optional
        ])
    ])
```

If you need full control over the tree structure, you can use `getTreeUsing` to provide a custom tree array, or a closure that resolves to an array.

Using an array:

```
SelectTree::make('categories')
    ->getTreeUsing([
        [
            'name' => 'Parent Category',
            'value' => '1',
            'children' => [
                [
                    'name' => 'Child Category',
                    'value' => '2',
                    'children' => [],
                ],
            ],
        ],
        [
            'name' => 'Another Category',
            'value' => '3',
            'children' => [],
        ],
    ])
```

Using a closure for dynamic data:

```
SelectTree::make('categories')
    ->getTreeUsing(function () {
        return Category::query()
            ->get()
            ->map(fn ($category) => [
                'name' => $category->name,
                'value' => $category->id,
                'children' => $category->children->map(fn ($child) => [
                    'name' => $child->name,
                    'value' => $child->id,
                    'children' => [],
                ])->toArray(),
            ])
            ->toArray();
    })
```

The tree structure should follow this format:

```
[
    [
        'name' => 'Display Name',
        'value' => 'option_value',
        'disabled' => false, // optional
        'hidden' => false, // optional
        'children' => [], // optional
    ],
]
```

Filters
-------

[](#filters)

Use the tree in your table filters. Here's an example to show you how.

```
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
use CodeWithDennis\FilamentSelectTree\SelectTree;
```

```
->filters([
    Filter::make('tree')
        ->form([
            SelectTree::make('categories')
                ->relationship('categories', 'name', 'parent_id')
                ->independent(false)
                ->enableBranchNode(),
        ])
        ->query(function (Builder $query, array $data) {
            return $query->when($data['categories'], function ($query, $categories) {
                return $query->whereHas('categories', fn($query) => $query->whereIn('id', $categories));
            });
        })
        ->indicateUsing(function (array $data): ?string {
            if (! $data['categories']) {
                return null;
            }

            return __('Categories') . ': ' . implode(', ', Category::whereIn('id', $data['categories'])->get()->pluck('name')->toArray());
        })
])
```

Screenshots
-----------

[](#screenshots)

[![example-1](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-1.jpg)](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-1.jpg)[![example-2](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-2.jpg)](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-2.jpg)[![example-3](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-3.jpg)](https://raw.githubusercontent.com/CodeWithDennis/filament-select-tree/3.x/resources/images/example-3.jpg)

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [CodeWithDennis](https://github.com/CodeWithDennis) / [Website](https://codewithdennis.com)
- [Dipson88](https://github.com/dipson88/treeselectjs)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance88

Actively maintained with recent releases

Popularity57

Moderate usage in the ecosystem

Community38

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 64.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~10 days

Total

87

Last Release

58d ago

Major Versions

v3.1.57 → v4.0.0-beta.12025-06-28

v3.1.58 → v4.0.02025-07-22

3.x-dev → v4.0.92025-12-24

PHP version history (2 changes)v3.0.0PHP ^8.1

v4.0.0-beta.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/6d47a56dfab94e67a7354a146f96a0285c09f6b9d649c558832c6a9b94354b8c?d=identicon)[CodeWithDennis](/maintainers/CodeWithDennis)

---

Top Contributors

[![CodeWithDennis](https://avatars.githubusercontent.com/u/23448484?v=4)](https://github.com/CodeWithDennis "CodeWithDennis (297 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (25 commits)")[![lotestudio](https://avatars.githubusercontent.com/u/1052691?v=4)](https://github.com/lotestudio "lotestudio (21 commits)")[![gp-lnuff](https://avatars.githubusercontent.com/u/169065476?v=4)](https://github.com/gp-lnuff "gp-lnuff (20 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (18 commits)")[![buzkall](https://avatars.githubusercontent.com/u/5702?v=4)](https://github.com/buzkall "buzkall (10 commits)")[![saade](https://avatars.githubusercontent.com/u/14329460?v=4)](https://github.com/saade "saade (9 commits)")[![gpibarra](https://avatars.githubusercontent.com/u/21188012?v=4)](https://github.com/gpibarra "gpibarra (7 commits)")[![nathanheffley](https://avatars.githubusercontent.com/u/8952123?v=4)](https://github.com/nathanheffley "nathanheffley (6 commits)")[![markvaneijk](https://avatars.githubusercontent.com/u/1925388?v=4)](https://github.com/markvaneijk "markvaneijk (5 commits)")[![iotron](https://avatars.githubusercontent.com/u/50877415?v=4)](https://github.com/iotron "iotron (5 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (4 commits)")[![A909M](https://avatars.githubusercontent.com/u/119125167?v=4)](https://github.com/A909M "A909M (3 commits)")[![ariaieboy](https://avatars.githubusercontent.com/u/15873972?v=4)](https://github.com/ariaieboy "ariaieboy (3 commits)")[![Casmo](https://avatars.githubusercontent.com/u/385764?v=4)](https://github.com/Casmo "Casmo (3 commits)")[![felixgilles](https://avatars.githubusercontent.com/u/900854?v=4)](https://github.com/felixgilles "felixgilles (3 commits)")[![mgkimsal](https://avatars.githubusercontent.com/u/75154?v=4)](https://github.com/mgkimsal "mgkimsal (3 commits)")[![stefket](https://avatars.githubusercontent.com/u/1169903?v=4)](https://github.com/stefket "stefket (3 commits)")[![Baspa](https://avatars.githubusercontent.com/u/10845460?v=4)](https://github.com/Baspa "Baspa (2 commits)")[![mohamedsabil83](https://avatars.githubusercontent.com/u/10126040?v=4)](https://github.com/mohamedsabil83 "mohamedsabil83 (2 commits)")

---

Tags

fieldfilamentfilament-pluginfilamentphplaravelphpselectselect-treetreetree-structurelaraveltreefilamentCodeWithDennisfilament-select-tree

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/codewithdennis-filament-select-tree/health.svg)

```
[![Health](https://phpackages.com/badges/codewithdennis-filament-select-tree/health.svg)](https://phpackages.com/packages/codewithdennis-filament-select-tree)
```

###  Alternatives

[pboivin/filament-peek

Full-screen page preview modal for Filament

253319.6k12](/packages/pboivin-filament-peek)[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

124139.3k2](/packages/dotswan-filament-map-picker)[creagia/filament-code-field

A Filamentphp input field to edit or view code data.

58289.3k3](/packages/creagia-filament-code-field)[ralphjsmit/laravel-filament-components

A collection of reusable components for Filament.

10972.2k2](/packages/ralphjsmit-laravel-filament-components)[swisnl/filament-backgrounds

Beautiful backgrounds for Filament auth pages

54149.2k6](/packages/swisnl-filament-backgrounds)[schmeits/filament-character-counter

This is a Filament character counter TextField and Textarea form field for Filament v4 and v5

33184.7k6](/packages/schmeits-filament-character-counter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
