gallo2000sv
gallo2000sv

Reputation: 121

Laravel 5.6: Get selected value from a dropdown to use it in another

6, I'm using a dropdown to read a column from a database table. All I want is to get the selected value on that dropdown and use it to create a new query that will be populated in a new drop-down.

After reading and see several examples I see people using ajax and other people using laravel HTTP request like $request->get() so i don't know which way to take since I'm not familiar with any of those and even when trying several times can't get it to work.

Can anyone give me an insight into the best/efficient way to do it? Is it possible to do it only using php or some feature in laravel that I'm missing?

Here is my controller:

public function selectsector() //this is the dropdown #1 that works fine
{ 
 $sectors = DB::table('Sectors')->whereBetween('SectorID', [1, 10])->value('SectorID');
 return view('besttradesview', ['sectors10' => $sectors]);
} 

public function selectsubsector() //dropdown #2 not working
{
$subsectors = DB::table('Sectors')->where('parentid', $sectors)->get(); 
//this line is not working it does not recognize $sector variable
return view('besttradesview', ['subsectors42' => $subsectors]);
}

View with dropdow #1: sector and #2: subsector

<form method="GET">
<div class="selectsector">
<Select class="selectsector" name = "sector">
@foreach($sectors10 as $sector) 
<option>{{ $sector->SectorName }}</option>
@endforeach
</select>

<Select class="selectsubsector" name = "subsector">
@foreach($subsectors42 as $subsector) 
<option>{{ $subsector->SectorName }}</option>
@endforeach
</select>
</form>

Routes:

Route::get('kitysoftware/besttrades', 'SectorsController@selectsector');
Route::get('kitysoftware/besttrades', 'SectorsController@selectsubsector');

Getting error: Undefined variable: sectors

Upvotes: 1

Views: 16503

Answers (3)

Mohammad Ali Abdullah
Mohammad Ali Abdullah

Reputation: 331

Controller

        public function selectsector() 
        { 
         $sectors = Sector::get();
         return view('besttradesview', compact('sectors'));
        } 
        
    public function selectsubsector($sectors)
        {
          $subsectors = Sectors::where('parentid', $sectors)->get(); 
        if (empty($subsectors)) {
            $html = '';
            $html = '<option value="">There has no Value</option>';
        } else {
            $html = '';
            foreach ($subsectors as $subsector) {
                $html .= '<option value="'.$subsector->id.'">'.$subsector->subsector.'</option>';
            }
        }
        return response()->json(['html' => $html]);       
        }

route

Route::get('/get-selector/{id}', 'Inventory\selectorController@selectsubsector')->name('get.selector');

ajax

$(document).on('change','.selectsector',function () { 
        var id= $(this).val();
        var url = "{{ URL::to('/get-selector') }}"+ '/' + id;
        $.ajax({
                url: url,
                type: 'get',
                dataType:'JSON',
                success: function (response) {
                    console.log(response);
                    if(response.html==''){
                        $('.selectsubsector').html('<option value="">There has no Value</option>');
                    }else{
                        $('.selectsubsector').html(response.html);
                    }   
                },error: function (exception) {
                    console.log(exception);
                }
            });
        });

Upvotes: 0

gallo2000sv
gallo2000sv

Reputation: 121

Ok, i managed to do it using javascript and ajax function with json datatype. I'm new at JavaScript and it took me a while so i'm taking the time to publish the details for the newcomers. Here we go:

The View file: The trick is to use a html hidden object that captures a route + prefix like in this line before the dropdowns:

 <input type="hidden" name="application_url" id="application_url" value="{{URL::to(Request::route()->getPrefix()) }}"/>

The name of this object is "application_url" which we'll be using later in the javascript code to complete the url that the routes needs.
DropDown#1 with name "sectorSelect":

<label class="selectsector">Sector:</label>
<Select class="selectsector" id="sectorSelect" name="sectorSelect" >
    <option value=""> -- Please select sector --</option>
    @foreach ($sectors10 as $sector)
        <option value="{{ $sector->SectorID }}">{{ $sector->SectorName }}</option>
    @endforeach
</select>

DropDown #2 with name: "SubsectorSelect"

 <label class="selectsector">SubSector:</label>
 <Select class="selectsector" id="subSectorSelect" name="subSectorSelect">
    <option value=""> -- Select an option --</option> // you don't have to do nothing here since this will be populated it from a query depending on the dropdown#1 selected value
 </select>

Now in the web.php routes file:

Route::get('kitysoftware/sectors/subsectors/{id}', 'SectorsController@selectsubsector');

We are creating a route with an {id} parameter. This will be the selected value in dropdown #1. Then we call the "selectsubsector" method in the Sectorscontroller.

Controller: First dropdown query:

public function selectsector()
{
$sectors = DB::table('Sectors')->select('SectorName', 'SectorID')- 
 >whereBetween('SectorID', [1, 10])->get();
    return view('besttradesview', ['sectors10' => $sectors]);

Second Dropdown query (selectsubsector method):

   public function selectsubsector($sectorId)
    {

    $subsectors = DB::table('Sectors')->select('SectorName', 'SectorID')->where('parentid', $sectorId)->get();
    return response()->json($subsectors); //this line it's important since we are sending a json data variable that we are gonna use again in the last part of the view.
    }

Final part of the view file The javaScript + ajax function

<script type="text/javascript">
    $('#sectorSelect').change(function () { //we watch and execute the next lines when any value from the dropdown#1 is selected
        var id = $(this).val(); //we get the selected value on dropdown#1 and store it on id variable
        var url = $('#application_url').val(); //we get the url from our hidden element that we used in first line of our view file, and store it on url variable
            //here comes the ajax function part
            $.ajax({
            url: url + "/kitysoftware/sectors/subsectors/" + id, //we use the same url we used in our route file and we are adding the id variable which have the selected value in dropdown#1
            dataType: "json", //we specify that we are going to use json type of data. That's where we sent our query result (from our controller)
            success: function (data) { //*on my understanding using json datatype means that the variable "data" gets the value and that's why we use it to tell what to do since here.*
                //and this final part is where we use the dropdown#1 value and we set the values for the dropdown#2 just adding the variables that we got from our query (in controllert) through "data" variable.
                $('#subSectorSelect').empty();
                $.each(data, function (key, value) {
                    $('#subSectorSelect').append('<option value="' + key.SectorID + '">' + value.SectorName + '</option>');
                });
            }
        });
    });
</script>

Hope it helps the solution and the explanations. I'm happy to get some feedback as well.

Upvotes: 4

Vinesh Goyal
Vinesh Goyal

Reputation: 637

I hope it is your requirement:

<Select class="selectsector" onChange="getSelectorValue( this, '#selector2' )" id="selector1" name="sector">
    @foreach($sectors10 as $sector)
    <option>{{ $sector->SectorName }}</option>
    @endforeach
</select>

<Select class="selectsubsector" onChange="getSelectorValue( this, '#selector1' )" name = "subsector" id="selector2" >
    @foreach($sectors10 as $sector)
    <option>{{ $sector->SectorName }}</option>
    @endforeach
</select>

Add Script to make it work:

<script type="text/javascript">
    function getSelectorValue( selectorObj, selector ){
        document.querySelector( selector ).value = selectorObj.value;
    }
</script>

Upvotes: 2

Related Questions