'Laravel price range filter

I have to search price range(min_price & max_price) from two columns(regular_price & sale_price) but unable to get values from both columns.

I currently have something like this:

My problem is ajax

blade.php

<div class="card mb-3">
    <div class="card-body">
        <p>
            <label for="amount">amount:</label>
            <input type="text" name="amount" id="amount" readonly class="border-0 fw-bold text-warning">
        </p>
        <div id="slider-range"></div>
    </div>
</div>

script.js

<script src="{{ asset('themes/js/jquery-ui.js') }}"></script>
<script>
    $( function() {
        $( "#slider-range" ).slider({
            range: true,
            min: 0,
            max: 500,
            values: [ 75, 300 ],
            slide: function( event, ui ) {
                $( "#amount" ).val( "$" + ui.values[ 0 ] + " - $" + ui.values[ 1 ] );
            }
        });
        $( "#amount" ).val( "$" + $( "#slider-range" ).slider( "values", 0 ) +
            " - $" + $( "#slider-range" ).slider( "values", 1 ) );
        $.ajax({
            method: 'get',
            url: '{{ route('price') }}',
            data: formData,
            success: function (data) {

            }
        });
    });
</script>

web.php

Route::any('/category/{categorySlug}', [App\Http\Controllers\CategoryController::class, 'price'])->name('price');

CategoryController.php

public function price(Category $category, Request $request)
{
    $categories = Category::all();
    $colors = Color::all();
    $brands  = Brand::all();
    $min_price = Product::min('price');
    $max_price = Product::max('price');
    $filter_min_price = $request->min_price;
    $filter_max_price = $request->max_price;
    $range = [$filter_min_price, $filter_max_price];
    $products = Product::query()->whereBetween('price', $range)->get();

    if($filter_min_price && $filter_max_price){
        if($filter_min_price > 0 && $filter_max_price > 0)
        {
            $products = Product::all()->whereBetween('price', [$filter_min_price, $filter_max_price]);
        }
    } else {
        $products = Product::all();
    }
    return view('Home.contents.category',compact('products','categories','min_price','max_price','filter_min_price','filter_max_price', 'category', 'colors', 'brands'));
}


Solution 1:[1]

I removed everything that seems unnecessarry for the core of the question. I extracted filter functionality to a seperate method, but in my project I would put it in a seperate class. I wrote the code here, so it might not work directly, but the logic should be correct.

public function price(Category $category, Request $request)
{
    $products = $this->filterByPrice(
        Product::query(),
        [$request->min_price ?: 0, $request->max_price ?: 0]
    );

    return ...;
}

private function filterByPrice($query, $range)
{
    if (!$range[0] && !$range[1]) return $query->all();
    
    if ($range[0] && !$range[1]) {
        return $query
            ->where('price', '>=', $range[0])
            ->orWhere('sale_price', '>=', $range[0])
            ->all();
    }

    if (!$range[0] && $range[1]) {
        return $query
            ->where('price', '<=', $range[1])
            ->orWhere('sale_price', '<=', $range[1])
            ->all();
    }

    return $query
        ->whereBetween('price', $range)
        ->orWhereBwtween('sale_price', $range)
        ->all();
}

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 Bulent