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

theUnforgiven's avatar

Product_Options Schema:

CREATE TABLE `product_options` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `size` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `colour` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `stock` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=410 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Products Schema

CREATE TABLE `products` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `seo_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `seo_description` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `content` text COLLATE utf8_unicode_ci NOT NULL,
  `image` text COLLATE utf8_unicode_ci NOT NULL,
  `status` int(11) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `slug` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `orig_image` text COLLATE utf8_unicode_ci,
  `image2` text COLLATE utf8_unicode_ci,
  `image3` text COLLATE utf8_unicode_ci,
  `orig_image2` text COLLATE utf8_unicode_ci,
  `orig_image3` text COLLATE utf8_unicode_ci,
  `price` float(10,2) DEFAULT NULL,
  `category_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=194 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
theUnforgiven's avatar

this image shows one item that is just black with various sizes and stock so only need to show black then the sizes that have stock.

In other cases like this screenshot

There is different colours as well as different size and stock again, so the first colour dropdown need to just show the colour once

Black Green

or if its just BLack then Show Black etc

Does this all make sense?

RachidLaasri's avatar

This is really simple stuffs, i suggest you get it to work with simple PHP codes, and then move it to Laravel.

theUnforgiven's avatar

I've kinda got it working now, like so:

//JS
$('#category').on('change', function(e){
         console.log(e);

         var cat_id = e.target.value;

         //ajax
         $.get('/related-sizes?cat_id=' + cat_id, function(data){
            console.log(data);
             $('#subcategory').empty();
             $.each(data, function(index, subcatObj){
                $('#subcategory').append('<option value="'+subcatObj.id+'">'+subcatObj.id+'</option>');
                 console.log(subcatObj);
             });
         });
     })

//View:
 {{ Form::open(['url' => 'add_to_cart']) }}
                    <div class="product-details">
                        @if($item->availableColours())
                            Colour:
                            <select name="colour" id="category">
                                @foreach($selects as $colour)
                                    <option value="{{ $colour->id }}">{{ $colour->colour }}</option>
                                @endforeach
                            </select>
                        @endif
                            Size:
                            <select name="size" id="subcategory">
                                <option value="">---</option>
                            </select>
                    </div>
{{ Form::close() }}

//Controller method:
public function selectedColour()
    {
        $id = Input::get('colour');
        $cat = Options::where('id', '=', $id)->get();

        return Response::json($cat, 200);
    }


//Route:
Route::get('related-sizes', ['as' => 'related-sizes', 'uses' => 'FrontController@selectedColour']);

But upon selecting the colour nothing is returned to the size select

RachidLaasri's avatar

Open this link on your browser, does it show the correct data? Just to make sure that the problem is on your JS

/related-sizes?cat_id=

RachidLaasri's avatar

the problem is here

public function selectedColour()
    {
        $id = Input::get('colour');
        $cat = Options::where('id', '=', $id)->get();

        return Response::json($cat, 200);
    }

the URL you requesting has a queryString name cat_id, so change the above code to

public function selectedColour()
    {
        $id = Input::get('cat_id');
        $cat = Options::where('id', '=', $id)->get();

        return Response::json($cat, 200);
    }
theUnforgiven's avatar

Right so that returns [{"id":"6","product_id":"52","size":"20","colour":"blue","stock":"2","category_id":"1"}]

When i do /related-sizes?cat_id=6

So how do i pass the size to the $('#subcategory').append('<option value="'+subcatObj.id+'">'+subcatObj.id+'</option>'); part? would that be subcatOdj.size ?

RachidLaasri's avatar
$('#category').on('change', function(e){
         console.log(e);

         var cat_id = e.target.value;

         //ajax
         $.get('/related-sizes?cat_id=' + cat_id, function(data){
            console.log(data);
             $('#subcategory').empty();
             $.each(data, function(index, subcatObj){
                $('#subcategory').append('<option value="'+subcatObj.id+'">'+subcatObj.size+'</option>');
                 console.log(subcatObj);
             });
         });
     })
RachidLaasri's avatar

Yes, that's what the code does, load the sizes, if you want to load the colors too, do the same.

repeat the JS code and add another route.

JS :

$('#subcategory').on('change', function(e){

         var cat_id = e.target.value;

         //ajax
         $.get('/related-colors?size_id=' + cat_id, function(data){
            console.log(data);
             $.each(data, function(index, subcatObj){

                $('#colors').append('<option value="'+subcatObj.id+'">'+subcatObj.color+'</option>');


             });
         });
})

Route:

Route::get('related-colors', ['as' => 'related-colors', 'uses' => 'FrontController@selectedColour']);

Note : rename the method above to relatedsizes because that what it does.

selectedColour method :

$id = Input::get('size_id');
$colors = Options::where('size', $id)->get(['id', 'colour']);

return Response::json($colors, 200);

HTML :

<select name="colors" id="colors">
    <option value="">---</option>
</select>
theUnforgiven's avatar

I mean nothing is displaying in the size select menu? It's blank

RachidLaasri's avatar

You mixed things, for the sizes use this

public function selectedSizes()
    {
        $id = Input::get('cat_id');
        $cat = Options::where('id', '=', $id)->get();

        return Response::json($cat, 200);
    }

for colors use this :

public function selectedColour()
{
    $id = Input::get('size_id');
    $colors = Options::where('size', $id)->get(['id', 'colour']);

    return Response::json($colors, 200);
}

change your routes to matches these methods names.

theUnforgiven's avatar

But the url is only $.get('/related-sizes?cat_id=' + cat_id, function(data){ } so do i really need the second function?

theUnforgiven's avatar

basically i should selected a colour then the size select should populate with the correct size based in the cat_id

RachidLaasri's avatar

the first method to get the sizes from a category and the second for getting the colors based on the selected size.

RachidLaasri's avatar

Select the size and then the color, that's all what you need?

theUnforgiven's avatar

well select color first then size, so i need these two methods then?

RachidLaasri's avatar

No, only one, forget about everything else and use this :

JS :

$('#category').on('change', function(e){

     var cat_id = e.target.value;

     //ajax
     $.get('/related-colors?size_id=' + cat_id, function(data){
        console.log(data);
         $.each(data, function(index, subcatObj){

            $('#colors').append('<option value="'+subcatObj.id+'">'+subcatObj.color+'</option>');


         });
     });
})

HTML :

<select name="colour" id="category">
    @foreach($selects as $colour)
        <option value="{{ $colour->id }}">{{ $colour->colour }}</option>
    @endforeach
</select>


<select name="size" id="colors">
    <option value="">---</option>
</select>

Route :

Route::get('related-colors', ['as' => 'related-colors', 'uses' => 'FrontController@selectedColour']);

selectedColour Methode :

public function selectedColour()
{
    $id = Input::get('cat_id');
    $cat = Options::where('id', '=', $id)->get(['id', 'color']);

    return Response::json($cat, 200);
}
RachidLaasri's avatar

JS :

$('#category').on('change', function(e){

     var cat_id = e.target.value;

     //ajax
     $.get('/related-sizes?color=' + cat_id, function(data){

         $.each(data, function(index, subcatObj){

            $('#sizes').append('<option value="'+subcatObj.id+'">'+subcatObj.size+'</option>');


         });
     });
})

HTML :

<select name="colour" id="category">
    @foreach($selects as $colour)
        <option value="{{ $colour->id }}">{{ $colour->colour }}</option>
    @endforeach
</select>


<select name="size" id="sizes">
    <option value="">---</option>
</select>

Route :

Route::get('related-sizes', ['as' => 'related-sizes', 'uses' => 'FrontController@selectedColour']);

selectedColour Methode :

public function selectedColour()
{
    $color= Input::get('color');

    $cat = Options::where('color', '=', $color)->get(['id', 'size']);

    return Response::json($cat, 200);
}
RachidLaasri's avatar
$('#category').on('change', function(e){

     var cat_id = e.target.value;

     //ajax
     $.get('/related-sizes?color=' + cat_id, function(data){

         $.each(data, function(index, subcatObj){

            $('#sizes').append('<option value="'+subcatObj.size+'">'+subcatObj.size+'</option>');


         });
     });
})

public function selectedColour() { $color = Input::get('color');

$cat = Options::where('color', $color)->get(['id', 'size']);

return Response::json($cat, 200);

}

```

Please or to participate in this conversation.