'dynamic select2 options depending on other select's selected option

I have the following select

   <select class="form-control" id="from-location" name="from-location">
     <option value="1">Inventory 1</option>
     <option value="2">Inventory 2</option>
     <option value="3">Inventory 3</option>
   </select>

Each inventory has products (different, obviously, but same products can be in multiple inventories). I also have a select2 (searchable select) on the same page, and I want to render the products as options DEPENDING on what I choose in the first select. Example: if I select Inventory 2, then the select2 should render the products from Inventory 2, same for the others.

My Ajax request (not done yet because I am stuck):

$('#from-location').on('change', function() {       

    $.ajax({    //create an ajax request to display.php
      type: "GET",
      url: "/inventory_products",             
      dataType: "html",   //expect html to be returned                
      success: function(response){                    
          
      }

  });
});

Route:

Route::get('/inventory-products', array('uses' => 'App\Http\Controllers\LogicForms@inventory_products'));

Controller:

class LogicForms extends Controller
{
    public function inventory_products()
    {
        
    }
}

Tables structure:

inventories: id, name

products: id, name

invoice: id, date, number

invoice_products: id, invoice_id, product_id, quantity, code

product_stocks: id, product_id, inventory_id, invoice_product_id



Solution 1:[1]

I think your AJAX need to pass the inventory id to the controller function and populate the products you receive into the products select2.

$('#from-location').on('change', function() {
    let inventoryId = $(this).val();

    $.ajax({
        type: "GET",
        data: {
            inventory: inventoryId
        },
        url: "/inventory_products",
        success: function(response) {
            $("#products").select2({
                data: response
            });
        }
    });

});

Fetch the inventory in your controller and return the associated products, provided you have a relation established between inventory and products.

App\Models\Inventory.php:

<?php

namespace App\Models;

use App\Models\Product;
use Illuminate\Database\Eloquent\Model;

class Inventory extends Model
{
    public function products()
    {
        return $this->belongsToMany(Product::class, 'product_stocks');
    }
}

App\Models\Product.php:

<?php

namespace App\Models;

use App\Models\Inventory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function inventories()
    {
        return $this->belongsToMany(Inventory::class, 'product_stocks');
    }
}

Controller:

class LogicForms extends Controller
{
    public function inventory_products(Request $request)
    {
        $inventory = Inventory::find($request->inventory);

        $products = $inventory->products;

        $response = collect([]);

        foreach ($products as $product) {
            $response->push([
                'id' => $product->id,
                'text' => $product->name,
            ]);
        }

        return response()->json($response);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1