You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel多关联模型表格多条件筛选实现问询

Laravel Product Multi-Condition Filtering Solution

Hey there! Let's get that multi-filter functionality working for your Laravel products. I'll break this down into backend logic, frontend AJAX handling, and a few extra tips to polish things up.

Step 1: Backend Controller Logic

First, we need to handle the filter parameters sent from your frontend dropdowns. We'll use Laravel's whereHas method to check for related records in your categories, colors, and sizes associations (this works perfectly for both one-to-many and many-to-many relationships—adjust the model associations if needed).

1.1 Update Your Product Model Associations

Make sure your Product model has the correct relationships defined. Since you mentioned the model "has collections" of categories/colors/sizes, this is likely a many-to-many setup:

// app/Models/Product.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }

    public function colors()
    {
        return $this->belongsToMany(Color::class);
    }

    public function sizes()
    {
        return $this->belongsToMany(Size::class);
    }
}

1.2 Add Filter Method to Your Controller

Create a method in your ProductController to handle the AJAX request and apply filters:

// app/Http/Controllers/ProductController.php
public function filter()
{
    // Get filter parameters from the request (default to 0 for "All")
    $categoryId = request()->input('category_id', 0);
    $colorId = request()->input('color_id', 0);
    $sizeId = request()->input('size_id', 0);

    // Start with a base Product query
    $products = Product::query();

    // Apply category filter if not "All"
    if ($categoryId != 0) {
        $products->whereHas('categories', function ($query) use ($categoryId) {
            $query->where('id', $categoryId);
        });
    }

    // Apply color filter if not "All"
    if ($colorId != 0) {
        $products->whereHas('colors', function ($query) use ($colorId) {
            $query->where('id', $colorId);
        });
    }

    // Apply size filter if not "All"
    if ($sizeId != 0) {
        $products->whereHas('sizes', function ($query) use ($sizeId) {
            $query->where('id', $sizeId);
        });
    }

    // Fetch filtered products (use paginate() instead of get() if you need pagination)
    $filteredProducts = $products->get();

    // Return results as JSON for the frontend
    return response()->json(['products' => $filteredProducts]);
}

1.3 Add a Route for the Filter

Add this route to your routes/web.php file:

use App\Http\Controllers\ProductController;

Route::get('/products/filter', [ProductController::class, 'filter'])->name('products.filter');

Step 2: Frontend AJAX Handling

Now let's update your jQuery to send filter values to the controller and update the product table dynamically:

$(document).ready(function() {
    // Listen for changes on any of the filter dropdowns
    $('#select-categories, #select-colors, #select-sizes').on('change', function() {
        // Get selected values
        const categoryId = $('#select-categories').val();
        const colorId = $('#select-colors').val();
        const sizeId = $('#select-sizes').val();

        // Send AJAX request to the filter route
        $.ajax({
            url: '{{ route("products.filter") }}',
            method: 'GET',
            data: {
                category_id: categoryId,
                color_id: colorId,
                size_id: sizeId
            },
            success: function(response) {
                // Update your product table with the filtered results
                const tableBody = $('#product-table tbody');
                tableBody.empty();

                // Loop through the products and build table rows
                $.each(response.products, function(index, product) {
                    // Customize this row to match your product table structure
                    const row = `
                        <tr>
                            <td>${product.name}</td>
                            <td>${product.price}</td>
                            <td>${product.categories.map(cat => cat.name).join(', ')}</td>
                            <td>${product.colors.map(col => col.name).join(', ')}</td>
                            <td>${product.sizes.map(size => size.name).join(', ')}</td>
                        </tr>
                    `;
                    tableBody.append(row);
                });
            },
            error: function(xhr) {
                console.error('Error fetching filtered products:', xhr.responseText);
            }
        });
    });
});

Step 3: Keep Filter State on Page Refresh (Optional)

If you want the dropdowns to retain their selected values after a page refresh, update your blade template to set the selected attribute based on the request parameters:

<!-- For Categories dropdown -->
<option value="{{ $category->id }}" {{ request()->input('category_id') == $category->id ? 'selected' : '' }}>
    {{ $category->name }}
</option>

<!-- Repeat the same pattern for Colors and Sizes dropdowns -->
<option value="{{ $color->id }}" {{ request()->input('color_id') == $color->id ? 'selected' : '' }}>
    {{ $color->name }}
</option>

<option value="{{ $size->id }}" {{ request()->input('size_id') == $size->id ? 'selected' : '' }}>
    {{ $size->name }}
</option>

That's it! This setup will let you filter products by any combination of category, color, and size—including "All" options for any of the filters.

内容的提问来源于stack exchange,提问作者Juweyr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:17:36