Weave 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

Easy Admin Tree Select Field Bundle Laravel Package

tourze/easy-admin-tree-select-field-bundle

Adds a tree-select field to EasyAdmin forms, letting editors pick nodes from hierarchical data like categories, menus, or org units in a searchable, nested dropdown. Install the bundle, register it, and use the field type in your CRUD controllers to choose parent records cleanly.

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/easy-admin-tree-select-field-bundle is a Symfony bundle (EasyAdmin field extension), not a Laravel package — despite the Laravel framing here, day one is about confirming that boundary. It ships a tree-select form field for choosing a node from a hierarchical entity (adjacency-list parent_id style tables) inside EasyAdmin CRUD controllers.

Minimal sequence:

  1. Install with Composer: composer require tourze/easy-admin-tree-select-field-bundle. This is a bundle, so there is no config/app.php provider entry — instead confirm the bundle is picked up by Flex (check config/bundles.php for the Tourze\EasyAdminTreeSelectFieldBundle\... entry; add it manually if Flex skipped it).
  2. Verify the EasyAdmin version in composer.lock — field bundles are tightly coupled to EasyAdmin 4.x field APIs, and a 1.0.0 tag published with only an auto-generated changelog gives you no compatibility matrix. composer why-not is your first debugging tool.
  3. Look first at the bundle's Field/ directory (the field class and its configureOptions) and any assets/ or Resources/ folder for the JS/CSS that renders the tree widget. That tells you which options are actually forwarded to the underlying form type.
  4. First use case: a Category entity with parent self-referencing relation, wired into CategoryCrudController::configureFields() as the tree-select field for the parent relationship. Then test index (list) and edit (form) pages before going near new — creation is where empty-tree and root-node bugs show up.

If you are on Laravel and arrived here by name collision: there is no service provider, no config/*.php publish tag, and no Eloquent bridge. Stop and look for a Laravel-native alternative unless you are running a Symfony app alongside.

Implementation Patterns

Field configuration in the CRUD controller. The core pattern is adding the field to configureFields() and letting the bundle's field class handle option normalization. Keep entity, form, and index contexts distinct — tree rendering on index is usually a different (heavier) code path than on edit/new.

Self-referencing entity as the source of truth. The field expects a parent/child relation. Standard entity shape:

#[ORM\ManyToOne(targetEntity: Category::class, inversedBy: 'children')]
#[ORM\JoinColumn(onDelete: 'SET NULL')]
private ?Category $parent = null;

onDelete: 'SET NULL' matters — cascading deletes on a tree silently removes whole subtrees.

Repository-driven tree loading. Do not let the field pull children lazily per node. Add a repository method that returns the flat, ordered node set in one query and hand it in via the field's query-builder/choice options:

public function findTreeOrdered(): array
{
    return $this->createQueryBuilder('c')
        ->orderBy('c.root, c.lft', 'ASC') // or c.name if adjacency-only
        ->getQuery()
        ->getResult();
}

Shared field configuration. If several CRUD controllers use the same tree, extract a small factory or trait rather than repeating options — this is the extension point that saves the most time when you upgrade EasyAdmin.

Integration with form themes and assets. For non-Flex installs, run bin/console assets:install --symlink after adding the bundle; the tree widget's JS will 404 otherwise and the field renders as a plain <select>, which is an easy-to-misread "the package is broken" symptom.

Migration/workflow pattern. When adopting on an existing flat table: add the parent column as nullable, backfill roots, populate relations in a one-off command or Doctrine migration, then flip the field on. Trees are painful to retrofit mid-flight, so stage it.

Gotchas and Tips

  • Only an auto-generated changelog exists for 1.0.0. Treat the 1.0.0 tag as "first stable API" only in the semver sense; there is no documented list of what changed, what is deprecated, or what is still experimental. Pin the exact version ("1.0.0" or ~1.0.0) and read the field class source before relying on any option name.
  • Bundle vs. package confusion is the top support risk. If a team member has a Laravel mental model, they will look for a service provider and a config/ publish tag and find neither. Document the Symfony/EasyAdmin requirement in your own README so the next person does not burn an hour.
  • EasyAdmin major-version drift. Field bundles subclass EasyAdmin field classes; a minor EasyAdmin bump can break configureOptions contracts. Run the EasyAdmin upgrade in its own commit with the tree field exercised on both index and edit.
  • Recursive rendering cost. Deep or wide trees slow the list view far more than the form view. If index is sluggish, restrict the tree field to form pages and show a breadcrumb/path string in the list instead.
  • Cycle protection is on you. Nothing in a tree field prevents setting a node's parent to one of its own descendants. Validate on the entity (prePersist/preUpdate lifecycle callback or a Symfony validator constraint) — a cycle will hang the widget on next render, and the failure looks like a JS bug, not a data bug.
  • Debugging the widget. When the tree renders empty, check in this order: asset install, the choice/query option actually being set in the controller, then whether your repository returns roots only. Enable the Symfony profiler's form panel to see the resolved options on the field — that beats dump()-ing the controller.
  • Extension points. The field class itself, the form theme template, and the JS asset are the three places to override. Prefer overriding the template in your app's templates/bundles/... path over forking the bundle; forking means you inherit maintenance for a package whose release notes you cannot audit.
  • No deprecation runway. With a first tagged release and no changelog narrative, assume future breaking changes may arrive without a deprecation layer. Keep the field's usage confined to a handful of controllers so an upgrade is a contained diff.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager