SemanticForm
Intro
SemanticForm adalah helper untuk membuat form sesuai dengan style Fomantic UI.
Tanpa SemanticForm, tipikal kode yang dibutuhkan untuk membuat sebuah form dengan Laravel, lengkap dengan penanganan Old Input
dan Error
, biasanya seperti ini:
<form class="ui form">
<div class="field {{ $errors->has('name') ? 'error' : '' }}">
<label>Your Fullname</label>
<input type="text" name="name" value="{{ old('name') }}">
</div>
</form>
Dengan SemanticForm, kode di atas bisa disederhanakan menjadi:
{!! form()->open() !!}
{!! form()->text('name')->label('Your Fullname') !!}
{!! form()->close() !!}
Anda bisa fokus pada fungsionalitas form. Urusan struktur (HTML), tampilan (CSS), dan behaviour (JS) sudah ditangani oleh Laravolt.
Fitur
SemanticForm secara otomatis sudah menangani hal-hal berikut ini:
- Styling
- Error state
- Preserve old input, jadi isian tidak hilang ketika terjadi error saat form disubmit
- Model binding, otomatis mengisi form dari Eloquent model
Instalasi
composer require laravolt/semantic-form
💡 Package ini sudah ter-install secara otomatis ketika Anda menginstall Laravolt.
Cara Pemakaian
Gambaran Umum
SemanticForm bisa dipanggil dengan dua cara:
- Melalui Facade Form, misalnya
Form::open()
. - Melalu helper form(), misalnya
form()->open()
.
Pemanggilan melalui fungsi helper form()
lebih direkomendasikan karena mendukung auto completion.
Di bawah ini adalah gambaran umum untuk membuat sebuah form:
// Membuka form
form()->open()->route('post.store');
// Field lainnya disini...
// Tombol submit
form()->submit('Save');
// Menutup form
form()->close();
Membuka Form
form()->open('search'); // action="search"
form()->open()->get();
form()->open()->post();
form()->open()->put();
form()->open()->patch();
form()->open()->delete();
form()->open(); // default to method="GET"
form()->open()->action('search');
form()->open()->url('search'); // alias for action()
form()->open()->route('route.name');
form()->open()->post()->action(route('comment.store'));
form()->open()->post()->multipart(); // Wajib ada jika form digunakan untuk upload file
Membuka Form (Shortcut)
form()->open('search'); // action="search" method=POST
form()->get('search'); // action="search" method=GET
form()->post('search'); // action="search" method=POST
form()->put('search'); // action="search" method=POST _method=PUT
form()->patch('search'); // action="search" method=POST _method=PATCH
form()->delete('search'); // action="search" method=POST _method=DELETE
CSRF Token
CSRF Token yang merupakan salah satu metode pengamanan form di Laravel sudah ditangani secara otomatis. Setiap kali form dibuat maka akan dibuatkan juga CSRF Token. Hal ini berlaku untuk semua jenis form kecuali untuk method GET
.
Jika ingin memaksa SemanticForm untuk menghilangkan CSRF Token, maka method withoutToken()
bisa dipanggil ketika membuka form.
form()->post('search')->withoutToken();
Basic Input
Checkbox
form()->checkbox($name, $value, $checked)->label('Remember Me');
Checkbox Group
$values = ['apple' => 'Apple', 'banana' => 'Banana'];
$checkedValue = 'banana';
form()->checkboxGroup($name, $values, $checkedValue)->label('Select Fruit');
Coordinate
form()->coordinate('lokasi');
Menampilkan peta yang bisa dipilih dengan drag & drop untuk mendapatkan koordinat latitude dan longitude, menggunakan API Google Maps.
form()->email($name, $value)->label('Email Address');
Hidden
form()->hidden($name, $value);
Input Wrapper
form()->input($name, $defaultvalue, $type = 'text');
form()->input($name, $defaultvalue)->appendIcon('search');
form()->input($name, $defaultvalue)->prependIcon('users');
form()->input($name, $defaultvalue)->appendLabel($label);
form()->input($name, $defaultvalue)->prependLabel($label);
form()->input($name, $defaultvalue)->type("password");
Reference: http://semantic-ui.com/elements/input.html
Number
form()->number($name, $integerValue)->label('Total');
// method tambahan khusus untuk number
form()
->number("umur", 17)
->min(7) // membatasi batas bawah angka yang bisa diinput
->max(35) // membatasi batas atas angka yang bisa diinput
->step(1);
Password
form()->password($name)->label('Password');
Text
form()->text($name, $value)->label('Username');
Textarea
form()->textarea($name, $value)->label('Note');
Time
form()->time($name, $value)->label('Start Time');
Radio
$checked = true;
form()->radio($name, $value, $checked)->label('Item Label');
Radio Group
$values = ['apple' => 'Apple', 'banana' => 'Banana'];
$checkedValue = 'banana';
form()->radioGroup($name, $values, $checkedValue)->label('Select Fruit');
Rupiah
form()->rupiah('harga', $defaultValue);
Menampilkan inputan angka dengan format ribuan secara otomatis, memanfaatkan http://autonumeric.org/.
Date & Time
Date
form()->date($name, $value)->label('Birthday');
Datepicker
Tanggal saja.
form()->datepicker($name, $value, $format);
// $format bisa diisi sesuai format yang disebutkan di https://www.php.net/manual/en/function.date.php
// To convert localized format to standard (SQL) datetime format, you can use Jenssegers\Date\Date library (already included):
// Jenssegers\Date\Date::createFromFormat('d F Y', '12 februari 2000')->startOfDay()->toDateTimeString();
// Jenssegers\Date\Date::createFromFormat('d F Y', '12 februari 2000')->startOfDay()->toDateString();
Datepicker with time
Tanggal dan waktu.
form()->datepicker()->withTime();
Timepicker
Hanya dropdown waktu saja, tanpa tanggal.
form()->timepicker($name, $value);
Select Date & Select Date Time
form()->selectDate('myDate', $startYear, $endYear)->label('Birth Date');
form()->selectDateTime('myDate', $startYear, $endYear, $intervalInMinute)->label('Schedule');
Tanggal dan waktu yang dipilih melalui selectDate
and selectDateTime
akan dikirim dengan nama _myDate
dan dalam format array:
// $_POST
[
'_myDate' => ['date'=>4, 'month'=>5, 'year'=>2016]
]
Untuk melakukan konversi secara otomatis menjadi format tanggal yang dikenali database, yaitu 2016-5-4
, maka SemanticForm telah menyediakan dua buah middleware
, yaitu SelectDateMiddleware
dan SelectDateTimeMiddleware
. Cara pemakaiannya cukup mudah.
1. Daftarkan Middleware
app/Http/Kernel.php
protected $routeMiddleware = [
'selectdate' => \Laravolt\SemanticForm\Middleware\SelectDateMiddleware::class,
'selectdatetime' => \Laravolt\SemanticForm\Middleware\SelectDateTimeMiddleware::class
];
2. Panggil Middleware
routes/web.php
Route::post('myForm', ['middleware' => ['web', 'selectdate:myDate'], function () {
dd($_POST['myDate']); // 2016-5-4
}]);
Select/Dropdown
Select (Dropdown) Single Value
form()->select($name, $options)->label('Choose Country');
form()->select($name, $options, $selected)->label('Choose Country');
form()->select($name, $options)->placeholder('--Select--');
form()->select($name, $options)->appendOption($key, $label);
form()->select($name, $options)->prependOption($key, $label);
Select Multiple (Tagging)
form()->select($name, $options, $selected)->multiple()->label('Select Multiple');
Select Range
form()->selectRange($name, $begin, $end)->label('Number of child');
Select Month
form()->selectMonth($name, $format = '%B')->label('Month');
Dropdown DB
$query = 'SELECT id, name from provinsi order by name';
form()->dropdownDB('provinsi', $query, $keyColumn = 'id', $valueColumn = 'name');
Dengan kode diatas, maka opsi dropdown akan diisi secara otomatis menggunakan hasil raw query ke database. Satu lagi, Anda bisa membuat chained dropdown secara mudah dengan memanfaatkan method dependency()
:
$query = 'SELECT id, name from kabupaten where provinsi_id = %s'
form()->dropdownDB('kabupaten', $query, 'id', 'name')->dependency('provinsi');
Setiap kali dropdown provinsi berubah nilainya, maka dropdown kabupaten juga akan di-update opsinya sesuai provinsi terpilih.
Under the hood, ID dari provinsi akan dikirim ke server via AJAX, dan query untuk dropdown kabupaten akan dijalankan dengan mengganti placeholder %s dengan ID provinsi tersebut.
Prepopulate Child Dropdown
By default, hanya parent dropdown yang akan melakukan query ketika halaman di-load pertama kali. Query untuk child dropdown baru dijalankan ketika value parent-nya berubah. Namun ada kalanya opsi dari child dropdown juga perlu di-generate di awal, misalnya ketika membuat halaman edit.
Sebagai contoh, jika sebelumnya pengguna sudah memilih provinsi dan kabupaten, maka kita bisa menampilkan selected value di awal dengan cara seperti berikut:
$selectedProvinsi = 1;
$selectedKabupaten = 56;
$queryProvinsi = 'SELECT id, name from provinsi order by name';
form()->dropdownDB('provinsi', $query, $keyColumn = 'id', $valueColumn = 'name')->value(selectedProvinsi);
$queryKabupaten = 'SELECT id, name from kabupaten where provinsi_id = %s'
form()->dropdownDB('kabupaten', $query, 'id', 'name')->value($selectedKabupaten)->dependency('provinsi', selectedProvinsi);
Bisa dilihat, kita hanya perlu mengeset value masing-masing dropdown dengan ->value($selectedValue)
dan menambahkan parameter kedua di method ->dependency('provinsi', $selectedProvinsi)
. Dengan cara ini, opsi kedua dropdown akan di-populate di awal dan selected value-nya bisa diset seperti biasa.
File
Standar HTML File Input
form()->file($name);
Uploader
Wrapper untuk library fileuploader.
{!!
form()
->uploader('files')
->limit($maxUploadedFile) //optional, defaul to 1 (single file upload)
->extensions(['jpg', 'png']) // optional, default to null (all files allowed)
->fileMaxSize($sizeInMB) //optional, default to 1000 MB
->mediaUrl($customURL) //optional, default to route("media::store"), handled by Laravolt
!!}
Rich Text Editor (WYSIWYG)
Redactor
form()->redactor($name, $value);
//Additional Methods
form()->redactor($name, $value)->mediaUrl($url); //custom URL to handle file upload, default to route("media::store")
Action
Button
form()->button($value);
Link
form()->link($label, $url);
Submit
form()->submit($value);
Model Binding
Version 1
{!! form()->bind($model) !!}
Version 2
// as parameter for method open()
{!! form()->open($route, $model) !!}
// or chaining it
{!! form()->bind($model)->get($route) !!}
Warning
// This is OK in version 1, but will produce error in version 2
{!! form()->bind($model) !!}
Macro
Macro digunakan untuk mendaftarkan custom field agar bisa dipanggil dengan lebih mudah.
form()->macro('trix', function ($id, $name, $value = null) {
return sprintf(
"%s %s",
form()->hidden($name, $defaultValue)->id($id),
"<trix-editor input='{$id}'></trix-editor>"
);
});
Setelah didaftarkan, macro bisa dipanggil secara langsung oleh SemanticForm:
form()->trix('contentId', 'content', '<b>some content</b>');
Action
Action
digunakan untuk mengelompokkan tombol-tombol aksi (Simpan, Batal, Reset, dan lainnya) dalam sebuah form. Menggabungkan Action
dan Macro
bisa menyederhanakan pembuatan form, terutama jika banyak form memiliki tombol yang seragam.
Manual Action
form()->action(form()->submit('Save'), form()->button('cancel'));
Shortcut Dengan Macro 1
// Assumed you already define some macros:
form()->macro('submit', function(){
return form()->submit('Submit');
});
form()->macro('cancel', function(){
return form()->button('Cancel');
});
// Then you can just call macro name as string
form()->action('submit', 'cancel');
Shortcut Dengan Macro 2
// Even further, you can define macro thats just wrap several buttons:
Semanticform()->macro('default', function(){
return new \Laravolt\SemanticForm\Elements\Wrapper(
form()->button('Cancel'),
form()->submit('Submit')
);
});
// And then make the call simplier:
form()->action('default');
Layout
Secara default, SemanticForm akan menghasilkan form dengan susuan vertikal dari atas ke bawah.
Jika ingin menerapkan susuan layout menyamping 2 kolom (label di kiri, input di kanan), cukup memanggil method horizontal()
ketika membuat form.
form()->open()->horizontal()
Kode di atas akan menghasilkan susunan form seperti ini:
Method Lainnya
Untuk setiap jenis form, method dibawah ini bisa dipanggil sesuai kebutuhan:
- id($string)
- addClass($string)
- removeClass($string)
- attribute($name, $value)
- clear($attribute)
- required()
- readonly()
- data($name, $value)
- enable($flag = true)
- disable($flag = true)
- hint($text) (Since 1.10.0)
- hint($text, $class = "hint") (Since 1.10.2)
Override Hint Class Globally (Since 1.10.2)
// Tambahkan kode berikut ketika booting, misalnya di AppServiceProvider
Laravolt\SemanticForm\Elements\Hint::$defaultClass = 'custom-class';
Contoh
form()->text($name, $value)->label('Username')->id('username')->addClass('foo');
form()->text($name, $value)->label('Username')->data('url', 'http://id-laravel.com');
form()->password($name, $value)->label('Password')->hint('Minimum 6 characters');
form()->password($name, $value)->label('Password')->hint('Minimum 6 characters', 'my-custom-css-class');
Credits
SemanticForm terinspirasi dari AdamWathan\Form.