Skip to main content

Overview

The NumberRangeFilter class provides two numeric inputs for filtering by a minimum and maximum value range. Values are automatically clamped to the specified bounds.

Creating a NumberRangeFilter

make
static method
required
Creates a new NumberRangeFilter instance.
field
string
required
The database column name to filter on
NumberRangeFilter::make('price')

Available Methods

label

label
method
Sets the display label for the filter.
label
string
required
The label text to display
NumberRangeFilter::make('price')
    ->label('Price Range')

min

min
method
Sets the minimum allowed value for both inputs.
min
float
required
Minimum value constraint
NumberRangeFilter::make('price')
    ->min(0)

max

max
method
Sets the maximum allowed value for both inputs.
max
float
required
Maximum value constraint
NumberRangeFilter::make('price')
    ->max(10000)

step

step
method
Sets the increment/decrement step for both inputs.
step
float
required
Step value
NumberRangeFilter::make('price')
    ->step(0.01)

key

key
method
Overrides the internal key used for the filter.
key
string
required
Custom key identifier
NumberRangeFilter::make('product.price')
    ->key('product_price_range')

default

default
method
Sets a default range value for the filter.
value
mixed
required
The default value (array with ‘min’ and/or ‘max’ keys)
NumberRangeFilter::make('price')
    ->default(['min' => 10, 'max' => 100])

initialValue

initialValue
method
Sets an initial range value that is pre-applied when the table first loads.
value
mixed
required
The initial value (array with ‘min’ and/or ‘max’ keys)
NumberRangeFilter::make('age')
    ->initialValue(['min' => 18, 'max' => 65])

filter

filter
method
Provides a custom query callback to override the default filter behavior.
callback
Closure
required
A closure that receives Builder $query and mixed $value (array with ‘min’ and ‘max’ keys) and returns the modified Builder
NumberRangeFilter::make('discount')
    ->label('Discount Range')
    ->filter(function (Builder $query, mixed $value) {
        if (isset($value['min']) && $value['min'] !== '') {
            $query->where('discount_percent', '>=', $value['min']);
        }
        if (isset($value['max']) && $value['max'] !== '') {
            $query->where('discount_percent', '<=', $value['max']);
        }
        return $query;
    })

groupClass / labelClass / inputClass

groupClass
method
Sets CSS classes for the filter wrapper, label, or input elements.
NumberRangeFilter::make('price')
    ->groupClass('col-md-6')
    ->labelClass('font-semibold')
    ->inputClass('form-control-sm')

Value Structure

The filter value is an array with min and max keys:
[
    'min' => 10.00,
    'max' => 99.99,
]
Either key can be omitted or empty, allowing for open-ended ranges:
['min' => 50]        // Only minimum filter
['max' => 100]       // Only maximum filter
['min' => '', 'max' => '']  // No filter applied

Value Clamping

Both min and max values are automatically clamped to stay within the bounds:
NumberRangeFilter::make('price')
    ->min(0)
    ->max(1000)
If a user enters min: -10 and max: 1500, they will be clamped to 0 and 1000 respectively.

Default Behavior

By default, NumberRangeFilter applies >= and <= queries:
if ($value['min'] !== null && $value['min'] !== '') {
    $query->where($fieldName, '>=', (float) $value['min']);
}

if ($value['max'] !== null && $value['max'] !== '') {
    $query->where($fieldName, '<=', (float) $value['max']);
}

Complete Examples

Basic Usage

use Livewire\Tables\Filters\NumberRangeFilter;

public function filters(): array
{
    return [
        NumberRangeFilter::make('price')
            ->label('Price Range')
            ->min(0)
            ->max(10000)
            ->step(0.01),

        NumberRangeFilter::make('age')
            ->label('Age Range')
            ->min(18)
            ->max(100)
            ->step(1),

        NumberRangeFilter::make('discount')
            ->label('Discount %')
            ->min(0)
            ->max(100)
            ->step(5)
            ->initialValue(['min' => 10, 'max' => 50]),
    ];
}

Custom Filter Logic

use Livewire\Tables\Filters\NumberRangeFilter;
use Illuminate\Database\Eloquent\Builder;

public function filters(): array
{
    return [
        NumberRangeFilter::make('quantity')
            ->label('Stock Quantity')
            ->min(0)
            ->step(1)
            ->filter(function (Builder $query, mixed $value) {
                if (isset($value['min']) && $value['min'] !== '') {
                    $query->where('stock_quantity', '>=', $value['min']);
                }
                if (isset($value['max']) && $value['max'] !== '') {
                    $query->where('stock_quantity', '<=', $value['max']);
                }
                return $query;
            }),

        NumberRangeFilter::make('rating')
            ->label('Rating Range')
            ->min(0)
            ->max(5)
            ->step(0.5)
            ->filter(function (Builder $query, mixed $value) {
                if (isset($value['min']) && $value['min'] !== '') {
                    $query->where('average_rating', '>=', $value['min']);
                }
                if (isset($value['max']) && $value['max'] !== '') {
                    $query->where('average_rating', '<=', $value['max']);
                }
                return $query;
            }),
    ];
}

Usage in Table Component

use App\Models\Product;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Tables\Filters\NumberRangeFilter;
use Livewire\Tables\Filters\SelectFilter;
use Livewire\Tables\Livewire\DataTableComponent;

class ProductsTable extends DataTableComponent
{
    public function query(): Builder
    {
        return Product::query();
    }

    public function filters(): array
    {
        return [
            NumberRangeFilter::make('price')
                ->label('Price Range')
                ->min(0)
                ->max(10000)
                ->step(0.01),

            NumberRangeFilter::make('quantity')
                ->label('Stock Range')
                ->min(0)
                ->step(1),

            SelectFilter::make('category_id')
                ->label('Category')
                ->setOptions(Category::pluck('name', 'id')->toArray()),
        ];
    }
}

UI Rendering

The filter renders two numeric inputs side by side:
  • Min input for the minimum value
  • Max input for the maximum value
The exact appearance depends on your theme (Tailwind, Bootstrap 5, or Bootstrap 4).

Decimal Precision

For currency or decimal ranges, use the step() method:
NumberRangeFilter::make('price')
    ->label('Price Range')
    ->min(0)
    ->step(0.01)  // Allows cents

Build docs developers (and LLMs) love