DomainFlag
DomainFlag

Reputation: 564

Update options select attributes according to the other select tag with the help of Ajax and Laravel?

I have the select tag and a series of options select attributes with their values and inner text stored in the database.

This is the way I am displaying the data on view, by calling a foreach for each select tag, 2 in total:

{!! Form::label('category_id', 'Category:') !!}
<select class="form-control category_id" name="category_id">
    @foreach($categories as $category)
        <option value='{{ $category->id }}'> {{ $category->name }}</option>
    @endforeach
</select>

{!! Form::label('subcategory_id', 'Subcategory:') !!}
<select class="form-control" name="subcategory_id" label="Subcategory">
    @foreach($subcategories as $subcategory)
        <option value='{{ $subcategory->id }}'> {{ $subcategory->name }}</option>
    @endforeach
</select>

The problem, is that I am stuck with the following idea: The category and the subcategory are in one to many relationship, that means that when the user clicks a certain category, the select subcategory should be populated only with the values linked to the category chosen.

How can I find a solution to this problem, I am thinking about creating an ajax request but I can't figure how to populate the option select attributes. Or create a JSON (all the work on front-end) variable to store the subcategories and just update the select tag accordingly to what category user chose.

Any help will be greatly appreciated.

SOLUTION:

VIEW:

{!! Form::label('category_id', 'Category:') !!}
<select class="form-control" id="categories" name="category_id">
    @foreach($categories as $category)
        <option value='{{ $category->id }}'> {{ $category->name }}</option>
    @endforeach
</select>

<div id="displayCategories" style="display:none">
    {!! Form::label('subcategory_id', 'Subcategory:') !!}
    <select class="form-control" id="subcategories" name="subcategory_id" label="Subcategory">
        @foreach($subcategories as $subcategory)
            <option value='{{ $subcategory->id }}'> {{ $subcategory->name }}</option>
        @endforeach
    </select>
</div>

JS & JQUERY & AJAX:

<script
 src="https://code.jquery.com/jquery-3.1.1.js"
 integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
 crossorigin="anonymous"></script>

<script>
$('#categories').on('change',function(e) {
    var cat_id = e.target.value;
    //ajax
    $.ajax({
        url: '../ajax-subcat/{cat_id}', //note:that the path can be different for different purpose used, in a simple page -> '/ajax-subcat/{cat_id}' so use the console of your browser
        type: 'GET',
        data: {cat_id : cat_id},
        success: function(response)
        {
            $('#subcategories').empty();
            $('#displayCategories').show();
            $.each(response, function(index, subcatObj) {
                $('#subcategories').append('<option value="' + subcatObj.id + '">' + subcatObj.name + '</option>');
                console.log(subcatObj);
            });
        }
    });
});
</script>

ROUTE:

Route::get('ajax-subcat/{cat_id}', 'PostController@getAjax');

CONTROLLER:

public function getAjax() 
{
   $cat_id = Input::get('cat_id');
   $subcategories = Subcategory::where('category_id', '=', $cat_id)->get();
   return Response::json($subcategories);
}

Don't forget to introduce in the controller the corresponding models, facades for Input and Response. In my case:

use Illuminate\Support\Facades\Input;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use App\Category;
use App\Subcategory;

Upvotes: 0

Views: 241

Answers (1)

Flyingearl
Flyingearl

Reputation: 679

You don't mention the version of Laravel you using so the implementation maybe slightly different. You can do it via the ajax method. You could look into Axios for the frontend calls but you will need to setup event listeners on the select element for when the user makes a new selection.

Upvotes: 2

Related Questions