Number
PandaPanel\Forms\Components\NumberInput adalah numeric input yang bounds-nya sekaligus menjadi validation rules. Gunakan field ini ketika sebuah column menyimpan angka yang diketik user — misalnya harga, quantity, atau berat. Jika angka dipilih dari suatu rentang dengan cara digeser, gunakan Slider.
Contoh minimal
use PandaPanel\Forms\Components\NumberInput;
use PandaPanel\Forms\FormSchema;
FormSchema::make()->schema([
NumberInput::make('quantity')
->integer()
->min(1)
->max(999)
->required(),
]);2
3
4
5
6
7
8
9
10
Method
public function integer(bool $integer = true): self // default: false
public function min(int|float|null $min): self // default: null
public function max(int|float|null $max): self // default: null
public function step(int|float|null $step): self // default: null2
3
4
| Method | Default | Rule yang ditambahkan | Attribute yang diatur |
|---|---|---|---|
integer() | false | integer menggantikan numeric | —, tetapi juga menentukan default step |
min() | null | min:n | min pada input |
max() | null | max:n | max pada input |
step() | null | tidak ada | step pada input |
use PandaPanel\Forms\Components\NumberInput;
NumberInput::make('price')
->label('Price (EUR)')
->min(0)
->max(100_000)
->step(0.01)
->placeholder('0.00')
->helperText('Excluding tax.');2
3
4
5
6
7
8
9
min(), max(), dan step() menerima null untuk menghapus value yang sudah pernah diset. integer() menggunakan boolean.
step() dan default-nya
step tidak pernah menjadi validation rule. Ini hanya browser affordance yang menentukan perubahan spinner dan native validity check. Yang diserialisasi adalah:
'step' => $this->step ?? ($this->integer ? 1 : null),Jadi field dengan integer() otomatis menggunakan step satu. Decimal field tidak memiliki step default; artinya step="1" tidak dipaksakan dan browser dapat menerima decimal. Gunakan step(0.01) untuk uang atau step(0.5) untuk setengah unit.
Validasi
use PandaPanel\Forms\Components\NumberInput;
use PandaPanel\Forms\FormSchema;
FormSchema::make()
->schema([
NumberInput::make('quantity')->integer()->min(1)->max(99)->required(),
NumberInput::make('weight')->min(0.5),
])
->validationRules();
// [
// 'quantity' => ['required', 'integer', 'min:1', 'max:99'],
// 'weight' => ['nullable', 'numeric', 'min:0.5'],
// ]2
3
4
5
6
7
8
9
10
11
12
13
14
Pada value numeric, min: dan max: membandingkan besar nilainya, bukan panjang digit. Behavior tersebut ditentukan oleh rule numeric atau integer. Ini adalah kesalahan Laravel yang cukup umum, sehingga type rule selalu ditempatkan lebih dulu dalam daftar.
Browser menerima bounds yang sama dalam dua bentuk: attribute min/max pada input dan hint validation yang diperiksa validateFields() sebelum submit.
use PandaPanel\Forms\Components\NumberInput;
NumberInput::make('quantity')->integer()->min(1)->max(99)->toArray(null, 'create')['validation'];
// ['required' => false, 'numeric' => true, 'min' => 1.0, 'max' => 99.0]2
3
4
Hint numeric digunakan baik untuk rule numeric maupun integer; browser tidak dapat membedakan keduanya dengan jaminan yang sama seperti server. Validation sebenarnya tetap dilakukan server.
Hydration
protected function castForForm(mixed $value): int|float|nullImplementasinya setara dengan is_numeric($value) ? $value + 0 : null. Operasi + 0 membuat column decimal yang mengembalikan string '19.99' menjadi float 19.99, sedangkan integer tetap menjadi int. Nilai non-numeric, termasuk '', menjadi null.
use PandaPanel\Forms\Components\NumberInput;
NumberInput::make('price')->formValue($record); // 19.99, 42, or null2
3
Control mengikuti behavior yang sama: input kosong mengirim null, bukan '', sehingga optional number dapat dibersihkan dengan benar ke nullable column.
Resep penggunaan
Uang. Simpan cents pada integer column, tetapi tampilkan unit utama:
use Illuminate\Database\Eloquent\Model;
use PandaPanel\Forms\Components\NumberInput;
NumberInput::make('price')
->label('Price')
->min(0)
->step(0.01)
->formatUsing(static fn (mixed $value, ?Model $record): ?float => is_numeric($value)
? ((int) $value) / 100
: null)
->mutateUsing(static fn (mixed $value, ?Model $record): ?int => is_numeric($value)
? (int) round(((float) $value) * 100)
: null);2
3
4
5
6
7
8
9
10
11
12
13
Bound bergantung pada field lain. min() hanya menerima angka. Cross-field constraint sebaiknya berada di rules(), tempat Laravel dapat merujuk field lain:
use PandaPanel\Forms\Components\NumberInput;
NumberInput::make('min_quantity')->integer()->min(1),
NumberInput::make('max_quantity')->integer()->rules(['gte:min_quantity']),2
3
4
Mengendalikan condition. GreaterThan dan LessThan melakukan perbandingan numeric di kedua sisi wire:
use PandaPanel\Forms\Components\NumberInput;
use PandaPanel\Forms\Components\Textarea;
use PandaPanel\Forms\Enums\ConditionOperator;
NumberInput::make('discount')->integer()->min(0)->max(100),
Textarea::make('discount_reason')
->visibleWhen('discount', ConditionOperator::GreaterThan, 0),2
3
4
5
6
7
Data yang dikirim ke frontend
interface NumberFieldDefinition extends BaseFieldDefinition {
type: 'number';
min: number | null;
max: number | null;
step: number | null;
}2
3
4
5
6
Hal yang perlu diperhatikan
min() dan max() membatasi value, bukan jumlah digit. Karena type rule adalah numeric atau integer, Laravel membandingkan magnitude. Gunakan regex atau digits jika ingin membatasi jumlah digit.
integer() menolak decimal. Rule integer bukan cast; 19.5 gagal validation dan tidak dibulatkan. Jika memang ingin membulatkan, lakukan eksplisit melalui mutateUsing().
step bukan server rule. step(0.01) membuat spinner bergerak per cent dan browser menandai 19.999 invalid, tetapi server tetap dapat menerimanya. Tambahkan ->rules(['decimal:0,2']) jika precision wajib dibatasi.
Integer sangat besar kehilangan presisi pada wire. Value menjadi JSON number dan dibaca sebagai JavaScript number, yaitu double. Angka di atas 2^53 sebaiknya menggunakan TextInput dengan numeric rule, bukan NumberInput.
Input kosong menjadi null, dan nullable mengizinkannya. Angka wajib tetap membutuhkan required(). min(1) saja tidak membuat null menjadi invalid karena rule min dilewati untuk null.
Lihat juga
- Slider — bounded number yang dipilih dengan drag
- Text — untuk angka yang sebenarnya identifier
- Date and Time — bounded scalar lainnya
- Validation
- Visibility —
GreaterThandanLessThan - Forms and Schemas