Tutorial Laravel 8 pt.17 Create Post Form
Tutorial Laravel 8 pt.17 Create Post Form
database kita
sekarang kita akan melakukan itu lewat dashboard kita. Untuk fitur create, kita
akan buat
form dlu, lalu kita akan tambahkan fitur validasi, selanjutnya kita akan
tambahkan datanya
ke dalam database ketika sudah oke
>> Jadi yang pertama kali akan kita lakukan kita akan menambah tombol untuk tambah
postingan
yang posisinya berada di bawah judul halaman. Kita buka file index yang berada
di folder
dashboard/posts
>> Kita akan tambahkan tombolnya di atas tabelnya, jadi kita masuk ke dalam tag
div untuk
table, kita buat tag a yang mengarah ke /dashboard/posts/create, kita arahkan
ke route
yang namanya create agar nanti bisa di ambil oleh route resource kita untuk
menampilkan
form tambah data post nya
>> Ini udah default, klo kita mau bikin form untuk tambah data, itu create, lalu
isi dari tag
a adalah Create new post. Kita kasih class btn untuk membuat button, gunakan -
primary
untuk membuat warnanya menjadi biru tua, kasih mb-3 untuk membuat margin bottom
Misal :
<a href="/dashboard/posts/create" class="btn btn-primary" mb-3>Create new
post</a>
>> Jika di klik nanti dia akan masuk ke create, ini masih kosong, karena di dalam
controllernya kita belum isikan apa2, tapi klo lihat di halamannya tidak 404,
karena
sudah ditangani. Kita buka dashboardpostcontroller, ke method create
>> Dalamnya kita akan mereturn view, kita akan bikin di dalam folder dashboard, di
dalam
folder posts namanya file create
Misal :
public function create()
{
return view('dashboard.posts.create');
}
>> Sekarang kita bikin file dengan nama create.blade.php, di dalam file tersebut
kita
akan extends ke layout dashboard kita, lalu kita bikin section yang namanya
container
Isinya kita contek dari halaman index di posts dashboard, kita copas judulnya
Misal :
@extends('dashboard.layouts.main')
@section('container')
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-
items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Create New Post</h1>
</div>
@endsection
>> Lalu kita ganti h2nya jadi Create New Post, jika kita cek di web browser maka
tidak
terjadi error. Kalau link My Posts mau tetap active, kita akan ubah sidebarnya,
klo untuk
My Post active kan dia ada di halaman posts, tapi kalo kita tambahkan wildcard,
sebuah
bintang (*), nanti dia akan melihat apapun yang ada setelah tanda posts akan
membuat
halaman ini active
>> Karena create itu adalah sub dari posts, kita ingin bikin link mengarah ke My
Posts tetap
berwarna biru. Sekarang kita akan bikin di bawah judul halaman adalah formnya.
Bagaimana
kita nambahin form untuk postingan kita, pertama kita contek dlu dari bootstrap
>> Kita ke dokumentasi, cari dokumentasi yang namanya form, berada di sebelah
kiri, ada sub
menu form lalu kita ke form control. Ada contohnya untuk email dan textarea,
kita butuhnya
emailnya aja karena kalau textarea kita gk pakai textarea default, tapi kita
akan pakai
sebuah WYSIWYG editor
>> Sekarang kita buka di bagian overview, kita copy yang bagian email dan
password, kita butuh
ada formnya supaya kita gk perlu copy2 lagi, kita copas, pindahkan di bawah tag
tutup
div
>> Jika kita lihat di web browser maka tampilannya sudah ada, tetapi terlalu
penuh, kita
inginnya kolomnya tidak penuh. Caranya kita bisa bungkus formnya dengan colom
dengan
membuat tag div baru di atas tag form, kasih class lg-8
Misal :
<div class="col-lg-8">
<form>
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">Email
address</label>
<input type="email" class="form-control" id="exampleInputEmail1"
aria-describedby="emailHelp">
<div id="emailHelp" class="form-text">We'll never share your email
with anyone else.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1"
class="form-label">Password</label>
<input type="password" class="form-control"
id="exampleInputPassword1">
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">Check me
out</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
>> Tinggal kita edit dari mulai formnya dlu, untuk formnya, methodnya post,
actionnya akan
mengarah ke route yang akan memproses ini, yaitu /dashboard/posts, ini akan
mengarah ke
method store di dalam controller dashboard
Misal :
<form method = "post" action = "/dashboard/posts">
>> Kalau kita pakai resource, udah otomatis, jadi gk perlu bikin webnya semua udah
ditangani,
begitu halamannya ini, methodnya get, dia akan langsung ke index, klo methodnya
post,
diarahkan ke store, begitu methodnya put, akan diarahkan ke update, begitu
methodnya delete
dia akan mengarahkan ke dastroy
>> Kita kasih @csrf di bawah formnya untuk menangani cross side resource forgery,
lalu kita
edit satu per satu bagian label dan inputnya, untuk label pertama kita akan
kasih namanya
title, isi dari labelnya kita kasih jadi title, tipenya adalah text biasa aria-
describeby
kita hapus, di bawah tag inputnya kita hapus juga, karena nanti kita akan pakai
validasi
untuk munculin kalau ada error, jangan lupa kita kasih name
Misal :
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" name = "title">
</div>
>> Untuk password dan checkbox bisa kita hapus, kita akan duplikat syntax nulis
titlenya
untuk membuat slug, kita ganti for label, isi label, id tag input, dan name tag
input
dengan nama slug
Misal :
<div class="mb-3">
<label for="slug" class="form-label">Slug</label>
<input type="text" class="form-control" id="slug" name="slug">
</div>
>> Lalu tombolnya kita ganti isinya jadi Create Post, berikutnya, sebelum kita
bikin elemen
input lain, kita butuh ada kategori, lalu kita butuh ada buat nulisin bodynya.
Sebelum
melakukan itu, kita akan coba bikin slug menjadi otomatis
>> Jadi kalau kita isikan sebuah judul, kita ingin ketika kita pindah fokus ke
kolom yang
lain, otomatis dibikinin. Jadi gk perlu mikirin slugnya lagi, caranya kita
butuh bantuan
sebuah package di dalam composer, nanti kita akan download yang tugasnya untuk
membuat
slug
>> Jadi kita gk perlu bikin sendiri, kita akan googling namanya eloquent
sluggable, pasti
ketemu yang paling pertama dari cviebrock, ini akan otomatis bikin slug kita
beserta fitur
fitur lain yang akan kita coba
>> Cara pakainya kita bisa lihat di installation di bawah, ini support untuk
laravel versi 8
cara manggilnya, kita install dlu packagenya lewat composer, nanti kita ketik :
composer require cviebrock/eloquent-sluggable, lalu otomatis udah langsung bisa
kita pakai
>> Kita balik ke vscode, kita buka terminal vscode, kita copas, kita tunggu
installasinya
akan terjadi warning, katanya kita punya satu model yang gk sesuai dengan
standard
yaitu model Post_, ini memang model sementara aja, sisanya udah beres
>> Cara pakainya pertama kita harus update model kita, cari model mana yang mau
pakai slugnya
kebetulan model yang mau kita pakai namanya Post juga. Jadi kita includekan
namespacenya
di atas model post, lalu kita panggil tradesnya, supaya bisa dipake
>> Lalu kita akan bikin sebuah method yang namanya sluggable() returnya kita
biarkan slug
lalu berisi array yang di dalamnya ada source nya mau ngambil dari field apa di
dalam
tabel post kita, kebetulan di dalam table post kita nama judul blognya juga
sama
>> Jadi kita copas semua, baru pindahkan ke model post kita. Jika terjadi error :
Undefined type cviebrock\eloquentsluggable\sluggable, maka caranya adalah kita
copas syntax di bawah composer require yang ada di git hubnya cviebrock, lalu
kita
restart vscode kita
>> Caranya kita harus update dlu model kita. Cari mau model yang mana yang akan
kita gunakan
slugnya, kebetulan model kita yang mau kita apakai post juga, jadi caranya kita
tulis
namespacenya, lalu kita panggil tradesnya supaya bisa dipakai
>> Lalu kita harus bikin method yang namanya sluggable(), lalu nanti kita lihar,
returnya
kita biarkan slug, sourcenya mau ngambil dari field apa di dalam tabel post
kita, kebetulan
di dalam tabel post kita nama isinya juga sama title, klo kita bukan title,
isinya diganti
Misal :
public function sluggable(): array
{
return [
'slug' => [
'source' => 'title'
]
];
}
>> Akan terjadi error ketika kita membuat trades, karena itu wajib kita harus
bikin methodnya
Sekarang cara pakainya, karena kita pengennya pada saat kita mengetikkan judul,
lalu pada
saat kita pindah ke kolom slug otomatis dibuatkan, itu musti pakai javascript
>> Kita bisa melakukannya dengan ajax atau pakai fetch API, supaya nanti dia
manggil method
sluggable secara otomatis, lalu secara otomatis ambil titlenya dan ubah jadi
slug. Berarti
kita butuh javascript, kita balik ke file create
>> Kita bikin di bawah sebelum @endsection, kita bikin tag script, lalu kita
googling namanya
fetch API, kita baca di website developer.mozilla. Mau pakai XML atau HTTP
request versi
AJAX juga boleh
>> Tapi karena kita ingin simple aja jadi kita pakai fetch aja, jadi kita butuh
untuk
mengambil inputan title dan slug ke dalam javascript kita, input title di ambil
buat
ngambil judulnya, input slug di ambil buat mengisikan slugnya
>> Jadi kita punya dua const, pertama const title yang isinya
document.querySelector('') isinya
kita ambil pakai id, jadi caranya tinggal kasi #title, lalu satu lagi const
untuk slug
Misal :
<script>
const title = document.querySelector('#title');
const slug = document.querySelector('#slug');
</script>
>> Selanjutnya kita akan bikin sebuah event handler yang menangani ketika yang
kita tuliskan
di dalam title itu berubah, jadi kita butuh eventnya onChange, caranya kita
kasih title
lalu .addEventListener() di dalamnya ketika eventnya adalah change
>> Sebenernya kita bisa pakai onKeyUp atau keyUp, tapi itu pemanggilan fatchnya
nanti
ketika kita ngetikkin sesuatu, jadi satu tombol langsung ngerequest, tapi klo
kita mau
nunggu selesai dlu, lalu kita pindah tab, kita pakainya change supaya tidak
terlalu
sering pemanggilannya
>> Lalu kita kasih parameter kedua barupa callback function yang di dalamnya
adalah apa yang
kita lakukan ketika title berubah isinya, disini baru kita akan gunakan fetch()
Jadi fetch itu memiliki parameter urlnya, kita mau ngefetch data darimana
>> Kita akan ngefetch data dari mathod yang akan kita buat di controller
dashboard, jadi di
paling bawah kita akan bikin satu method baru yang tugasnya untuk menangani
ketika ada
permintaan slug, jadi ceritanya kita akan bikin function dengan nama
checkSlug()
>> Di dalamnya ada parameter request, request itu akan didapatkan ketika kita
pindah tab
akan mengambil isi dari inputan titlenya, isi dari functionnya belakangan kita
isi
Misal :
<script>
const title = document.querySelector('#title');
const slug = document.querySelector('#slug');
title.addEventListener('change',function(){
fetch('')
});
</script>
>> Jadi nanti kita akan bikin routes buat ngarah ke function ini, jadi misalnya
kalau ada
request ke /dashboard/posts/createSlug, maka kita akan ambil isinya jadi
pakai .then()
karena fetch ini bentuknya promise harus kita ambil dlu isinya
>> Nanti responsenya akan kita jalankan ke dalam method JSON, jadi
response.json(), karena
yang dikirim nanti nya adalah json, jadi nanti kita ambil, kebetulan json ini
masih
bentuknya promise, berarti kita harus kasih .then() isinya akan mengembalikan
dalam
bentuk data
Misal :
fetch('/dashboard/posts/checkSlug')
.then(response => response.json())
>> Nanti data ini akan mengganti si slug.value kita, slug.value adalah isi dari
inputan slug
Kan slug itu elemen inputnya, .valuenya itu isinya, nanti valuenya itu akan
mengambil dari
data yang nama propertinya slug, jadi nanti kita akan bikin supaya nama
propertinya slug
Misal :
fetch('/dashboard/posts/checkSlug')
.then(response => response.json())
.then(data =>slug.value = data.slug)
>> Karena yang dikirimin itu bentuknya object, pasangan dari key dan value.
Sekarang kita akan
membuat routes untuk script kita. Kita akan simpen di atas resource, karena
bukan bagian
dari resource, kita harus bikin manual
>> Jadi kita bikin Route::, ketika ada request dalam method get ke url
/dashboard/posts/checkSlug,
nanti kita akan panggil controllernya, jadi cara manggilnya manual,
DashboardPostController
lalu methodnya apa
Misal :
Route::get('/dashboard/posts/checkSlug', [DashboardPostController::class,
'checkSlug']);
>> Klo kita mau kasih middleware('auth') boleh, supaya gk bisa diakses oleh user
yang belum
login, walaupun kecil kemungkinan bisa diakses, karena ini adalah utility
function aja
Misal :
Route::get('/dashboard/posts/checkSlug', [DashboardPostController::class,
'checkSlug'])
->middleware('auth');
>> Jadi ini udah manggil, tapi kita belum ngirimin datanya, jadi kita harus
ngirimin dlu
datanya ke controller seupaya bisa diambil oleh $request, kita kasih datanya di
fetch()
dengan cara kita kasih ?title = itu berisi title.value
Misal :
fetch('/dashboard/posts/createSlug?title=' + title.value)
>> Jadi apa yang kita isikan di dalam title akan masuk ke method createSlug(),
diolah oleh
method createSlug, dikembalikan datanya sebagai slug, jadi inputnya title,
outputnya slug
tinggal kita bikin apa yang ada di dalam checkSlugnya
>> Jadi kita akan bikin varible slug, lalu berisi kita akan panggil servicenya
yang ada di
github sluggable, kita scroll cari yang namanya The SlugService Class, jadi
kita copas
syntaxnya
Misal :
$slug = SlugService::createSlug(Post::class, 'slug', 'My First Post');
>> Ini akan jadi error karena kita harus menggunakan namespacenya dlu :
use \Cviebrock\EloquentSluggable\Services\SlugService;
>> Jadi gunakan method createSlug(), ngambil dari class Post, kebetulan sama
classnya,
lalu ngambil fieldnya slug, supaya nanti diubah field slug, lalu titlenya apa,
titlenya
akan ngambil dari $request, request itu ngambil dari url fetch yang kita buat,
request
yang keynya title
Misal :
$slug = SlugService::createSlug(Post::class, 'slug', $request->title);
>> Nanti slug akan berisi hasilnya, apapun yang sudah diambil dari si title,
bahkan nanti
dia akan ngecek di database kita, udah ada belum slug yang sama, karena slug
harus unique
pengecekan unique udah dikerjain sama si library ini
>> Klo sudah kita return sebagai response(), kita kasih dalam bentuk json() supaya
nanti bisa
di olah sama method json yang ada di create, yang isi variablenya berupa array
assosiative
yang keynya slug, isi nya variable slug
Misal :
return response()->json(['slug' => $slug]);
>> Dikirim ke file create, lalu promisenya resolve, data slug ini masuk sebagai
value di
inputan kita di const slug. Jika kita cek di web browser, ketika kita ketik
titlenya
lalu pencet tab, maka otomatis akan dibuatkan slugnya
>> Kita bisa bikin slugnya readOnly atau disable gk bisa diganti, tapi klo
misalnya kita
ingin user punya kendali atas slugnya, boleh dibiarkan begini saja. Klo mau
bikin disable
bisa juga
>> Kita cari di dokumentasi bootstrap cara untuk disable form controll, jadi
caranya tinggal
dikasih disabled readonly
Misal :
<input type="text" class="form-control" id="slug" name="slug" disabled
readonly>
>> Selanjutnya kita akan bikin untuk kategori, untuk category kita akan
menggunakan tag
select option, kita ke bootstrap di subab form ada namanya select, kita copas
aja syntaxnya
Kita duplikasi tag input untuk slugnya, tag inputnya diganti jadi tag select
yang sudah
kita copas
Misal :
<div class="mb-3">
<label for="slug" class="form-label">Slug</label>
<select class="form-select" aria-label="Default select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
>> Jika sudah, sekarang kita ganti attribut label, isi dari label, atribut aria-
labelnya
kita ganti jadi name dengan value category_id, lalu optionnya kita sisakan
satu, supaya
nanti kita looping dari tabel category
>> Kalau kita pengen looping dari tabel category caranya kita bisa includekan
categorynya di
controller, nanti kita kirimkan ke method create. Jadi kita gunakan namespace
model
Category, lalu di dalam method create kita kirimin dengan menggunakan array
Misal :
return view('dashboard.posts.create',[
'categories' => Category::all()
]);
>> Di bawah tag select nya kita kasih foreach, lalu tulis categories as category,
value
nya berupa idnya, jadi kita gunakan blade lalu akses variable category lalu
ambil id,
dan tulisannya itu kita tulis category name
Misal :
<select class="form-select" aria-label="Default select example">
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category-
>name }}</option>
@endforeach
</select>
>> Selanjutnya, kita butuh sebuah editor untuk nulisin bodynya, nanti excerptnya
itu akan
dibikin supaya ngambil beberapa kata dari body, caranya. Kita mau cari sebuah
editor
yang namanya trix editor di google
>> Ada namanya trix editor dari developer yang nama pembuatnya basecamp.
Sebenernya masih
banyak yang lain seperti ckeditor, atau editor yang lain, tapi kita gunakan
trix karena
cukup simple
>> Walaupun ada tombol untuk nambahin file, tapi kita gk akan kita pakai. Nanti
trix editor
ini membuat kita menulis blognya ada formatingnya, bisa bold, italic, straight
trough,
ada linknya bisa kita perbesar hurufnya, bisa kita pakai list dst
>> Dan yang terpenting cara makainya gampang banget. Kita bisa klik view on
GitHub. urlnya
trix-editor.org. Sebenernya klo kita googling trix editor, yang paling atas
udah githubnya
>> Cara pakainya yang pertama, kita tambahkan 2 baris syntax Getting Started di
bagian head
mengarah ke file trix.css dan trix.js. Ini dapet dari, nanti kita download
codenya
Setelah itu kita bikin editornya dengan menuliskan : <trix-editor></trix-
editor> di dalam
view kita
>> Jadi kalau kita form, kita akan bikin trix-editor dan kita akan bikin sebuah
input yang
tipenya hidden dimana idnya berpasangan dengan input dari trix-editor, jadi
kalau misalkan
nama dari input kita adalah body, maka id dari tag input diisi body, attribut
input dari
tag trix-editor diisi body
>> Kita akan coba, kita akan download kodingannya berupa zip, kita buka zipnya,
kita lihat di
folder dist, atau distribution. ada 2 file trix.css dan trix.js, yg core tidak
perlu,
karena itu digunakan untuk mengedit si editornya lebih lanjut
>> Kita copas 2 file tersebut dan simpan di public/css dan public/js yang ada pada
projek
kita. Jika sudah, selanjutnya kita copas syntax untuk menggunakan trix.css dan
trix.js
Misal :
<head>
<link rel="stylesheet" type="text/css" href="trix.css">
<script type="text/javascript" src="trix.js"></script>
</head>
>> Jika sudah kita buka file main kita, kita akan simpan syntax ini di head kita.
Kita kasih
komentar Trix Editor, kita simpan di bawahnya
Misal :
{{-- Trix Editor --}}
<link rel="stylesheet" type="text/css" href="/css/trix.css">
<script type="text/javascript" src="/js/trix.js"></script>
>> Selanjutnya kita duplikat lagi tag div untuk category yang ada di file create,
lalu kita
hapus selectnya, fornya for body, nanti kita lihat kita butuh label atau gk, di
bawah tag
label, kita copas syntax yang ada di integrating with forms
Misal :
<div class="mb-3">
<label for="body" class="form-label">Body</label>
<input id="body" type="hidden" name="body">
<trix-editor input="body"></trix-editor>
</div>
>> Label fornya kita kasih body, isi dari labelnya namanya body, id tag inputnya
body,
name dari tag inputnya body dan input dari tag trix-editornya juga body, supaya
apa yang
kita inputnkan akan masuk ke dalam inputnya dan dikirim ke controllernya, Jika
kita cek
di browser
>> Maka trix-editor sudah diterapkan. Jadi kalau kita ingin blod, maka kita
tinggal klik
tombol boldnya, nanti tag boldnya ke kirim ke dalam controllernya. Sekarang
kita ingin
menghilangkan tombol dari file uploadnya supaya orang gk bisa iseng buat
nambahin
file upload
>> Kita harus melakukan 2 hal, kita hilangin dari sisi css nya dan kita akan
activekan
fungsinya di javascriptnya. Kita hilangkan di css nya. Kita bikin css di main,
karena
hanya sedikit syntaxnya.
>> Jadi kita bikin tag style untuk mengakses trix-toolbarnya, caranya kita bisa
ambil
trix-toolbar, karena dia bentuknya sebuah tag, lalu kita ambil dengan array
data-trix-button-group, semua tombolnya adalah button group
>> Kita cari untuk yang file upload, yang namanya file-tools, jadi dicari elemen
tersebut,
lalu buka kurung kurawal isinya display:none. Setelah itu agar gk jalan
fiturnya, kita
kasih javascript di bawah file create, kita panggil event listener lagi
Misal:
<style>
trix-toolbar [data-trix-button-group="file-tools"]{
display:none;
}
</style>
>> Kita ambil dari document.addEventListener(), isi dari methodnya adalah trix-
file-accept
lalu tinggal kita panggil callbacknya dengan membuat function dengan parameter
e(event)
di dalam functionnya kita matikan dengan menuliskan e.preventDefault()
Misal :
document.addEventListener('trix-file-accept', function (e) {
e.preventDefault();
>> Klo kita ke browser, maka tombol uploadnya gk akan bisa dilakukan, selanjutnya
kita
coba isi dlu datanya, tapi sebelum itu, kita bikin function storenya agar
ngembaliin
variable request untuk nangkep data yang dikirimin
>> Jika kita isi formnya, lalu kita klik tombol create post, maka data yang kita
isikan
akan tampil di halaman. Kalau kita kasih enter pada isi postingannya, maka
otomatis
akan dikasi tag br oleh tag trixnya
>> Maka data akan dikirim dari tokennya, titlenya slugnya, categorynya dan
bodynya, di bodynya
ada tag htmlnya