Yuk Belajar Web Menggunakan Spring Boot(2)
Bismillah,
Artikel kali ini adalah lanjutan dari artikel sebelumnya yang terakhir fiturnya adalah menampilkan semua data pada sebuah halaman web. Sementara kali ini, akan kita coba mengimplementasikan edit data, hapus data, validation, dan beberapa fungsi menarik lainnya. Tampilan utama aplikasi yang kita bangun adalah sebagai berikut.
Beberapa point yang akan kita bahas adalah sebagai berikut
- Menambahkan Halaman Simpan atau Edit Data
- Menambahkan Halaman Hapus Data
- Menambahkan Halaman Detail
- Menambahkan Validasi
- Menampilkan Alert
- Referensi
Menambahkan Halaman Simpan atau Edit Data
Untuk mengimplementasikan fungsi edit dan tambah, sebenarnya aksi tersebut hampir sama karena di JPA method yang dipanggil juga sama yaitu save(Object o)
. Kita persiapkan halaman html dan controller untuk dapat membuatnya, controller pada class MahasiswaController
adalah sebagai berikut
@GetMapping("/mahasiswa/form")
public ModelMap tampilFormedit(@RequestParam(required = false, value = "id") Mahasiswa mahasiswa) {
if (mahasiswa == null) {
mahasiswa = new Mahasiswa();
}
return new ModelMap().addAttribute("mahasiswa", mahasiswa);
}
@PostMapping("/mahasiswa/form")
public String editMahasiswa(@ModelAttribute @Valid Mahasiswa mahasiswa, BindingResult errors, SessionStatus status) {
LOGGER.info(mahasiswa.toString());
LOGGER.info(errors.toString());
LOGGER.info("" + errors.hasErrors());
LOGGER.info("" + errors.hasGlobalErrors());
if (errors.hasErrors())
return "/mahasiswa/form";
try {
mahasiswaDao.save(mahasiswa);
status.setComplete();
return "redirect:/index";
} catch (DataAccessException e) {
errors.reject("error.object", e.getMessage());
LOGGER.error(e.getMessage());
return "/mahasiswa/form";
}
}
Penjelasan kode di atas adalah di bawah ini
@GetMapping("/mahasiswa/form")
, untuk mengakses form ini berarti yang digunakan adalahGET
.@RequestParam(required = false, value = "id") Mahasiswa mahasiswa
, parameter pada methodtampilFormedit()
berarti ketika mengakses method tersebut membutuhkan request parameter. Cara memanggilnya seperti ini.../mahasiswa/form?id=xxx
dan objekmahasiswa
secara automatis Spring akan query berdasarkanid
tersebut.return new ModelMap().addAttribute("mahasiswa", mahasiswa)
, nilai balik method tersebut berarti akan mengembalikan objek mahasiswa. Tujuannya adalah akan ditampilkan ke halaman html nantinya.@PostMapping("/mahasiswa/form")
, berarti untuk mengakses method tersebut menggunakanPOST
.@ModelAttribute @Valid Mahasiswa mahasiswa, BindingResult errors, SessionStatus status
; parameter-parameter tersebut terdapat pada methodeditMahasiswa()
,@ModelAttribute
berarti ada parameter objek mahasiswa yang bisa dilewatkan,@Valid
maksudnya adalah untuk memvalidasi objek mahasiswa sebelum disimpan, objekerrros
digunakan untuk menampung data error dan objekstatus
untuk menghandle sebuah session.
Setelah itu, kita perlu membuat halaman html yang digunakan menampilkan form edit atau simpan. Potongan kodenya yang digunakan adalah sebagai berikut
<form method="post" th:object="${mahasiswa}" th:action="@{/mahasiswa/form}" class="needs-validation" novalidate>
<input type="hidden" th:field="*{id}">
<div class="form-group">
<label for="nim" class="col-form-label">Nim</label>
<input type="text" class="form-control" id="nim" th:field="*{nim}" placeholder="Nim mahasiswa" required>
<div class="invalid-feedback">
Nim tidak boleh kosong.
</div>
</div>
<div class="form-group">
<label for="nama" class="col-form-label">Nama</label>
<input type="text" class="form-control" id="nama" th:field="*{nama}" placeholder="Nama mahasiswa"
required>
<div class="invalid-feedback">
Nama tidak boleh kosong.
</div>
</div>
<div class="form-group">
<label for="ipk" class="col-form-label">IPK</label>
<input type="number" step="any" class="form-control" id="ipk" th:field="*{ipk}"
placeholder="IPK mahasiswa"
required>
</div>
<div class="form-group">
<label for="jurusan" class="col-form-label">Jurusan</label>
<input type="text" class="form-control" id="jurusan" th:field="*{jurusan}"
placeholder="Jurusan mahasiswa" required>
<div class="invalid-feedback">
Jurusan tidak boleh kosong.
</div>
</div>
<button type="submit" class="btn btn-primary mb-3">Submit</button>
<div th:if="${#fields.hasErrors('all')}">
<div class="form-group">
<div class="alert alert-warning alert-dismissible fade show">
<label th:errors="*{all}">xxx</label>
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
</div>
</div>
</form>
Dari kode di atas, pada tag form method yang digunakan adalah post
sesuai yang terdapat di controller. th:object="${mahasiswa}
adalah salah satu penerapan tag thymeleaf untuk menampung objek mahasiswa
, objek mahasiswa
berasal dari controller. th:action="@{/mahasiswa/form}
maksudnya adalah path yang diakses ketika button di-submit, sedangkan th:field="*{id}"
bertujuan untuk mengisikan data id
objek mahasiswa
pada input text. Form tersebut digunakan untuk melakukan edit data dan simpan data, ketika data menggunakan yang sebelumnya berarti edit dan ketika menggunakan data baru artinya adalah simpan data. Tampilannya adalah sebagai berikut
Menambahkan Halaman Hapus Data
Selanjutnya untuk menghapus data, terlebih dahulu buat fungsi untuk menghadle kebutuhan tersebut pada controller. Methodnya adalah sebagai berikut
@DeleteMapping("/mahasiswa/hapus")
public String hapusMahasiswa(@RequestParam(name = "id") String id) {
mahasiswaDao.deleteById(id);
return "redirect:/index";
}
Kode di atas sederhana, methode yang digunakan adalah DELETE
dan menggunakan request parameter dengan nama id
untuk mengaksesnya. Setelah berhasil menghapus, akan redirect
ke halaman index
. Sementara untuk halaman html menggunakan kode berikut ini
<form method="post" th:action="@{/mahasiswa/hapus(id=${mhs.id})}" class="d-inline">
<input type="hidden" name="_method" value="delete"/>
<button type="button" class="btn btn-link btn-sm" data-toggle="modal"
data-target="#exampleModalCenter">Hapus
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog"
aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterTitle">Hapus data mahasiswa</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Apakah Anda yakin akan menghapus data?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tidak</button>
<button type="submit" class="btn btn-primary">Ya</button>
</div>
</div>
</div>
</div>
</form>
Kode di atas tertulis pada tag form mengunakan method post
, sementara pada controller adalah DELETE
berarti kita butuh <input type="hidden" name="_method" value="delete"/>
. Kemudian untuk kode di bawahnya adalah digunakan untuk menampilkan dialog/modal karena prosesnya hapus, sehingga perlu mengkonfirmasi ke pengguna. Hasilnya adalah sebagai berikut
Menambahkan Halaman Detail
Untuk halaman detail digunakan melihat detail data mahasiswa, seperti pada pembahasan sebelumnya kita membutuhkan fungsi pada controller. Yang perlu ditambahkan adalah sebagai berikut
@GetMapping("/mahasiswa/detail_form")
public ModelMap tampilFormDetail(@RequestParam(required = false, value = "id") Mahasiswa mahasiswa) {
if (mahasiswa == null) {
mahasiswa = new Mahasiswa();
}
return new ModelMap().addAttribute("mahasiswa", mahasiswa);
}
Isi kode di atas sebenarnya sama dengan untuk form edit dan simpan, bedanya adalah alamat path yang digunakan yaitu "/mahasiswa/detail_form"
. Kemudian untuk halaman html implementasinya adalah sebagai berikut
<div class="container">
<h4>Detail Mahasiswa</h4>
<table class="table table-hover">
<tbody>
<tr>
<th scope="row">NIM</th>
<td th:text="${mahasiswa.nim}"> </td>
</tr>
<tr>
<th scope="row">Nama</th>
<td th:text="${mahasiswa.nama}"> </td>
</tr>
<tr>
<th scope="row">IPK</th>
<td th:text="${mahasiswa.ipk}"> </td>
</tr>
<tr>
<th scope="row">Jurusan</th>
<td th:text="${mahasiswa.jurusan}"> </td>
</tr>
</tbody>
</table>
<a th:href="@{/index}" class="btn btn-primary">Kembali</a>
</div>
Untuk menampilkan menggunakan tabel, kemudian tag th:text="${mahasiswa.nim}"
digunakan untuk mengambil nilai nim
pada objek mahasiswa
. Objek mahasiswa dihasilkan ketika mengakses /mahasiswa/detail_form
pada controller. Tampilan detailnya adalah sebagai berikut
Menambahkan Validasi
Validasi sangat penting dibutuhkan untuk memastikan data sebelum di simpan adalah data yang sesuai dengan format yang kita inginkan, validasi dapat dilakukan menggunakan 2 cara yaitu dari sisi client dan dari sisi server. Berikut ini adalah contoh penerapan validasi dari sisi client
<div class="form-group">
<label for="nim" class="col-form-label">Nim</label>
<input type="text" class="form-control" id="nim" th:field="*{nim}" placeholder="Nim mahasiswa" required>
<div class="invalid-feedback">
Nim tidak boleh kosong.
</div>
</div>
Kata kunci yang dibutuhkan menggunakan required
pada tag input
dan kita butuh menambahkan <div class="invalid-feedback">
untuk menampilkan pesan ketika inputan tidak valid. Kemudian jika dari sisi server, sebelumnya telah dituliskan yaitu menggunakan anotasi @Valid.
Berikut ini tampilan ketika data yang diinputkan tidak valid
Menampilkan Alert
Alert kadang disebut juga dengan notifikasi, hal tersebut penting untuk menginfokan sebuah kondisi pada seorang pengguna. Misalkan ketika terjadi error akan menampilkan sebuah pesan error, contoh penggunaannya adalah sebagai berikut
<div th:if="${#fields.hasErrors('all')}">
<div class="form-group">
<div class="alert alert-warning alert-dismissible fade show">
<label th:errors="*{all}">xxx</label>
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
</div>
</div>
Thymeleaf memiliki tag untuk menangkap error ketika atau mendeteksi error, bisa menggunakan th:if="${#fields.hasErrors('all')}
. Sementara untuk menampilkan pesan error digunakan tag th:errors="*{all}"
, hasilnya adalah sebagai berikut
Demikianlah artikel saya mengenai web Java menggunakan Spring Boot dikombinasikan dengan Bootstrap, semoga bermanfaat dan menambah wawasan baru bagi temen-temen yang ingin dan sedang belajar Java. Kritik dan saran sangat diharapkan untuk meningkatkan kwalitas tulisan saya, kode lengkap dapat didapatkan di sini. 🙂
Referensi
- https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/htmlsingle/boot-features-developing-web-applications.html
- https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
- https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc
- https://www.youtube.com/playlist?list=PL9oC_cq7OYbyhdZmCECQqp7OcS8J5QpAo