简体   繁体   中英

Creating a dropdown that dynamically creates another dropdown in Laravel

I'm fairly new to Laravel (and I love it:) I'm trying to do something a bit complicated. Creating a drop-down menu that upon selection of an option -will display a second drop-down menu that will give further options dynamically based on the previous selection.

My controller looks like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Manufacturer;
use App\GearCategory;
use App\SubCategory;
use App\GearItem;

class GearItemController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth'); 
    }

    public function create(Manufacturer $manufacturers, GearItem $gearItem, GearCategory $gearCategory, SubCategory $subCategory)
    {
        // dd($gearCategory->all());
        $catNum = 6; // <-- needs to be equal to the dispaly div name. Hard coded as 6 for test purposes. 
        $gearCategory = $gearCategory->all();
        $subCategory = $subCategory::where('gear_categories_id', $catNum)->get();
        $manufacturers = $manufacturers->all();


        return view('gearitem.create', compact('gearCategory'), compact('subCategory'), compact('manufacturers'),  compact('gearItem'));
    }
}

My blade looks like this:

  <div class="card-header">
                    <h3>Add a new gear Item</h3>

                </div>
                <div class="container">
                    <select name="gear_categories_id" id="gear_categories_id" class="custom-select mb-3 mt-3"
                        onchange="selector('display_div', this)">
                        <option value="" selected>Choose category</option>
                        @foreach ($gearCategory as $category)
                        <option id="cat_selector" value="{{ $category->id  }}"
                            {{ (old("gear_categories_id") == $category->id ? "selected" : "") }}>{{ $category->name }}
                        </option>

                        @endforeach
                    </select>
                </div>


                <script>
                    "use strict"
                    function selector(divId, element) {

                        console.log(element.value);

                        document.getElementById(divId).setAttribute("name", element.value)

                    }
                </script>



                    <div class="display_div container" id="display_div" name="">

                    <select name="sub_categories_id" id="sub_categories_id" class="custom-select mb-3 mt-3"
                    onchange="selector('display_div', this)">
                    <option value="" selected>Choose item's type</option>
                    @foreach ($subCategory as $scategory)
                    <option id="cat_selector" value="{{ $scategory->id }}"
                        {{ (old("sub_categories_id") == $scategory->id ? "selected" : "") }}>{{ $scategory->name }}
                    </option>
                    @endforeach
                </select>

                </div>

(Sorry for using vanilla JS i haven't gotten into Vue yet...) I'm trying to pass the name of the "display_div" onto the $catNum variable in the controller (set to "6" just to test if it works but should be set to whatever the user is choosing on the first dropdown) The values of the 'gear_categories_id' appear as a foreign key in the SubCategory model and if i'll manage to feed these values to the second dropdown it would work. I've been struggling for hours with it and I can't figure it out... Please help and sorry for being such a n00b.

You can use an AJAX request on change of the parent category drop-down to populate the subcategories. See the code below. I have added a second route to get subCategories for a specific categoryID .

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Manufacturer;
use App\GearCategory;
use App\SubCategory;
use App\GearItem;

class GearItemController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth'); 
    }

    public function create(Manufacturer $manufacturers, GearItem $gearItem, GearCategory $gearCategory, SubCategory $subCategory)
    {
        // dd($gearCategory->all());
        $catNum = 6; // <-- needs to be equal to the dispaly div name. Hard coded as 6 for test purposes. 
        $gearCategory = $gearCategory->all();
        $subCategory = $subCategory::where('gear_categories_id', $catNum)->get();
        $manufacturers = $manufacturers->all();


        return view('gearitem.create', compact('gearCategory'), compact('subCategory'), compact('manufacturers'),  compact('gearItem'));
    }

    public function getSubCategories($categoryID) {
        return  SubCategory::where('gear_categories_id', $categoryID)->get();
    }
}

Route::get('/sub-categories/{categoryID}', 'GearItemController@getSubCategories');

<div class="card-header">
    <h3>Add a new gear Item</h3>
</div>
<div class="container">
    <select name="gear_categories_id" id="gear_categories_id" class="custom-select mb-3 mt-3"
        onchange="selector('display_div', this)">
        <option value="" selected>Choose category</option>
        @foreach ($gearCategory as $category)
        <option id="cat_selector" value="{{ $category->id  }}"
            {{ (old("gear_categories_id") == $category->id ? "selected" : "") }}>{{ $category->name }}
        </option>

        @endforeach
    </select>
</div>


    <script>
        "use strict"
        function selector(divId, element) {

            console.log(element.value);

            document.getElementById(divId).setAttribute("name", element.value);


            fetch('/sub-categories/')
            .then(res => res.json())
            .then(subCategories => {
                var options = subCategories.reduce( (opts, cat) => 
                    `${opts}<option value="${cat.id}">${cat.name}</option>`, "");
                document.getElementById("sub_categories_id").innerHTML = `<option value="" selected>Choose item's type</option>${options}`;
            });

        }
    </script>



<div class="display_div container" id="display_div" name="">

    <select name="sub_categories_id" id="sub_categories_id" class="custom-select mb-3 mt-3"
        onchange="selector('display_div', this)">
        <option value="" selected>Choose item's type</option>
    </select>

</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM