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

marsuch's avatar

Multi Level Category in Select Option

Hi I need to do multiple category entries. In the drop-down menu.

I have a table with 4 columns [id, title, url, parent_id]. Of which ID, and title I list in the drop-down menu. But I would need them to be listed as they are recursively stored in the database

Which I partially succeed in using the following code:

<div class="form-group">
                <label>Kategorie</label>
                <select class="form-control" name="parent_id">
                    <option selected disabled>Vyberte ID rodičovské položky</option>
                    @foreach($allMenus as $menu)
                        <option value="{{ $menu->id }}">{{$menu->title}}</option>
                        @foreach($menu->childs as $sub)
                            <option value="{{ $sub->id }}">-{{ $sub->title }}</option>
                        @endforeach
                    @endforeach
                </select>
            </div>

However, this sinks exactly as it is stored in the database. This causes some items to be displayed twice, e.g

The category of traction battery belongs to the category of source. The source category belongs to the electronics category.

And when I list, I see this

-Electronics
--traction battery
--powersource
--pencil batteries
-traction battery
--use of traction battery
--disposal of traction battery

But I need such a view

-Electronics
--traction battery¨
---use of traction battery
---disposal of traction battery
--powersource
--pencil batteries

How can I do the immersion so that it is not unnecessarily confused

0 likes
2 replies
tykus's avatar

The allMenus variable should only contain parent categories; but you don't show your queries, so this is for example only

// Menu model

public function scopeParent(Builder $builder)
{
	return $builder->whereNull('parent_id'); // returns only top-level menu items
}

// Controller
$allMenus = Menu::parent()->with('childs.childs')->get(); 
// example of eager-loading children two levels below the parent
marsuch's avatar

Finally, the problem was solved by changing the database query

        $allMenus = Menu::where('parent_id', '=', 0)->get();

And by adding another immersion to the view. I haven't noticed your answers before. But I will definitely try it too

<select class="form-control" name="parent_id">
                    <option selected disabled>Select menu category</option>
                    @foreach($allMenus as $category)
                        <option value="{{$category->id}}">{{$category->title}}</option>
                        @foreach($category->childs as $sub)
                            <option value="{{$sub->id}}">-{{$sub->title}}</option>
                            @foreach($sub->childs as $subsub)
                                <option value="{{$subsub->id}}">--{{$subsub->title}}</option>
                            @endforeach
                        @endforeach
                    @endforeach
                </select>

And the result is exactly what I need

Please or to participate in this conversation.