Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

bionary's avatar

Making Form Dropdown: DRY and Validate?

What is a good way to architect form dropdowns so that I don't have to change datasets in multiple places and can also easily validate the form data server-side.

It almost feels like I should be making a helper function/array or something in laravel somewhere. And then looping through that array in blade, but also using this helper to validate the data.

An example use case would be a list of states (NY,NJ,CA,...) or a list of colors (red,blue,yellow,...). If the data lives somewhere in laravel, then items can easily be added...but where would this data live and what's a good best-practice?

Any thoughts?

Thank you

0 likes
5 replies
Snapey's avatar

You could use something like spatie valuestore package and then save states as an array in the setting?

https://github.com/spatie/valuestore

You could use a migration or a seeder to import the list of values at deployment.

(i was going to suggest that the valuestore itself could just be a json file committed in your code, but the problem with that is that if you redeploy the application, the value store would be reset - potentially loosing any changes made by users)

1 like
bionary's avatar

@SNAPEY - Hey thanks, this is a good suggestion but I'm a bit unclear on a few things you mentioned.

After reading the api/doc it looks like I would create the lists of things via a valuestore method. So I would need an admin script of some sort to build out the json file, right? Is this what you mean by "seeder"?

I'm not sure what you mean by migration? I think of database when I hear that term.

I can't see why committing the json file would be problematic but I'm probably missing something. The only this in this json file would be lists of things such as: states, sizes, colors, etc... Things only I add in and rarely change. Couldn't I just run my seeder script after I make a change push the json to production?

Thanks.

Snapey's avatar
Snapey
Best Answer
Level 122

If you want an array of items that will only change through code changes then you can do this with a simple config file. For instance, in your example of states, make a file states.php in the config folder and then put in it;

<?php

return [

    'NY','NJ','CA'....
];

Then in a view,

@foreach(config('states') as $state)
    <option>{{ $state }}</option>
@endforeach

and in validation use the in rule and pass the config element.

But, if you want a user to be able to change these lists of values then a user interface could be built to modify the spatie value store. This is where there are maybe a list of choices that the user decides.

Suppose you were building a HR system, you might start with a list of 'types' such as 'Manager', 'Supervisor', 'Developer' etc as a get them started type list. But then the user of the system wants to add new job types. They should be able to do this without coming to you to edit the code. You could create a table for this, or you could store it in the valuestore.

If you hold that valuestore in code then when you deploy an updated version of the application you could easily overwrite the user's modified list with your base list.

This is why I mentioned seeding or Migrations.

Migrations are just a script that runs only when you ask for it, and hopefully not twice. Just as you might push rows into the database after building the tables, you could do the same for valuestore.

A migration created like php artisan make:migration == create_job_types --create=whatever will contain;

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateJobTypes extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('whatever', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

You can put whatever code you like in the up() and down() methods, eg

    public function up()
    {

        $valuestore = Valuestore::make($pathToFile);

        $valuestore->put(['jobtypes' => [
            'Director',
            'Manager',
            'Supervisor',
            'Developer',
            ],
        ]);

    }
    

The benefit of this is that if you redeploy to a new server, you can run php artisan migrate:fresh and have the value store initiated.

bionary's avatar

Simply wow, I am grateful for your examples and explanation Snapey! You have nudged me in a direction that has actually streamlined my code. Now that I know what was possible I went back and read some of the docs and watched some of the tuts as well.

For more information checkout:

https://laravel.com/docs/5.7/configuration

https://laracasts.com/series/laravel-from-scratch-2018/episodes/23 (beginning ~ 8:30 )

The problem is I watch all of these things but forget about them or don't know where to look. But your response was incredibly helpful.

I ended up making a file: config/myappname.php

And in there I have a multi dimensional array containing all lists, everything.

I love how laravel can cache the configs into one file!

php artisan config:cache

so cool.

Thanks a bunch!

Please or to participate in this conversation.