Skip to content
全部文档

滑块

简介

滑块组件允许你在轨道上拖动手柄,以选择一个或多个数值:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
滑块滑块

该组件使用 noUiSlider 包,其大部分 API 均基于该库。

WARNING

就其本质而言,滑块字段永远不能为空。字段值永远不能是 null 或空数组。若滑块字段为空,用户将没有可在轨道上拖动的手柄。

因此,滑块字段开箱即有默认值,该值设为滑块 范围 内允许的最小值。当表单为空时会使用该默认值,例如资源的创建(Create)页面。要了解更多关于默认值的信息,请参阅 default() 文档

控制滑块的范围

默认情况下,滑块可选的最小值与最大值分别为 0 和 100。Filament 会自动应用验证规则,确保用户无法超出这些值。你可以用 range() 方法调整它们:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 40, maxValue: 80)

TIP

除了接受静态值,range() 方法也接受函数以动态计算这些值。你可以将各种工具(utilities)作为参数注入到函数中。

自定义范围的滑块自定义范围的滑块

控制步长

默认情况下,用户可在最小值与最大值之间选择任意小数值。你可以使用 step() 方法将可选值限制为特定步长。Filament 会自动应用验证规则,确保用户无法偏离该步长:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->step(10)

TIP

除了接受静态值,step() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

限制小数位数

若你更希望允许用户在最小值与最大值之间选择任意小数值,而不是将其限制为某一固定步长,可以使用 decimalPlaces() 方法定义所选值将四舍五入到的小数位数:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->decimalPlaces(2)

TIP

除了接受静态值,decimalPlaces() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

控制轨道的行为内边距

默认情况下,用户可在整条轨道上选择任意值。你可以使用 rangePadding() 方法为轨道添加行为内边距。这将确保所选值始终与轨道边缘至少保持一定距离。Filament 默认应用于滑块的最小值与最大值验证会将该内边距纳入考量,确保用户无法超出加了内边距后的范围:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->rangePadding(10)

TIP

除了接受静态值,rangePadding() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

带范围内边距的滑块带范围内边距的滑块

在此示例中,尽管最小值为 0、最大值为 100,用户只能选择 10 到 90 之间的值。内边距会应用于轨道两端,因此所选值始终与轨道边缘至少相距 10 个单位。

若希望分别控制轨道两侧的内边距,可以向 rangePadding() 方法传入包含两个值的数组。第一个值应用于轨道起点,第二个值应用于轨道终点:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->rangePadding([10, 20])

从右到左的轨道

默认情况下,轨道按从左到右运作。若用户使用从右到左的区域设置(例如阿拉伯语),轨道会自动按从右到左显示。你也可以使用 rtl() 方法强制轨道按从右到左显示:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->rtl()

可选地,你可以传入一个布尔值,以控制滑块是否应为从右到左:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->rtl(FeatureFlag::active())

TIP

除了接受静态值,rtl() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

从右到左的滑块从右到左的滑块

为滑块添加多个值

若滑块被设为一个值数组,用户即可在允许范围内沿轨道拖动多个手柄。请确保滑块有一个设为值数组的 default(),以便在表单为空时使用:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->default([20, 70])
带多个值的滑块带多个值的滑块

若你使用 Eloquent 保存多个滑块值,应确保为模型属性添加 array 类型转换(cast)

php
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'slider' => 'array',
        ];
    }

    // ...
}

使用垂直轨道

你可以使用 vertical() 方法将滑块显示为垂直轨道而非水平轨道:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->vertical()
垂直滑块垂直滑块

可选地,你可以传入一个布尔值,以控制滑块是否应为垂直:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->vertical(FeatureFlag::active())

TIP

除了接受静态值,vertical() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

从上到下的轨道

默认情况下,垂直轨道按从下到上运作。在 noUiSlider 中,这对应 从右到左行为。要将最小值置于轨道顶部,可以使用 rtl(false) 方法:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->vertical()
    ->rtl(false)
从上到下的垂直滑块从上到下的垂直滑块

为手柄添加工具提示

你可以使用 tooltips() 方法为滑块手柄添加工具提示。工具提示会显示手柄的当前值:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->tooltips()
带工具提示的滑块带工具提示的滑块

可选地,你可以传入一个布尔值,以控制滑块是否应显示工具提示:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->tooltips(FeatureFlag::active())

使用多个手柄时,会显示多个工具提示,每个手柄各一个。工具提示也适用于 垂直轨道

带工具提示的垂直滑块带工具提示的垂直滑块

自定义工具提示格式

你可以使用 JavaScript 自定义工具提示的格式。向 tooltips() 方法传入一个包含 JavaScript 字符串表达式的 RawJs 对象。待格式化的当前值可在 $value 变量中获取:

php
use Filament\Forms\Components\Slider;
use Filament\Support\RawJs;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->tooltips(RawJs::make(<<<'JS'
        `$${$value.toFixed(2)}`
        JS))
带自定义工具提示格式的滑块带自定义工具提示格式的滑块

分别控制多个手柄的工具提示

若滑块被设为一个值数组,你可以通过向 tooltips() 方法传入值数组,分别控制每个手柄的工具提示。第一个值应用于第一个手柄,第二个值应用于第二个手柄,以此类推:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->tooltips([true, false])
带多个工具提示的滑块带多个工具提示的滑块

用颜色填充轨道

默认情况下,轨道颜色不受其上任何手柄位置的影响。使用单个手柄时,你可以使用 fillTrack() 方法用颜色填充手柄之前的轨道部分:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->fillTrack()
带填充的滑块带填充的滑块

可选地,你可以传入一个布尔值,以控制滑块是否应填充:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->fillTrack(FeatureFlag::active())

TIP

除了接受静态值,fillTrack() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

使用多个手柄时,你必须通过传入 truefalse 值的数组手动指定应填充轨道的哪些部分,每个区段各一个值。值的总数应比手柄数量多一个。第一个值应用于第一个手柄之前的区段,第二个值应用于第一与第二个手柄之间的区段,以此类推:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->fillTrack([false, true, false])
带多段填充的滑块带多段填充的滑块

填充同样适用于 垂直轨道

带填充的垂直滑块带填充的垂直滑块

为轨道添加刻度标记

你可以为轨道添加刻度标记(pips),它们是指示手柄位置的小标记。你可以使用 pips() 方法为轨道添加刻度标记:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips()
带刻度标记的滑块带刻度标记的滑块

存在多个手柄时,刻度标记同样有效:

带多个刻度标记的滑块带多个刻度标记的滑块

你也可以为 垂直轨道 添加刻度标记:

带刻度标记的垂直滑块带刻度标记的垂直滑块

调整刻度标记密度

默认情况下,刻度标记的密度为 10。这意味着轨道上每 10 个单位会显示一个刻度标记。你可以使用 pips() 方法的 density 参数调整该密度:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(density: 5)

TIP

除了接受静态值,density 参数也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

自定义刻度标记密度的滑块自定义刻度标记密度的滑块

自定义刻度标记标签格式

你可以使用 JavaScript 自定义刻度标记标签的格式。向 pipsFormatter() 方法传入一个包含 JavaScript 字符串表达式的 RawJs 对象。待格式化的当前值可在 $value 变量中获取:

php
use Filament\Forms\Components\Slider;
use Filament\Support\RawJs;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips()
    ->pipsFormatter(RawJs::make(<<<'JS'
        `$${$value.toFixed(2)}`
        JS))

TIP

除了接受静态值,pipsFormatter() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

带自定义刻度标记格式的滑块带自定义刻度标记格式的滑块

为轨道步长添加刻度标记标签

若你使用 步长 限制轨道上的移动,可以为每个步长添加刻度标记标签。为此,向 pips() 方法传入 PipsMode::Steps 对象:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->step(10)
    ->pips(PipsMode::Steps)
在步长上带刻度标记的滑块在步长上带刻度标记的滑块

若希望在轨道上再添加不带标签的额外刻度标记,也可以 调整刻度标记密度

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->step(10)
    ->pips(PipsMode::Steps, density: 5)
在步长上带刻度标记且自定义密度的滑块在步长上带刻度标记且自定义密度的滑块

在轨道的百分比位置添加刻度标记标签

若希望在轨道的特定百分比位置添加刻度标记标签,可以向 pips() 方法传入 PipsMode::Positions 对象。百分比位置需在 pipsValues() 方法中以数字数组定义:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(PipsMode::Positions)
    ->pipsValues([0, 25, 50, 75, 100])

TIP

除了接受静态值,pipsValues() 方法也接受函数以动态计算这些值。你可以将各种工具(utilities)作为参数注入到函数中。

在百分比位置带刻度标记的滑块在百分比位置带刻度标记的滑块

密度 仍控制不带标签的刻度标记间距。

在轨道上添加固定数量的刻度标记标签

若希望在轨道上添加固定数量的刻度标记标签,可以向 pips() 方法传入 PipsMode::Count 对象。刻度标记数量需在 pipsValues() 方法中定义:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(PipsMode::Count)
    ->pipsValues(5)

TIP

除了接受静态值,pipsValues() 方法也接受函数以动态计算这些值。你可以将各种工具(utilities)作为参数注入到函数中。

带固定数量刻度标记的滑块带固定数量刻度标记的滑块

密度 仍控制不带标签的刻度标记间距。

在轨道的指定值处添加刻度标记标签

除了定义 百分比位置固定数量 的刻度标记标签,你也可以定义一组用于刻度标记标签的值。为此,向 pips() 方法传入 PipsMode::Values 对象。这些值需在 pipsValues() 方法中以数字数组定义:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(PipsMode::Values)
    ->pipsValues([5, 15, 25, 35, 45, 55, 65, 75, 85, 95])

TIP

除了接受静态值,pipsValues() 方法也接受函数以动态计算这些值。你可以将各种工具(utilities)作为参数注入到函数中。

在指定值处带刻度标记的滑块在指定值处带刻度标记的滑块

密度 仍控制不带标签的刻度标记间距:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(PipsMode::Values, density: 5)
    ->pipsValues([5, 15, 25, 35, 45, 55, 65, 75, 85, 95])
在指定值处带刻度标记且自定义密度的滑块在指定值处带刻度标记且自定义密度的滑块

手动过滤刻度标记

若要对轨道上刻度标记的显示方式有更精细的控制,可以使用 JavaScript 表达式。该表达式应根据刻度标记的外观返回不同数字:

  • 若应显示大刻度标记标签,表达式应返回 `1`。
  • 若应显示小刻度标记标签,表达式应返回 `2`。
  • 若应显示不带标签的刻度标记,表达式应返回 `0`。
  • 若完全不显示刻度标记,表达式应返回 `-1`。

刻度标记的 密度 会控制哪些值会传给 JavaScript 表达式。表达式应使用 $value 变量访问当前刻度标记的值。表达式应定义在 RawJs 对象中并传给 pipsFilter() 方法:

php
use Filament\Forms\Components\Slider;
use Filament\Support\RawJs;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->pips(density: 5)
    ->pipsFilter(RawJs::make(<<<'JS'
        ($value % 50) === 0
            ? 1
            : ($value % 10) === 0
                ? 2
                : ($value % 25) === 0
                    ? 0
                    : -1
        JS))

TIP

除了接受静态值,pipsFilter() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

在此示例中,使用 % 运算符判断刻度标记值的可整除性。表达式对每 50 个单位返回 1,每 10 个单位返回 2,每 25 个单位返回 0,其余值返回 -1

带刻度标记过滤器的滑块带刻度标记过滤器的滑块

设置手柄之间的最小差值

要设置手柄之间的最小距离,可以使用 minDifference() 方法并传入一个数字。这表示两个手柄值之间的实际差值,而非视觉距离:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->minDifference(10)

TIP

除了接受静态值,minDifference() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

WARNING

minDifference() 方法不影响滑块的验证。熟练用户可能通过 JavaScript 操纵滑块值,选择不符合最小差值的值。他们仍无法选择超出滑块范围的值。

设置手柄之间的最大差值

要设置手柄之间的最大距离,可以使用 maxDifference() 方法并传入一个数字。这表示两个手柄值之间的实际差值,而非视觉距离:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->maxDifference(40)

TIP

除了接受静态值,maxDifference() 方法也接受函数以动态计算该值。你可以将各种工具(utilities)作为参数注入到函数中。

WARNING

maxDifference() 方法不影响滑块的验证。熟练用户可能通过 JavaScript 操纵滑块值,选择不符合最大差值的值。他们仍无法选择超出滑块范围的值。

控制滑块的一般行为

滑块的 behavior() 方法允许你传入一个或多个 Behavior 对象以控制滑块行为。可用选项包括:

  • `Behavior::Tap` - 用户点击轨道时,滑块会平滑移动到点击位置。这是默认行为,因此在应用其他行为时,若想保留该行为,也应将其包含在数组中。
  • `Behavior::Drag` - 当轨道上有两个手柄时,用户可拖动轨道以同时移动两个手柄。必须使用 [`fillTrack([false, true, false])`](#filling-a-track-with-color) 方法,以确保用户有可拖动的区域。
  • `Behavior::Drag` 与 `Behavior::Fixed` - 当轨道上有两个手柄时,用户可拖动轨道以同时移动两个手柄,但无法改变它们之间的距离。必须使用 [`fillTrack([false, true, false])`](#filling-a-track-with-color) 方法,以确保用户有可拖动的区域。请注意,手柄之间的距离不会在后端自动验证,因此熟练用户可能通过 JavaScript 操纵滑块值,选择不同距离的值。他们仍无法选择超出滑块范围的值。
  • `Behavior::Unconstrained` - 当轨道上有多个手柄时,它们可以相互越过拖动。[`minDifference()`](#setting-a-minimum-difference-between-handles) 与 [`maxDifference()`](#setting-a-maximum-difference-between-handles) 方法在此行为下无效。
  • `Behavior::SmoothSteps` - 拖动手柄时,它们不会吸附到轨道的 [步长](#controlling-the-step-size)。用户松开手柄后,它会吸附到最近的步长。

例如,要同时使用 Behavior::TapBehavior::DragBehavior::SmoothSteps

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\Behavior;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->behavior([Behavior::Tap, Behavior::Drag, Behavior::SmoothSteps])

要禁用所有行为(包括默认的 Behavior::Tap),可以使用 behavior(null) 方法:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->behavior(null)

非线性轨道

你可以通过在滑块的 nonLinearPoints() 方法中定义百分比点数组,创建某些部分被压缩或拉伸的非线性轨道。数组中每个百分比键应有对应的实际值,用于计算手柄在轨道上的位置。下面的示例配合 刻度标记 演示轨道的非线性行为:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->nonLinearPoints(['20%' => 50, '50%' => 75])
    ->pips()
带非线性轨道的滑块带非线性轨道的滑块

TIP

除了接受静态值,nonLinearPoints() 方法也接受函数以动态计算这些值。你可以将各种工具(utilities)作为参数注入到函数中。

使用非线性轨道时,你还可以控制每个区段的步进。通过为每个百分比点定义包含两个数字的数组,第一个数字用作该百分比位置的实际值,第二个数字用作该区段的步长,直至下一个百分比点为止有效:

php
use Filament\Forms\Components\Slider;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 100)
    ->nonLinearPoints(['20%' => [50, 5], '50%' => [75, 1]])
    ->pips()

WARNING

使用非线性轨道时,某些轨道区段的步长值不影响滑块的验证。熟练用户可能通过 JavaScript 操纵滑块值,选择与轨道步长值不一致的值。他们仍无法选择超出滑块范围的值。

在非线性轨道上使用 刻度标记 时,你可以确保刻度标记标签被四舍五入,并仅显示在轨道上可选的位置。否则,非线性区段的步进可能在不可选位置添加标签。为此,使用 steppedPips() 方法:

php
use Filament\Forms\Components\Slider;
use Filament\Forms\Components\Slider\Enums\PipsMode;

Slider::make('slider')
    ->range(minValue: 0, maxValue: 10000)
    ->nonLinearPoints(['10%' => [500, 500], '50%' => [4000, 1000]])
    ->pips(PipsMode::Positions, density: 4)
    ->pipsValues([0, 25, 50, 75, 100])
    ->steppedPips()