A. Pendahuluan

Pengelolaan formulir pada Flutter berpusat pada widget Form dan kunci pengendali GlobalKey. Widget Form berfungsi sebagai wadah utama yang membungkus seluruh elemen input agar dapat dikelola dan divalidasi secara bersamaan. Untuk mengakses status dan memicu eksekusi fungsi validasi pada seluruh kolom input secara serentak, digunakan GlobalKey sebagai pengidentifikasi unik dari formulir tersebut.

Dalam mengambil masukan berupa teks, digunakan widget TextFormField yang terintegrasi langsung dengan formulir dan dihubungkan ke TextEditingController. Pengendali ini bertugas membaca dan merekam setiap teks yang diketikkan oleh pengguna. Selain kolom teks, pengisian data pilihan juga dapat memanfaatkan DropdownButtonFormField untuk menyajikan opsi masukan terbatas dari daftar data statis.

Untuk menjaga integritas data, setiap kolom input dilengkapi dengan fungsi validator. Fungsi ini bertugas mengevaluasi masukan pengguna, di mana nilai balik berupa null menandakan bahwa data telah valid dan memenuhi kriteria. Sebaliknya, jika data tidak sesuai atau dibiarkan kosong, fungsi akan mengembalikan nilai berupa pesan kesalahan (string) yang otomatis ditampilkan di bawah kolom input.

B. Tujuan Praktikum

Adapun tujuan dari pelaksanaan praktikum ini adalah sebagai berikut::

  • Menangkap teks dari pengguna via controller.
  • Menerapkan widget dropdown statis.
  • Validasi Input untuk Mencegah data kosong atau format salah.

C. Alat

Perangkat dan dependensi yang digunakan selama praktikum:

  • Flutter SDK
  • Code Editor : VS Code atau Android Studio.
  • Emulator / Device

D. Langkah-langkah Praktikum

1. Membuat Project Flutter

Praktikum diawali dengan membuat project baru dengan nama praktikum3 menggunakan Flutter.

2.Membuat File add_transaction_screen.dart di dalam folder lib

Langkah pertama adalah membuat file baru bernama add_transaction_screen.dart. File ini digunakan untuk membuat halaman formulir pencatatan transaksi yang berisi input judul transaksi, nominal saldo, kategori, serta tombol untuk menyimpan data.

Kode dasar untuk membuat halaman adalah sebagai berikut.

Struktur Dasar Halaman
Thumbnail Java

Kode diatas mengimpor library material.dart yang menyediakan berbagai widget antarmuka Flutter. AddTransactionScreen dibuat sebagai StatefulWidget karena isi form dapat mengalami perubahan. Method createState() digunakan untuk menghubungkan widget dengan class _AddTransactionScreenState yang menangani seluruh state dan proses pada halaman form.

3. Menyiapkan State, GlobalKey, dan Controller

Selanjutnya dibuat class _AddTransactionScreenState yang berfungsi mengatur kondisi halaman. Pada bagian ini dibuat sebuah GlobalKey untuk mengakses dan menjalankan validasi form. Dua buah TextEditingController digunakan untuk mengambil isi dari input judul transaksi dan nominal. Selain itu, dibuat variabel _selectedCategory untuk menyimpan kategori yang sedang dipilih serta list _categories sebagai daftar pilihan kategori.

Menyiapkan State dan Controller
Thumbnail Java

_formKey digunakan untuk mengontrol Form, khususnya ketika proses validasi dijalankan. TextEditingController memungkinkan program mengambil teks yang diketik pengguna tanpa harus mengambil nilai secara manual dari widget. Sementara itu, _selectedCategory memiliki nilai awal Makanan, sehingga ketika form pertama kali dibuka kategori tersebut langsung menjadi pilihan aktif. List _categories berisi seluruh pilihan kategori yang nantinya ditampilkan dalam dropdown.

4. Membersihkan Controller dengan dispose()

Setelah controller digunakan, controller perlu dibersihkan ketika halaman sudah tidak digunakan. Flutter menyediakan method dispose() untuk melakukan proses tersebut.

Membuat dispose()
Thumbnail Java

Method dispose() dipanggil ketika widget sudah dihapus dari widget tree. Pemanggilan dispose() pada masing-masing controller bertujuan melepaskan resource yang digunakan sehingga tidak terjadi penggunaan memori yang tidak diperlukan. Modul juga menjelaskan bahwa controller perlu dibersihkan ketika halaman ditutup untuk mencegah memory leak.

5. Membuat Struktur Halaman dengan Scaffold

Setelah state siap, langkah berikutnya adalah membuat tampilan utama menggunakan Scaffold.

Struktur Dasar Halaman
Thumbnail Java

Scaffold digunakan sebagai struktur utama halaman Flutter. Pada bagian AppBar, ditampilkan judul “Catat Transaksi Baru” dengan warna latar ungu dan teks putih. Bagian body menggunakan SingleChildScrollView agar form tetap dapat digulir ketika keyboard muncul dan ukuran layar menjadi terbatas. Selanjutnya seluruh input dibungkus dengan widget Form dan dihubungkan dengan _formKey, sehingga setiap field di dalamnya dapat divalidasi secara bersamaan.

6. Membuat Input Judul Transaksi

Input pertama digunakan untuk memasukkan judul transaksi.

Input Judul Transaksi
Thumbnail Java

Widget TextFormField digunakan karena selain menerima teks, widget ini juga memiliki fasilitas validasi melalui property validator. Controller _titleController digunakan untuk mengambil nilai yang dimasukkan pengguna. InputDecoration memberikan tampilan berupa label, garis tepi, dan ikon. Pada bagian validator, program memeriksa apakah nilai yang dimasukkan kosong. Jika kosong, validator mengembalikan pesan error sehingga Flutter menampilkan pesan tersebut pada form. Jika data sudah benar, validator mengembalikan null yang berarti tidak terdapat kesalahan.

7. Membuat Input Nominal

Input kedua digunakan untuk memasukkan jumlah nominal transaksi.

Input Nominal
Thumbnail Java

Pada input nominal digunakan TextInputType.number sehingga keyboard yang ditampilkan lebih sesuai untuk memasukkan angka. Selain memeriksa apakah input kosong, validator juga menggunakan int.tryParse() untuk memastikan bahwa nilai yang diberikan benar-benar dapat dikonversi menjadi bilangan bulat. Jika proses konversi gagal, pengguna akan mendapatkan pesan bahwa nominal harus berupa angka yang valid. Dengan demikian, validasi tidak hanya memastikan data terisi, tetapi juga memastikan format data sesuai dengan kebutuhan.

8. Membuat Dropdown Kategori

Selanjutnya dibuat dropdown untuk memilih kategori transaksi.

Dropdown Kategori
Thumbnail Java

DropdownButtonFormField digunakan untuk membuat pilihan kategori yang terintegrasi dengan form. Nilai awal dropdown diambil dari _selectedCategory, sedangkan items dibuat berdasarkan isi list _categories. Method map() digunakan untuk mengubah setiap data kategori menjadi DropdownMenuItem. Ketika pengguna memilih kategori lain, method onChanged dijalankan dan setState() digunakan agar nilai _selectedCategory diperbarui pada tampilan. Ada empat kategori, yaitu Makanan, Transportasi, Hiburan, dan Lainnya.

9. Menambahkan Tombol Simpan

Bagian terakhir dari form adalah tombol untuk menyimpan transaksi sekaligus menjalankan validasi.

Tombol Simpan
Thumbnail Java

ElevatedButton digunakan sebagai tombol utama untuk menyimpan data. Pada onPressed, method _formKey.currentState!.validate() menjalankan seluruh fungsi validator yang terdapat di dalam Form. Jika seluruh input valid, program akan menampilkan SnackBar sebagai notifikasi bahwa transaksi berhasil disimpan. Data judul dan nominal diambil dari masing-masing controller dan ditampilkan di dalam pesan. Jika terdapat input yang tidak valid, proses penyimpanan tidak dilanjutkan dan pesan error akan ditampilkan pada field yang bermasalah.

10. Menghubungkan Halaman dengan main.dart

Setelah halaman form selesai dibuat, langkah berikutnya adalah menghubungkan halaman tersebut dengan file utama main.dart agar dapat diakses pengguna.

Isi file main.dart
Thumbnail Java

Pada bagian awal, file add_transaction_screen.dart diimpor agar class AddTransactionScreen dapat digunakan. runApp() menjalankan aplikasi melalui class MyApp. MaterialApp digunakan sebagai konfigurasi utama aplikasi, termasuk judul dan tema warna. Sementara itu, property home diarahkan ke AddTransactionScreen, sehingga halaman formulir transaksi langsung ditampilkan ketika aplikasi dijalankan.

13. Menjalankan Program

Setelah seluruh kode dibuat, aplikasi dijalankan melalui emulator atau device. Pengujian dilakukan dengan mencoba mengisi judul transaksi, nominal, dan memilih kategori. Kemudian tombol Simpan Transaksi ditekan untuk melihat apakah validasi berjalan sesuai dengan yang diharapkan. Jika seluruh data sesuai, aplikasi menampilkan SnackBar yang menunjukkan data transaksi yang berhasil diproses.

Thumbnail Java

Pengujian juga dilakukan dengan sengaja membiarkan judul atau nominal kosong. Pada kondisi tersebut, validator akan menampilkan pesan kesalahan dan proses penyimpanan tidak dijalankan.

Thumbnail Java

Selain itu, pengujian juga dilakukan dengan memasukkan nilai nominal yang bukan angka. Validator akan menampilkan pesan kesalahan bahwa nominal harus berupa angka yang valid.

Thumbnail Java

Dengan demikian, seluruh mekanisme input, validasi, dan penyimpanan data dapat berjalan sesuai dengan yang diharapkan.

Kode Lengkap File add_transaction_screen.dart
Thumbnail Java
Kode Lengkap File main.dart
Thumbnail Java

LATIHAN - Menambahkan Input Tanggal Transaksi

Pada latihan, ditambahkan satu input baru sebelum tombol Simpan untuk memasukkan Tanggal Transaksi. Modul menyediakan dua pendekatan, yaitu menggunakan TextFormField biasa dengan format DD/MM/YYYY atau menggunakan tombol yang menjalankan fungsi showDatePicker. Selain itu, input tanggal wajib memiliki validasi agar tidak boleh kosong.

Pada implementasi berikut digunakan pendekatan TextFormField yang dilengkapi showDatePicker. Cara ini membuat pengguna tidak perlu mengetik tanggal secara manual karena tanggal dapat dipilih melalui kalender.

Menambahkan Controller Tanggal

Pertama, pada file add_transaction_screen.dart tambahkan controller baru pada class _AddTransactionScreenState.

Thumbnail Java

Controller _dateController digunakan untuk menyimpan tanggal yang dipilih pengguna. Nilai tanggal yang dipilih melalui showDatePicker nantinya diubah menjadi format teks DD/MM/YYYY dan dimasukkan ke controller tersebut.

Menambahkan dispose() untuk Controller Tanggal

Karena telah menambahkan controller baru, controller tersebut juga harus dibersihkan ketika halaman ditutup.

Thumbnail Java

Baris _dateController.dispose() berfungsi melepaskan resource yang digunakan oleh controller tanggal. Dengan demikian, seluruh controller yang dibuat di halaman tersebut dikelola dan dibersihkan dengan benar.

Menambahkan Input Tanggal

Kemudian, tambahkan input tanggal di dalam widget form sebelum tombol Simpan.

Thumbnail Java

TextFormField digunakan sebagai tempat untuk menampilkan tanggal yang telah dipilih. Property readOnly: true membuat pengguna tidak mengetik tanggal secara langsung, tetapi memilihnya melalui kalender. Ketika field ditekan, onTap dijalankan dan showDatePicker() menampilkan kalender. initialDate menggunakan tanggal saat ini sebagai pilihan awal, sedangkan firstDate dan lastDate menentukan rentang tanggal yang dapat dipilih.

Setelah pengguna memilih tanggal, hasilnya disimpan pada variabel pickedDate. Kondisi if (pickedDate != null) memastikan bahwa tanggal benar-benar dipilih sebelum dimasukkan ke controller. Nilai hari dan bulan menggunakan padLeft(2, '0') agar format selalu memiliki dua digit. Contohnya, tanggal 5 Januari 2026 akan ditampilkan sebagai 05/01/2026.

Validator pada input tanggal memeriksa apakah controller kosong. Jika kosong, validator mengembalikan pesan error "Tanggal transaksi wajib diisi." sehingga pengguna akan melihat pesan tersebut di bawah field. Jika tanggal sudah dipilih, validator mengembalikan null yang menandakan tidak ada kesalahan.

Hasil perubahan

Setelah kode latihan dijalankan, form memiliki tambahan field Tanggal Transaksi yang terletak setelah dropdown kategori dan sebelum tombol Simpan Transaksi.

Thumbnail Java

Pengguna dapat menekan field tersebut untuk membuka kalender, kemudian memilih tanggal yang diinginkan. Tanggal yang dipilih akan ditampilkan dalam format DD/MM/YYYY.

Thumbnail Java

Validasi tetap dilakukan ketika tombol Simpan Transaksi ditekan. Artinya, seluruh field pada form harus memenuhi aturan yang telah ditentukan. Judul transaksi dan nominal tidak boleh kosong, nominal harus berupa angka bulat, dan tanggal transaksi wajib dipilih.

Thumbnail Java

Jika semua validasi berhasil, SnackBar menampilkan informasi transaksi beserta tanggal yang telah dipilih.

Thumbnail Java

E. Kesimpulan

Berdasarkan praktikum yang telah dilaksanakan, dapat disimpulkan bahwa praktikum ini memberikan pemahaman mengenai penggunaan Input Widgets dan Forms pada Flutter untuk membangun formulir yang dapat menerima dan mengelola data dari pengguna. Melalui penggunaan TextFormField, DropdownButtonFormField, TextEditingController, dan GlobalKey, data seperti judul transaksi, nominal, dan kategori dapat ditangkap serta diproses dengan lebih terstruktur. Praktikum juga menunjukkan penerapan validasi menggunakan validator untuk memastikan data yang dimasukkan tidak kosong dan memiliki format yang sesuai sebelum diproses.

Pada latihan, formulir dikembangkan dengan menambahkan input Tanggal Transaksi menggunakan showDatePicker. Penambahan ini membuat proses pengisian tanggal lebih mudah sekaligus tetap dapat divalidasi agar wajib diisi. Secara keseluruhan, praktikum ini menunjukkan bahwa Flutter menyediakan widget dan mekanisme yang cukup lengkap untuk membangun form interaktif, menangkap input pengguna, mengatur pilihan data, serta melakukan validasi sehingga data yang diproses menjadi lebih terstruktur dan sesuai kebutuhan aplikasi.

Link Github Project