Field Slider
PandaPanel\Forms\Components\Slider adalah field angka yang dipilih dengan cara digeser. Gunakan field ini ketika angka memiliki batas yang jelas dan user lebih membutuhkan posisi relatif daripada digit yang sangat presisi — misalnya persentase, bobot, atau prioritas. Jika nilai pasti lebih penting, gunakan NumberInput, yang mendukung input keyboard.
Form minimal
<?php
declare(strict_types=1);
namespace App\Panels\Admin\Resources\Products\Forms;
use PandaPanel\Forms\Components\Slider;
use PandaPanel\Forms\FormSchema;
final class ProductForm
{
public static function configure(FormSchema $schema): FormSchema
{
return $schema->schema([
Slider::make('discount')
->label('Discount (%)')
->range(0, 50, 5)
->default(0),
]);
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Konfigurasi ini merender range input dari 0 sampai 50 dengan interval 5, menampilkan nilai saat ini di samping slider, dan memvalidasi discount sebagai nullable|numeric|min:0|max:50.
Batas slider sekaligus menjadi validation rule
Slider yang secara visual tidak dapat digeser melewati 100 tetapi menerima value 1000 dari crafted request hanyalah control yang berpura-pura menjadi constraint. Karena itu range() melakukan dua hal sekaligus: mengatur control dan menghasilkan validation rules.
Slider::make('weight')->range(10, 20, 5);// FormSchema::make()->schema([...])->validationRules()
['weight' => ['nullable', 'numeric', 'min:10', 'max:20']]2
Browser menerima hint numeric, min, dan max dari deklarasi yang sama, sehingga UI dan validation tidak dapat drift menjadi dua aturan berbeda. Server tetap melakukan validasi ulang terhadap request.
Method
range(float $min, float $max, float $step = 1): self
Mengatur ketiga nilai sekaligus. Default: min: 0, max: 100, step: 1.
use PandaPanel\Forms\Components\Slider;
Slider::make('opacity')->range(0, 1, 0.05);
Slider::make('priority')->range(1, 5); // step stays 1
Slider::make('score')->range(-100, 100, 10);2
3
4
5
6
7
step bernilai nol atau negatif ditolak dan diubah kembali menjadi 1, karena range input dengan step nol tidak memiliki posisi valid untuk berhenti.
Tidak ada method min(), max(), atau step() terpisah. Ketiganya memang hanya bermakna sebagai satu konfigurasi range, dan satu baris deklarasi jauh lebih mudah diaudit daripada range yang dirakit dari tiga tempat berbeda.
showValue(bool $show = true): self
Default true. Menentukan apakah value saat ini ditampilkan di samping track.
Slider::make('volume')->range(0, 11)->showValue(false);Matikan ketika label/posisi sudah cukup menjelaskan arti value — misalnya priority lima tingkat di mana posisi lebih penting daripada angka.
type(): FieldType
Mengembalikan FieldType::Slider, yang diserialisasi menjadi 'slider' dan memilih SliderField.vue.
Bentuk serialized payload
Slider::make('discount')->range(0, 50, 5)->toArray(null, 'create') menambahkan empat key ke payload dasar field:
| Key | Type | Default | Sumber |
|---|---|---|---|
min | number | 0 | range() |
max | number | 100 | range() |
step | number | 1 | range() |
showValue | boolean | true | showValue() |
Value dinormalisasi oleh castForForm(): numeric value dikembalikan sebagai number ($value + 0, sehingga "7" menjadi 7 dan "7.5" menjadi 7.5), sedangkan value lain menjadi null.
Memberikan nilai awal
default() diwarisi dari Field dan default-nya null. Default hanya berlaku ketika tidak ada record:
Slider::make('discount')->range(0, 50, 5)->default(10);Pada edit Page, value berasal dari record. Jika column bernilai null dan Anda ingin control dimulai dari nilai tertentu, ubah nilai saat hydration menggunakan formatUsing(), bukan default():
use Illuminate\Database\Eloquent\Model;
Slider::make('discount')
->range(0, 50, 5)
->formatUsing(static fn (mixed $value, ?Model $record): float => is_numeric($value)
? (float) $value
: 0.0);2
3
4
5
6
7
Membuat slider wajib diisi
Slider::make('rating')->range(1, 5)->required();required() mengganti nullable menjadi required dan menandai label. Baca gotcha pertama sebelum menggunakannya: range input tidak memiliki state visual kosong, sehingga "user belum pernah menyentuh slider" bukan sesuatu yang bisa ditampilkan control.
Hal yang perlu diperhatikan
- Slider yang tidak disentuh mengirim
null, walaupun UI menampilkan nilai minimum. Range input selalu memiliki posisi visual.SliderField.vuemenampilkanminketika value bukan finite number, tetapi component belum mengemit value sampai user menggeser slider. Denganrequired(), user dapat melihat form seolah sudah terisi tetapi mendapat error "The Rating field is required." Berikandefault()atau biarkan optional dan anggapnullsebagai unset. stepadalah bantuan control, bukan validation rule.range(0, 100, 25)membuat thumb berhenti di 0, 25, 50, 75, 100, tetapi rule hanyanumeric|min:0|max:100. Request dengan value37tetap valid. Jika posisi discrete memang constraint, tambahkan->rules(['in:0,25,50,75,100']), atau gunakan field dengan whitelist sepertiRadioatauPandaPanel\Forms\Components\ToggleButtons.range()tidak memeriksa apakahminlebih kecil darimax. Range terbalik menghasilkanmin:20|max:10, yang tidak dapat dipenuhi value apa pun, dan control tidak memiliki posisi valid. Hanyastepyang dijaga karena zero step benar-benar merusak control.- Stored type mengikuti value yang masuk. Field memvalidasi
numerictetapi mempersist value tanpa mengubah type kecuali hook melakukannya. Cast attribute di model, misalnya'discount' => 'float'atau'integer', daripada berharap field menentukan tipe penyimpanan. mindanmaxberarti batas value, bukan panjang. Shared browser check mengikuti Laravel: number diukur berdasarkan value, string berdasarkan length, dan collection berdasarkan count. Karena Slider juga mengirim hintnumeric, numeric string diperlakukan sebagai angka. Server menerapkan semantik yang sama.