1.1 Tujuan
Tujuan praktikum ini yaitu mahasiswa mampu membuat basic form untuk menerima inputan dari keyboard dan
mengelola inputan:
1.2 Alat
Basic Form merupakan widget yang berfungsi sebagai inputan nilai seperti TextField, TextFormField, CheckBox, Switch, Dropdown, Radio, Dialog, DatePicker, BottomSheet, Snackbar dan lain-lain. Basic Form digunakan untuk validasi dan mengelola inputan dari berbagai field.
Form akan memberikan tampilan inputan kemudian inputan akan diperiksa apakah sudah sesuai dengan aturan atau format yang ditetapkan, selanjutnya data inputan akan diambil nilainya setelah proses pengecekan selesai dilakukan.
TextField adalah widget yang digunakan untuk memasukkan teks oleh pengguna, biasanya digunakan untuk membuat form inputan seperti login, pencarian, dll.
TextEditingControllerTextField(
decoration: InputDecoration(
labelText: 'Nama Lengkap',
hintText: 'Misalnya masnoer',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
controller: _textEditingController,
keyboardType: TextInputType.text,
onChanged: (text) {
print('Sedang mengetik teks: $text');
},
)
TextFormField adalah versi lengkap dari TextField yang terintegrasi dengan logika validasi dan manajemen state dari sebuah form.
validator untuk memeriksa inputFormState untuk validasi kolektifTextFormField(
controller: _nameController,
decoration: InputDecoration(
labelText: "Nama : ",
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan nama anda';
}
return null;
},
)
GlobalKey digunakan untuk mengakses state widget secara global. Dengan
FormState, kita bisa memanggil metode seperti validate() atau
save() dari luar widget.
Metode validate() digunakan untuk menjalankan validasi pada setiap TextFormField
dalam Form. Jika semua validator mengembalikan null, maka hasilnya
true; jika ada error, akan mengembalikan false dan menampilkan pesan error.
setState() digunakan untuk memberitahu Flutter bahwa ada perubahan state pada
StatefulWidget dan perlu dilakukan rebuild.
setState(() {
// perubahan state
});
Kata kunci const digunakan untuk membuat widget menjadi konstanta saat kompilasi. Ini
meningkatkan performa karena widget tidak akan di-rebuild jika tidak berubah.
// Non-const
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Center(
child: Text('Hello World!'),
),
);
}
// Const
Widget build(BuildContext context) {
return const Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Center(
child: Text('Hello World!'),
),
);
}
form-textfield.dart di dalam folder lib.import 'package:flutter/material.dart';
class FormApp extends StatelessWidget {
const FormApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Basic Form')),
body: const MyForm(),
),
);
}
}
class MyForm extends StatefulWidget {
const MyForm({super.key});
@override
State<MyForm> createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Masukkan nama anda :'),
const SizedBox(height: 10),
const TextField(
decoration: InputDecoration(
labelText: 'Nama Lengkap',
hintText: 'Misalnya masnoer',
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.person),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.amber,
foregroundColor: Colors.black,
),
child: const Text('Tampilkan mama'),
),
],
),
);
}
}
import 'package:flutter/material.dart';
class LoginForm extends StatelessWidget {
const LoginForm({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Basic Form TextFormField")),
body: const MyFormText(),
),
);
}
}
class MyFormText extends StatefulWidget {
const MyFormText({super.key});
@override
State<MyFormText> createState() => _MyFormTextState();
}
class _MyFormTextState extends State<MyFormText> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
String name = _nameController.text;
String email = _emailController.text;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Validasi $name, $email Berhasil')),
);
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 10),
TextFormField(
controller: _nameController,
decoration: const InputDecoration(
labelText: "Nama : ",
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan nama anda';
}
return null;
},
),
const SizedBox(height: 10),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
labelText: "Email : ",
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Masukkan email anda ';
}
if (!value.contains('@')) {
return 'Email tidak valid';
}
return null;
},
),
const SizedBox(height: 10),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _submitForm,
child: const Text('Submit'),
),
),
],
),
),
);
}
}
Buatlah form pendaftaran pengguna dengan menggunakan 4 buah form yaitu nama, email, password, confirm password, dan satu tombol submit.
main.dart dan user_registration_form.dartmain.darthome ke widget UserRegistrationFormUserRegistrationFormvalidator untuk
validasi@onPressed dan ketika tombol ditekan akan memanggil _submitForm
import 'package:flutter/material.dart';
class RegisterWidget extends StatefulWidget {
const RegisterWidget({super.key});
@override
State<RegisterWidget> createState() => _RegisterWidgetState();
}
class _RegisterWidgetState extends State<RegisterWidget> {
final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmController = TextEditingController();
final _usernameController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
_confirmController.dispose();
_usernameController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
print(
'Registering: ${_usernameController.text}, ${_emailController.text}',
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Mendaftarkan ${_usernameController.text}...')),
);
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(40.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Nama pengguna',
prefixIcon: Icon(Icons.person),
),
controller: _usernameController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Tidak boleh kosong!';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email),
),
controller: _emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email wajib diisi';
} else if (!emailRegex.hasMatch(value)) {
return 'Format email tidak valid';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(
labelText: 'Kata sandi',
prefixIcon: Icon(Icons.lock),
),
controller: _passwordController,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Kata sandi wajib diisi';
}
if (value.length < 6) {
return 'Kata sandi tidak boleh kecil dari 6';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
decoration: const InputDecoration(
labelText: 'Konfirmasi kata sandi',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
controller: _confirmController,
validator: (value) => value == _passwordController.text
? null
: 'Kata sandi tidak cocok',
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _submitForm,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 32,
vertical: 14,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 6,
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
letterSpacing: 1.2,
),
),
child: const Text('Daftar Sekarang'),
),
],
),
),
);
}
}