Search code examples
laravellaravel-5laravel-8laravel-blade

Laravel: Nested loop html option and increasing the indent (prefix)


I want to display indented subcategories in the html option tag. I created a recursive iteration in a separate file that I import in a foreach statement. With the first subcategories, I get a prefix of one space and when it starts to load deeper levels, the indent is the same and should be increased by one more.

How can i increase the indented (prefix) for each level that is deeper?

I expect it to be like this:

Root
  Child
    Sub child 1
    Sub child 2
      Sub sub child

My real exmple when code is excuted is like this:

Root
  Child
  Sub child 1
  Sub child 2
  Sub sub child
  

(no prefix spaces in Sub childrens)

Controller

public function create()
{
    $categories = BlogCategory::where('parent_id', '')->get();

    return view('ecommerce::admin.post.create', [
        'categories' => $categories
    ]);
}

form.blade.php

<select name="public" id="page_category_field" class="custom-select {{ $errors->has('status') ? 'is-invalid' : ''}}">
        @foreach($categories as $category)
            <option value="{{ $category->id }}">{{ $category->name }}</option>

            @if(count($category->childrens) > 0)
                @include('ecommerce::admin.post.loop.nested_category_html_select', ['childrens' => $category->childrens])
            @endif
        @endforeach
</select>

nested_category_html_select.blade.php

@foreach($childrens as $child)
    <option value="{{ $child->id }}">&nbsp; {{ $child->name }}</option>

    @if(count($child->childrens) > 0)
        @include('ecommerce::admin.post.loop.nested_category_html_select', ['childrens' => $child->childrens])
    @endif
@endforeach

Here is problem in &nbsp:

<option value="{{ $child->id }}">&nbsp; {{ $child->name }}</option>

How to add more spaces for each new level?


Solution

  • This may be very basic (not the best solution), but one simple and quick solution would be for you to pass another variable specifying the level of indentation you want:

    nested_category_html_select.blade.php

    @foreach($childrens as $child)
        <option value="{{ $child->id }}">
            @foreach(range(1, $level ?? 1) as $l)
                &nbsp;
            @endforeach
            {{ $child->name }}
        </option>
    
        @if(count($child->childrens) > 0)
            @include('ecommerce::admin.post.loop.nested_category_html_select', ['childrens' => $child->children's, 'level' => $level + 1])
        @endif
    @endforeach
    

    The code may not exactly work as I did not use blade in a long time, but the idea would be for you to add spaces based on the level you are currently at.

    One more thing you would need to modify is having $level available on the blade file, so if no one inputs something, it has $level = 1, and then you increment by 1.