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

Dependent Select Bundle Laravel Package

evercodelab/dependent-select-bundle

Symfony bundle for dependent select fields: dynamically load and update dropdown options based on another field’s selection, simplifying cascading forms with AJAX-backed choices.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — that shapes everything below. composer require evercodelab/dependent-select-bundle will pull it into a Laravel app, but it won't do anything useful: there is no ServiceProvider, no facade, and the code targets Symfony's Form component (AbstractType, FormBuilderInterface, FormEvents::PRE_SUBMIT) plus a Symfony controller for the AJAX endpoint. Laravel's form story is Blade/HTTP, not a Form component, so the bundle has nothing to hook into.

First steps for a Laravel dev:

  1. Open the README and identify the two moving parts: a form type (usually named something like DependentSelectType or a parent/child pair) and an AJAX endpoint (a controller action that returns JSON options for the child field based on the parent value).
  2. Check composer.json for symfony/form and symfony/framework-bundle constraints — these reveal which Symfony era this targets (likely 2.8/3.x, which is long EOL). That's your signal for how much of the API surface is still relevant.
  3. Read the bundle's JS asset (usually a small dependent-select.js or inline script in a Twig template). This is the most portable piece: it listens for change on the parent <select>, calls the endpoint, and rebuilds the child <select>. That pattern translates 1:1 to Blade + vanilla JS, HTMX, Livewire, or Alpine.
  4. First real use case: a country → region → city cascade on a registration or address form. Model it in Laravel as a GET /api/regions?country_id= JSON route and a Blade partial, or a Livewire component with wire:model.live.

Realistically: treat the repo as reference material, not a dependency. With 0 stars and 0 dependents it's effectively a dormant reference implementation. Copy the idea (parent change → fetch children → swap options → reset downstream selects) into your own stack.

Implementation Patterns

If you're stuck supporting a Symfony app in the same monorepo (or a legacy service you're proxying to from Laravel), the pattern looks like this:

// Symfony side — register in config/bundles.php (modern) or AppKernel (legacy)
$bundles = [ EvercodeLab\DependentSelectBundle\DependentSelectBundle::class => ['all' => true] ];
// A form type that exposes parent/child relationship
$builder->add('country', CountryType::class);
$builder->add('city', DependentSelectType::class, [
    'parent' => 'country',
    'endpoint' => 'app_cities_by_country',
]);

The bundle wires an event listener so that when the parent submits, the child's choices are populated server-side — this matters because Symfony's Form component validates against declared choices. Laravel has no equivalent constraint, which is why porting the server-side half is mostly unnecessary.

Day-to-day Laravel patterns that replace this bundle:

  • Livewire (recommended): two wire:model.live selects, updatedCountryId() resets cityId and repopulates cities. Zero JS, built-in CSRF, testable. This is the direct analogue of the bundle's intent.
  • HTMX / Alpine: parent <select hx-get="/cities" hx-target="#city"> or Alpine x-on:change="fetch('/cities?country='+$event.target.value)...". Keep the endpoint returning an HTML <option> list so you avoid client-side templating.
  • API + SPA: GET /api/regions?country_id= with a resource collection; the JS swaps <option> elements. Mirror the bundle's endpoint contract exactly (parent key in → child list out) so a Symfony frontend and a Laravel frontend can share it.

Integration tips:

  • Keep the cascade stateless and idempotent — the bundle's endpoint is a simple lookup. Cache it (Cache::remember("regions:{$countryId}", 3600, ...)) because dependent-select endpoints get hammered by every keystroke if you attach them to search inputs.
  • Reset all downstream selects when a parent changes, not just the immediate child. The bundle's JS usually does this; in your own code it's the #1 bug.
  • Return the selected value's text alongside the list so edit forms hydrate correctly ([{'id'=>1,'name'=>'...','selected'=>true}]).
  • If a form is submitted before the AJAX completes, the child will be stale — validate the pair server-side with a Rule::exists scoped to the parent (Rule::exists('cities','id')->where('country_id', $countryId)). This is the equivalent of the Symfony Form's choice validation the bundle gives you for free.

Gotchas and Tips

  • It's a Symfony bundle, full stop. No extra.laravel in composer.json, no service provider, no config publish. Installing it in Laravel is a no-op; don't expect a facade or config/dependent_select.php.
  • Zero stars / zero dependents / dormant. Pin nothing, expect no fixes, and audit the JS before copying it (Symfony-era bundle JS often assumes jQuery and uses $.ajax with no CSRF token — a bad import into a Laravel app where VerifyCsrfToken is active).
  • CSRF mismatch is the classic failure. The bundle's endpoint was designed for Symfony sessions; if you port it to a Laravel api.php route it will be unauthenticated by default. Put it behind auth + web middleware and include @csrf or X-CSRF-TOKEN in the fetch headers.
  • Debugging checklist: Network tab → confirm the parent value is in the request payload; confirm the endpoint returns Content-Type: application/json; then confirm the JS is targeting the correct child select ID (bundle-generated IDs often differ from your Blade IDs — this is the most common silent bug).
  • Bundle config quirks to expect: entity/field name mappings, an endpoint route name string (breaks if you rename routes), and a template path override. All three are hard-coded assumptions that don't map to Laravel's Route names.
  • Extension points worth stealing: the event-listener-on-PRE_SUBMIT idea (server-side revalidation of dependent choices) and the "return options as JSON, let JS rebuild the DOM" contract. Implement the former as a FormRequest rule and the latter as a resourceful JSON endpoint.
  • Performance trap: the bundle resolves child options with a fresh query per parent value. In Laravel, use ->where('country_id', $id) with an index on country_id, and eager-load if the child has grandchildren. For three-level cascades add a composite index and cache the leaf level.
  • Don't use it for free-text + datalist cases. Dependent selects assume a closed choice set. If your "child" is a searchable autocomplete (cities with thousands of entries), the bundle's full-list swap degrades badly — use a debounced GET /search/cities?q= instead.
  • Testability: because there's no Laravel integration, you can't php artisan your way through it. Test the ported behavior directly — Livewire::test(CitySelector::class)->set('countryId', 1)->assertSee('...') or a feature test against your JSON route. The bundle itself has no tests you can lean on.

Bottom line: the package is a useful conceptual reference for dependent selects but is not a dependency a Laravel developer can adopt. Skim the JS and the endpoint contract, then build the cascade natively with Livewire or HTMX and enforce the parent-child relationship with a scoped exists rule.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
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