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

Laravel Simple Select Laravel Package

dotmarn/laravel-simple-select

A lightweight Laravel package that makes building HTML select elements simple. Generate options from arrays or Eloquent models, handle selected values and placeholders, and keep your Blade forms clean with minimal boilerplate. Works with old input and validation.

View on GitHub
Deep Wiki
Context7

Getting Started

The v1.0.0 tag is the package's first stable release, and the only change called out is Laravel v12 support. That makes this a good moment to adopt it: the public API is now covered by semver, so a ^1.0 constraint won't surprise you with breaking changes the way an unpinned 0.x requirement could.

  1. Install with an explicit major constraint so you stay on the stable line:
    composer require dotmarn/laravel-simple-select:^1.0
    
  2. Confirm the environment matrix before you commit. v1.0.0 explicitly targets Laravel 12, so check composer.json for the supported illuminate/* range and the minimum PHP version (Laravel 12 implies PHP 8.2+). If your app is still on Laravel 10/11, verify the constraint actually allows it rather than assuming — the release note only mentions 12.
  3. Laravel package auto-discovery should register the service provider. If the README advertises publishable config or views, run the publish command it documents; otherwise there is nothing to configure and you can start using it immediately.
  4. First use case: pick the ugliest <select> in your app — usually a form with a belongsTo relation — and replace the hand-rolled @foreach ($roles as $role) <option value="{{ $role->id }}" @selected(old('role_id', $user->role_id) == $role->id)> block with the package's helper. That single swap exercises the three things you actually care about: option generation, selected-state resolution, and old-input handling. Once that works, roll it out form by form.

Keep the changelog link (.../commits/v1.0.0) open while you onboard. Because this is the 1.0.0 milestone, read back through the 0.x tags too — the jump to 1.0.0 is where a maintainer normally banks up renames and signature changes, and the visible release note probably doesn't tell the whole story.

Implementation Patterns

Controller-prepares-data, view-renders. The most maintainable pattern is to build the option set in the controller (or a form request / view model) and pass a plain array or collection into the view. This keeps queries out of Blade, makes the data easy to assert in feature tests, and means the package is only responsible for markup — so if you ever drop it, the swap is one line per template.

Model-backed options. For enum-ish tables, pluck only the two columns you need:

$roles = Role::orderBy('name')->pluck('name', 'id');

Being explicit about the select list avoids hydrating full models just to read a label, and it pairs naturally with whatever key/label signature the helper exposes.

Selected state resolution order. The rule you want in every form is: old input wins, then the persisted model value, then a default. Centralise that so no template reimplements it — if the package's helper takes the current value as an argument, pass old('role_id', $user->role_id) and let the package own the comparison. Watch for loose-vs-strict comparison: a string "3" from old() and an int 3 from the model must both match, which is exactly the kind of thing a helper exists to paper over.

Placeholders and empty options. Decide on a per-form basis whether an empty first option is a prompt ("Choose a role…") or a legitimate value ("Unassigned"). These behave differently on validation and on re-population after a failed submit; treat them as two distinct helpers or an explicit boolean flag in your own wrapper.

Wrap it once. Put a thin Blade component or helper of your own in front of the package — e.g. <x-form.select name="role_id" :options="$roles" :value="$user->role_id" />. That gives you one place to add @error class toggling, aria-invalid, required markers, and any app-specific styling, and it isolates your codebase from the package's API surface. This is the highest-leverage thing you can do with a small UI package.

Dependent / cascading selects. For country → region style forms, render the first select server-side and populate the second with a JSON endpoint or Livewire. The package handles the initial markup; it won't manage the async refresh, so keep that logic in your JS/Livewire layer and reuse the same option-shaping code in the endpoint as in the initial render.

Validation and errors. Pair every select with the matching @error('field') block, and assert in feature tests that a failed validation re-renders with the previously submitted value selected — that's the regression most likely to bite you after a refactor.

Gotchas and Tips

  • Laravel 12 is new, the rest is unstated. Don't infer that 10/11 work just because they used to. Check the composer.json constraints on the 1.0.0 tag, and if you maintain a package or a multi-version app, add 12 to your CI matrix rather than trusting the changelog line.
  • The 0.x → 1.0.0 delta is invisible here. The release note shows one line, but the 1.0.0 boundary is where breaking changes conventionally land. If you were already on a 0.x version, diff the source or scan the README for renamed methods before bumping, and read the full commit list behind the link.
  • N+1 queries hide in selects. A select inside a table row that calls $row->relation->pluck(...) is a classic. Eager-load or pre-pluck the option set once outside the loop.
  • Escaping. Labels are often user-entered (category names, team names). Confirm the helper escapes output; if it emits raw HTML, a crafted category name becomes stored XSS in every admin dropdown.
  • Config caching. If the package ships config, php artisan config:cache in deploy scripts will freeze it — remember to re-run on deploy, and don't read config at boot in a way that breaks under cache.
  • Auto-discovery failures. If the helper or facade isn't found, the first thing to check is bootstrap/cache/packages.php after a composer dump-autoload; stale discovery caches after a version jump are common and look like missing classes.
  • Debugging output. When a select renders "wrong", dump the option array and the resolved current value before the template. Nine times out of ten the bug is a key type mismatch or an unexpectedly empty collection, not the rendering.
  • Extension points. Prefer publishing/overriding the Blade view or wrapping the helper over forking. With ^1.0 you get patch and minor updates safely; a fork means you own the Laravel 13 upgrade yourself.
  • Pin and review. "dotmarn/laravel-simple-select": "^1.0" is right for an app; for a library, widen to ^1.0 and test against the lowest supported Laravel so you don't quietly require 12-only APIs.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels