Kembali ke Portofolio
Mobile App
Published on: 23 September 2026

Laporan Praktikum 3: Input Widgets & Forms (Menangkap Data, Dropdown, dan Validasi)

Pendahuluan

Praktikum ini bertujuan untuk memahami cara menangkap data masukan dari pengguna pada aplikasi Flutter menggunakan 'controller', menerapkan widget dropdown statis untuk pemilihan kategori, serta menerapkan validasi input agar mencegah data kosong atau format yang salah tersimpan ke dalam sistem.

Validasi dilakukan melalui fungsi 'validator' pada setiap 'TextFormField'. Jika fungsi tersebut mengembalikan nilai null, data dianggap valid dan tidak ada error yang ditampilkan. Sebaliknya, jika fungsi mengembalikan sebuah String, data dianggap tidak valid dan pesan error tersebut akan tampil berwarna merah di bawah kolom terkait.

Repository Github
Form & GlobalKey: 'Form' merupakan wadah utama untuk mengelompokkan beberapa input, sedangkan 'GlobalKey<FormState>' digunakan sebagai kunci untuk mengakses dan memicu validasi pada seluruh input sekaligus.
TextFormField: Kolom teks yang mendukung validasi terintegrasi melalui properti 'validator', berbeda dengan 'TextField' biasa yang tidak memiliki fitur validasi bawaan.
TextEditingController: Pengendali yang digunakan untuk membaca dan mengelola teks yang diketik pengguna pada sebuah 'TextFormField'.
Validator: Fungsi yang memeriksa isi kolom. Mengembalikan nilai null berarti data valid, sedangkan mengembalikan sebuah String berarti data tidak valid dan pesan tersebut akan ditampilkan sebagai error.

Langkah Kerja

1. Persiapan State & Controller

Membuat file baru bernama 'add_transaction_screen.dart'. Karena isi formulir (teks & dropdown) akan terus berubah saat pengguna mengetik, dibuat class 'AddTransactionScreen' yang meng-extend 'StatefulWidget'. Pada class state-nya, '_AddTransactionScreenState', disiapkan 'GlobalKey<FormState>' bernama '_formKey' untuk memicu validasi, serta dua 'TextEditingController' ('_titleController' dan '_amountController') untuk judul dan nominal transaksi, ditambah variabel '_selectedCategory' dengan nilai default 'Makanan' untuk dropdown.

placeholder-modul3-langkah1 placeholder-modul3-langkah1
2. Membuat Kolom Input (TextFormField)

Membungkus seluruh kolom input dengan widget 'Form' dan menghubungkan properti 'key' ke '_formKey'. Setiap 'TextFormField' dihubungkan dengan 'controller' masing-masing: kolom "Judul Transaksi" divalidasi agar tidak boleh kosong, sedangkan kolom "Nominal (Rp)" menggunakan 'keyboardType: TextInputType.number' serta validasi wajib diisi dan harus berupa angka menggunakan 'int.tryParse()'.

placeholder-modul3-langkah2
3. Dropdown & Tombol Simpan

Menambahkan 'DropdownButtonFormField<String>' untuk memilih kategori transaksi (Makanan, Transportasi, Hiburan, Lainnya), dengan 'value' terhubung ke '_selectedCategory' dan 'onChanged' memanggil 'setState()' untuk memperbarui pilihan. Selanjutnya ditambahkan 'ElevatedButton' dengan 'onPressed' yang memanggil '_formKey.currentState!.validate()' untuk menjalankan seluruh validator; jika semua input valid, akan muncul 'SnackBar' berwarna hijau sebagai notifikasi transaksi berhasil disimpan.

placeholder-modul3-langkah3 placeholder-modul3-langkah3

Terakhir, seluruh formulir dibungkus dengan 'SingleChildScrollView' agar layar tidak mengalami error layout saat keyboard muncul. Berikut adalah full code dan tampilan hasil akhir mockup formulir setelah dijalankan:

placeholder-modul3-hasil-akhir placeholder-modul3-hasil-akhir placeholder-modul3-hasil-akhir placeholder-modul3-hasil-akhir

dan ini code dari main.dart:

placeholder-modul3-tugas1
4. Latihan/Tugas: Input Tanggal

Menambahkan satu input baru sebelum tombol "Simpan Transaksi" untuk mengisi Tanggal Transaksi. Input dibuat menggunakan 'TextFormField' biasa dengan format teks DD/MM/YYYY, dilengkapi tombol ikon (misalnya ikon kalender) yang memanggil fungsi 'showDatePicker' agar pengguna dapat memilih tanggal melalui date picker bawaan Flutter. Kolom ini juga diberi 'validator' agar wajib diisi sebelum transaksi dapat disimpan.

placeholder-modul3-tugas1 placeholder-modul3-tugas1 placeholder-modul3-tugas1 placeholder-modul3-tugas1 placeholder-modul3-tugas1