-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Form Model adalah library khusus framework laravel untuk mempermudah pembuatan form create dan edit data berdasarkan model tertentu.
- PHP >= 7.0
- Laravel 5.5
Buka terminal/cmd, masuk ke direktori proyek laravel kamu. Kemudian ketikkan perintah composer berikut:
composer require laraspells/form-model:dev-master
Jika kamu ingin melakukan perubahan pada konfigurasi view form, view fields, dsb. Kamu dapat melakukan publish konfigurasi terlebih dahulu menggunakan perintah dibawah ini:
php artisan vendor:publish --provider=LaraSpells\\FormModel\\ServiceProvider --tag=config
Untuk sementara, silahkan simak video ini untuk melihat alur kerja form model.
Untuk dapat lebih memahami potensi dan batasan form model, kamu perlu mengetahui bagaimana form model bekerja.
Pada dasarnya form model hanyalah sebuah objek yang menampung spesifikasi formulir pada (eloquent) model tertentu yang ingin dilakukan proses create atau update. Spesifikasi-spesifikasi ini didefinisikan melalui array dan method-method yang telah disediakan.
Selanjutnya form model memanfaatkan spesifikasi tersebut untuk melakukan rendering dan submitting (proses create/update model).
Untuk melakukan rendering, form model memaksimalkan kemampuan Blade pada laravel, khususnya fitur @include
, @component
, dsb untuk management view. Untuk contoh bagaimana form model mengelola file viewnya, kamu dapat melihat pada folder form bs3 ini.
Untuk lebih jelasnya, perhatikan setup form model Product
dibawah ini:
// file: app/Http/Controllers/ProductController.php
...
protected function form(Product $product)
{
return FormModel::make($product, [
'name' => [
'input' => 'text',
'label' => 'Name',
'maxlength' => 120,
'rules' => 'required|max:120'
],
'slug' => [
'input' => 'text',
'label' => 'Slug',
'maxlength' => 120,
'rules' => 'required|max:120|unique:products,slug'
],
'description' => [
'input' => 'textarea',
'label' => 'Description',
'rules' => 'required'
],
'image' => [
'input' => "image",
'label' => "Image",
'delete_old_file' => true,
'upload_disk' => 'uploads',
'upload_path' => 'product/images',
'rules' => 'required|image|max:2048'
]
]);
}
...
Form model tersebut, jika di render()
menggunakan form template bs3, akan menghasilkan struktur view seperti dibawah ini:
Dan tentu saja, kamu dapat mengirimkan view data tambahan ke setiap bagian view tersebut, ataupun jika kamu ingin menggunakan field khusus yang menggunakan plugin seperti ckeditor, tinymce, input mask, dsb, kamu dapat menambahkan view field type kamu sendiri dan mendaftarkannya pada file konfigurasi, ataupun melalui method withInputViews
.
Hal yang perlu kamu ketahui selanjutnya, form model memanfaatkan property exists
(boolean) pada Eloquent. Property exists ini mengindikasikan sebuah model terdapat pada database atau tidak. Form model memanfaatkan property ini untuk menentukan proses yang dilakukan adalah proses create atau proses edit.
Contoh:
$this->form(new Product)->render(); // will render form create product
$this->form(Product::findOrFail(1))->render(); // will render form edit product
$this->form(new Product)->submit($request); // will insert new product
$this->form(Product::findOrFail(1))->submit($request); // will update product
Misalkan kamu ingin set readonly
menjadi true pada field kode_barang
hanya pada saat update.
Kamu dapat menggunakan if_update
seperti contoh di bawah ini:
'kode_barang' => [
'input' => 'text',
'label' => 'Kode Barang',
'rules' => 'required|unique:barang,kode_barang',
'if_update' => [
'readonly' => true
]
]
Dengan begitu, jika kamu sedang melakukan proses update, parameter readonly
yang bernilai true akan dikirim ke view input text.
Begitu juga dengan parameter khusus create, kamu dapat menggunakan if_create
.
Misalkan kamu ingin menambahkan field type select2 yang menggunakan plugin select2. Kamu dapat melakukan beberapa tahap berikut:
Buat sebuah file view baru di resources/views/partials/fields/select2.blade.php
.
Karena select2 ini berupa select, kita dapat copy-paste isi dari field select di form template bs3.
@php
$id = "input-{$name}";
$label = isset($label)? $label : ucwords(snake_case(camel_case($name), ' '));
$required = isset($required)? (bool) $required : false;
$empty_option = isset($empty_option)? $empty_option : 'Pick '.$label;
$value = isset($value)? $value : '';
@endphp
@component('form-model::bs3.fields.wrapper', [
'name' => $name,
'label' => $label,
'required' => $required
])
@if(isset($groupLeft) OR isset($groupRight))
<div class="input-group">
{!! $groupLeft or '' !!}
@endif
<select
class="form-control select2"
name="{{ $name }}"
id="{{ $id }}"
{{ $required? 'required' : '' }}>
@if($empty_option)
<option value="">{{ $empty_option }}</option>
@endif
@foreach($options as $option)
@if(isset($option['options']))
<optgroup label="{{ $option['label'] }}" {!! isset($option['attributes'])? html_attributes($option['attributes']) : "" !!}>
@foreach($option['options'] as $opt)
<option value="{{ $opt['value'] }}" {{ $value == $opt['value']? 'selected' : '' }} {!! isset($opt['attributes'])? html_attributes($opt['attributes']) : "" !!}>{{ $opt['label'] }}</option>
@endforeach
</optgroup>
@else
<option value="{{ $option['value'] }}" {{ $value == $option['value']? 'selected' : '' }} {!! isset($option['attributes'])? html_attributes($option['attributes']) : "" !!}>{{ $option['label'] }}</option>
@endif
@endforeach
</select>
@if(isset($groupLeft) OR isset($groupRight))
{!! $groupRight or '' !!}
</div>
@endif
@endcomponent
@css('vendor/admin-lte/plugins/select2/select2.min.css')
@js('vendor/admin-lte/plugins/select2/select2.min.js')
@script('init-select2')
<script>
$('select.select2').select2({})
</script>
@endscript
Directive
@css
,@js
, dan@script
merupakan directive khusus dari komponen asset-collector. Directive tersebut berfungsi untuk mendaftarkan file css, js, dan kode javascript, dan mencegahnya agar tidak duplikat semisal kamu menggunakan lebih dari satu fieldselect2
pada form kamu.
Buka file config/form-model.php
. Jika tidak ada, silahkan publish terlebih dahulu.
Kemudian tambahkan baris berikut:
return [
'default_form' => 'bs3',
'forms' => [
'bs3' => [
'form' => 'form-model::bs3.form',
'inputs' => [
...
'select2' => 'partials.fields.select2', // << tambahkan ini
]
]
]
];
Jika sudah, jangan lupa simpan.
Setelah itu kamu dapat menggunakan 'input' => 'select2'
pada form model kamu.
Adakalanya, kita memiliki sebuah kolom yang berisi data komposit (gabungan dari beberapa nilai).
Misalnya kita memiliki database user yang hanya memiliki kolom name
, tetapi kita ingin memisahkan inputannya menjadi first_name
dan last_name
.
Pada kasus seperti itu, kamu dapat menggunakan method beforeSave
, dan parameter tambahan render_value
pada field-field tambahan tersebut seperti contoh dibawah ini:
// file: app/Http/Controllers/UserController.php
...
protected function form(User $user)
{
return FormModel::make($user, [
'first_name' => [
'input' => 'text',
'label' => 'First Name',
'maxlength' => 60,
'rules' => 'required|max:60',
'render_value' => function($value) {
return $this->getModel()->getFirstName(); // add this method to User model
}
],
'last_name' => [
'input' => 'text',
'label' => 'Last Name',
'maxlength' => 60,
'rules' => 'required|max:60',
'render_value' => function($value) {
return $this->getModel()->getLastName(); // add this method to User model
}
],
...
])
->beforeSave(function($user) {
$req = $this->getRequest();
$user->name = $req->get('first_name').' '.$req->get('last_name');
});
}
...
Parameter
render_value
berfungsi untuk set nilai yang akan di render ke view field. SedangkanbeforeSave
digunakan untuk set callback yang akan dieksekusi tepat sebelum eloquent model melakukan methodsave()
.