Checkbox
PandaPanel\Forms\Components\Checkbox adalah field boolean tunggal yang dirender sebagai kotak centang. PandaPanel\Forms\Components\Toggle adalah field yang sama tetapi dirender sebagai switch — class ini extends Checkbox dan tidak mengubah apa pun selain control yang digunakan. Gunakan salah satunya ketika jawabannya hanya ya atau tidak; untuk beberapa jawaban dari sebuah daftar gunakan CheckboxList, dan untuk satu jawaban dari beberapa pilihan gunakan Radio.
Contoh minimal
use PandaPanel\Forms\Components\Checkbox;
use PandaPanel\Forms\Components\Toggle;
use PandaPanel\Forms\FormSchema;
FormSchema::make()->schema([
Checkbox::make('is_featured'),
Toggle::make('is_admin')
->label('Administrator')
->helperText('Administrators can reach the Admin panel and manage users.'),
]);2
3
4
5
6
7
8
9
10
11
Nilai field
Checkbox tidak memiliki opsi khusus field. Yang membuatnya menjadi checkbox adalah beberapa override pada Field:
| Override | Nilai |
|---|---|
type() | FieldType::Checkbox ('checkbox'), atau FieldType::Toggle ('toggle') |
$default | false — bukan null, sehingga form create dimulai dalam keadaan tidak dicentang, bukan kosong |
typeRules() | ['boolean'] |
castForForm() | (bool) $value |
Cast tersebut membuat column tinyint(1), string 0/1, maupun boolean asli selalu sampai ke control sebagai true atau false:
use PandaPanel\Forms\Components\Checkbox;
Checkbox::make('is_featured')->formValue($record); // always bool2
3
Control Vue mengirim value === true, sehingga nilai yang kembali adalah boolean JSON asli, bukan 'on'. Tidak ada konfigurasi khusus untuk nilai unchecked: field tetap hadir di payload baik dicentang maupun tidak.
Semua konfigurasi yang tersedia
Checkbox tidak menambahkan method khusus miliknya sendiri. Berikut method bawaan Field yang paling relevan untuk boolean:
use PandaPanel\Forms\Components\Toggle;
Toggle::make('is_admin')
->label('Administrator') // default: Str::headline('is_admin')
->helperText('Grants access to the Admin panel.')
->default(true) // overrides the field's false
->inlineLabel() // label beside the switch
->columnSpan(2)
->disabled()
->rules(['accepted']); // see Gotchas2
3
4
5
6
7
8
9
10
| Method | Signature | Catatan |
|---|---|---|
label() | (string $label): static | default Str::headline($name) |
helperText() | (string $text): static | teks bantuan di bawah control |
default() | (mixed $default): static | false jika tidak diatur |
disabled() | (bool $disabled = true): static | tetap divalidasi dan tetap di-dehydrate |
inlineLabel() | (bool $inline = true): static | label berada di samping, bukan di atas |
columnSpan() / columnSpanFull() | (int $span): static / (): static | di-resolve terhadap container |
rules() | (list<mixed> $rules): static | ditambahkan setelah rule boolean |
required() | (bool $required = true): static | lihat Gotchas — jarang menjadi pilihan yang tepat |
placeholder() tersedia pada Field, tetapi checkbox tidak memiliki text input untuk menampilkannya; definition tetap membawa nilainya, namun control mengabaikannya.
Memetakan checkbox ke column yang berbeda
Kasus umum adalah timestamp nullable yang ditampilkan sebagai switch. Tiga hook berikut digunakan karena masing-masing menjawab pertanyaan yang berbeda:
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Date;
use PandaPanel\Forms\Components\Toggle;
Toggle::make('verified')
->label('Email verified')
->formatUsing(static fn (mixed $value, ?Model $record): bool => $record instanceof User
&& $record->email_verified_at !== null)
->dehydrateTo('email_verified_at')
->mutateUsing(static function (mixed $value, ?Model $record): mixed {
if ($value !== true) {
return null;
}
return $record instanceof User && $record->email_verified_at !== null
? $record->email_verified_at
: Date::now();
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
formatUsing() membentuk nilai saat masuk ke form, dehydrateTo() menentukan nama column tujuan, dan mutateUsing() membentuk nilai saat keluar dari form. Nama field pada wire dan rules tetap verified; tidak perlu mengganti nama field atau membuat column baru.
Perhatikan bahwa closure formatUsing() mengembalikan boolean, bukan membaca data_get($record, 'verified') — attribute tersebut memang tidak ada. Tanpa hook ini, field akan membaca null dan tampil tidak dicentang meskipun user sebenarnya sudah terverifikasi.
Mengendalikan field lain
Checkbox sangat cocok menjadi sumber declarative condition karena operator default-nya adalah Truthy:
use PandaPanel\Forms\Components\TextInput;
use PandaPanel\Forms\Components\Toggle;
Toggle::make('notify'),
TextInput::make('notify_email')->visibleWhen('notify'),2
3
4
5
Tidak ada request ke server: browser mengevaluasi ulang condition setiap kali switch berubah. Lihat Visibility.
Jika perubahan checkbox mengharuskan server membangun ulang sesuatu — misalnya options yang bergantung pada nilainya atau total hasil komputasi — tandai field sebagai live():
use PandaPanel\Forms\Components\Toggle;
Toggle::make('use_custom_pricing')->live();2
3
Hal yang perlu diperhatikan
required() pada checkbox tidak berarti checkbox harus dicentang. Field::validationRules() menempatkan required di awal, dan rule required Laravel tetap lolos untuk false karena nilainya hadir. Yang berubah secara visual hanya tanda wajib di label. Jika checkbox memang harus dicentang — misalnya persetujuan syarat dan ketentuan — gunakan rule Laravel accepted:
use PandaPanel\Forms\Components\Checkbox;
Checkbox::make('accepts_terms')->rules(['accepted']); // ['nullable', 'boolean', 'accepted']2
3
Default-nya adalah false, bukan null. Form create dimulai tidak dicentang dan mengirim false, sehingga column boolean non-nullable aman walaupun database tidak memiliki default.
Toggle adalah subclass, bukan flag. Toggle::make() mengembalikan instance Toggle; instanceof Checkbox tetap bernilai true. Jika page hook melakukan branching berdasarkan class field, ingat detail ini.
Checkbox bukan final. Bersama TextInput, ini adalah dua field class dalam package yang tidak final, sehingga Toggle dapat meng-extend-nya. Override type() untuk menggunakan control berbeda, tetapi ingat bahwa union frontend bersifat closed — menambah case FieldType baru juga membutuhkan renderer Vue.
Checkbox yang disabled tetap di-dehydrate. Disabled hanyalah state browser. Gunakan dehydrated(false) jika nilainya sama sekali tidak boleh mencapai column.
Lihat juga
- Toggle — field yang sama dalam bentuk switch
- Radio — satu pilihan dari beberapa pilihan
- Visibility —
visibleWhen()dan condition operator - Live Fields —
live()dan form-state endpoint - State Lifecycle —
formatUsing(),mutateUsing(),dehydrateTo() - Validation
- Forms and Schemas