Belajar Flutter Basic #4: Form & Validation

Belajar Flutter Basic #4: Form & Validation

Pendahuluan

Interaksi yang sering kali dilakukan dalam sebuah aplikasi adalah mengisi form, sebut saja ketika akan checkout dari sebuah transaksi e-commerce maka yang akan dilakukan adalah mengisi data pelanggan, ketika akan login kedalam sebuah aplikasi yang mengharuskan untuk login maka user harus mengisi form tersebut.

Tak lengkap rasanya jika sebuah form hanyalah sebuah form biasa saja tanpa dilengkapi dengan fitur validation. Sebab sering kali dan wajib untuk didengungkan oleh seorang programmer adalah "don't trust user input". Pada kesempatan kali ini, kita akan belajar bersama bagiamana cara membuat sebuah form, meng-handlenya, dan membuat validation menggunakan Flutter.

Baca Juga: Belajar Flutter Basic #3: Membuat Tabs

Membuat Form Input Dengan Flutter

Tahap awal kita akan membuat sebuah form input untuk user dengan menggunakan widget yang telah disediakan oleh Flutter. Sebab ini bukanlah case yang berkelanjutan, maka kita akan memulainya kembali dengan Flutter fresh install.

flutter create register

Buka file main.dart yang terletak didalam folder lib, kemudian modifikasi menjadi:

import 'package:flutter/material.dart';
import 'src/app.dart';

void main() {
  runApp(App());
}

Perhatikan, ada request sebuah class bernama App() pada line 5, dimana class tersebut terletak di dalam file app.dart. Buat file app.dart di dalam folder lib/src, kemudian tambahkan code berikut:

import 'package:flutter/material.dart';
import 'screens/register.dart';

class App extends StatelessWidget {
  Widget build(context) {
    return MaterialApp(
      title: 'Registrasi Daengweb',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Form Registrasi'),
        ),
        body: RegisterScreen(),
      ),
    );
  }
}

Note: Code diatas sudah pernah dibahas pada materi sebelumnya, yang perlu diperhatikan adalah pada bagian body terdapat request class RegisterScreen(). Pada line-2 kita meng-import file register.dart dari folder screens.

Buat folder screens di dalam folder lib/src, kemudian pada folder screens buat file bernama register.dart, kemudian letakkan code berikut:

import 'package:flutter/material.dart';

class RegisterScreen extends StatefulWidget {
  createState() {
    return RegisterScreenState();
  }
}

class RegisterScreenState extends State<RegisterScreen> {

  Widget build(context) {
    return Container(
      margin: EdgeInsets.all(20.0), //SET MARGIN DARI CONTAINER 
      child: Form( 
        child: Column( 
          //CHILDREN DARI COLUMN BERISI 4 BUAH OBJECT YANG AKAN DI-RENDER, YAKNI
          // TextInput UNTUK NAME, EMAIL, PASSWORD DAN TOMBOL DAFTAR
          children: [
            nameField(),
            emailField(),
            passwordField(),
            registerButton(),
          ],
        )
      ),
    );
  }

  Widget nameField() {
    //MEMBUAT TEXT INPUT 
    return TextFormField(
      decoration: InputDecoration(
        labelText: 'Nama Lengkap' //DENGAN LABEL Nama Lengkap
      ),
      //AKAN BERISI VALIDATION
    );
  }

  Widget emailField() {
    return TextFormField(
      keyboardType: TextInputType.emailAddress, // KEYBOARD TYPENYA ADALAH EMAIL ADDRESS
      //AGAR SYMBOL @ DILETAKKAN DIDEPAN KETIKA KEYBOARD DI TAMPILKAN
      decoration: InputDecoration(
        labelText: 'Email',
        hintText: '[email protected]',
      ),
      //AKAN BERISI VALIDATION
    );
  }

  Widget passwordField() {
    return TextFormField(
      obscureText: true, //KETIKA obsecureText bernilai TRUE
      //MAKA SAMA DENGAN TYPE PASSWORD PADA HTML
      decoration: InputDecoration(
        labelText: 'Password',
        hintText: 'Enter Password',
      ),
      //AKAN BERISI VALIDATION
    );
  }

  Widget registerButton() {
    //MEMBUAT TOMBOL
    return RaisedButton(
      color: Colors.blueAccent, //MENGATUR WARNA TOMBOL
      onPressed: () {
        //PERINTAH YANG AKAN DIEKSEKUSI KETIKA TOMBOL DITEKAN
      },
      child: Text('Daftar'), //TEXT YANG AKAN DITAMPILKAN PADA TOMBOL
    );
  }
}

Note: Children dari widget Column() berisi 4 buah helper yakni: nameFiled(), emailField(), passwordField(), dan registerButton(). Dimana masing-masing helpers tersebut berisi widget sesuai dengan perutukannya. Sebenarnya bisa saja widget tersebut langsung diletakkan didalam children dari Column(), hanya saja untuk memudahkan kita dalam meng-handle masing-masing Form Input, maka kita pisahkan agar terlihat lebih rapi.

Sampai pada tahap ini, kita telah berhasil membuat 3 buah form input dan 1 buah tombol untuk register. Kamu dapat melihatnya dengan menjalankan command: flutter run. Akan tetapi, ketika tombol tersebut ditekan, belum terjadi apa-apa karena pada property onPressed() masing kosong. Maka selanjutnya, kita akan membuat fungsi validation & meng-handle data yang telah di-input oleh user.

Baca Juga: Belajar Flutter Basic #2: Layout Menggunakan Widget

Membuat Form Validation

Terdapat 3 buah text input yang akan di-validasi, sedangkan untuk fungsi untuk validation dari masing-masing form tersebut akan kita pisahkan pada file tersendiri agar dapat digunakan kembali pada form yang lainnya. Buat folder mixins di dalam folder lib/src, kemudian pada folder mixins buat sebuah file bernama validation.dart:

class Validation {
  // FUNGSI validatePassword > NAMA FUNGSI BEBAS
  String validatePassword(String value) { //MENERIMA VALUE DENGAN TYPE STRING
    if (value.length < 4) { //VALUE TERSEBUT DI CEK APABILA KURANG DARI 6 KARAKTER
      return 'Password Minimal 4 Karakter'; //MAKA ERROR AKAN DITAMPILKAN
    }
    return null; //SELAIN ITU LOLOS VALIDASI
  }

  String validateEmail(String value) {
    if (!value.contains('@')) { //JIKA VALUE MENGANDUNG KARAKTER @
      return 'Email tidak valid'; //MAKA PESAN DITAMPILKAN
    }
    return null;
  }

  String validateName(String value) {
    if (value.isEmpty) { //JIKA VALUE KOSONG 
      return 'Nama Lengkap Harus Diisi'; //MAKA PESAN DITAMPILKAN
    }
    return null;
  }
}

Kembali pada file register.dart, import file yang baru saja dibuat:

import '../mixins/validation.dart';

Kemudian use class Validation pada pada class RegisterScreenState() menggunakan with

class RegisterScreenState extends State<RegisterScreen> with Validation { //VALIDATION ADALAH NAMA CLASS YANG TELAH DIBUAT SEBELUMNYA
    
  final formKey = GlobalKey<FormState>(); //MEMBUAT GLOBAL KEY UNTUK VALIDASI 
  
  // DEFINE VARIABLE
  String name = '';
  String email = '';
  String password = '';
  
  
  // CODE LAINNYA YANG TELAH DIBUAT ...
}

Masih dengan file register.dart, gunakan global key yang telah didefinisikan pada widget Form()

...

Widget build(context) {
    return Container(
      margin: EdgeInsets.all(20.0),
      child: Form(
        key: formKey, //MENGGUNAKAN GLOBAL KEY
        child: Column(
          children: [
            nameField(),
            emailField(),
            passwordField(),
            registerButton(),
          ],
        )
      ),
    );
  }

...

Terakhir, kita akan memodifikasi masing-masing helpers dengan menambahkan property validator

...

Widget nameField() {
    return TextFormField(
      decoration: InputDecoration(
        labelText: 'Nama Lengkap'
      ),
      validator: validateName, //validateName ADALAH NAMA FUNGSI PADA FILE validation.dart
      onSaved: (String value) { //KETIKA LOLOS VALIDASI
        name = value; //MAKA VARIABLE name AKAN DIISI DENGAN TEXT YANG TELAH DI-INPUT
      },
    );
  }

  Widget emailField() {
    return TextFormField(
      keyboardType: TextInputType.emailAddress,
      decoration: InputDecoration(
        labelText: 'Email',
        hintText: '[email protected]',
      ),
      validator: validateEmail, //BERLAKU SAMA DENGAN HELPERS SEBELUMNYA
      onSaved: (String value) {
        email = value;
      },
    );
  }

  Widget passwordField() {
    return TextFormField(
      obscureText: true,
      decoration: InputDecoration(
        labelText: 'Password',
        hintText: 'Enter Password',
      ),
      validator: validatePassword, ////BERLAKU SAMA DENGAN HELPERS SEBELUMNYA
      onSaved: (String value) {
        password = value;
      },
    );
  }

  Widget registerButton() {
    return RaisedButton(
      color: Colors.blueAccent,
      onPressed: () {
        //formKey ADALAH GLOBAL KEY, KEMUDIAN DIIKUTI DENGAN currentState
        //LALU METHOD validate(), NILAINYA ADALAH FALSE / TRUE
        if (formKey.currentState.validate()) { //JIKA TRUE
          formKey.currentState.save(); //MAKA FUNGSI SAVE() DIJALANKAN
          
          //DISINI KAMU BISA MENGHANDLE DATA YANG SDH DITAMPUNG PADA MASING-MASING VARIABLE
          //KAMU DAPAT MENGIRIMNYA KE API ATAU APAPUN
          //NAMUN UNTUK SEMENTARA KITA PRINT KE CONSOLE SAJA
          //KARENA BELUM MEMBAHAS TENTANG HTTP REQUEST
          print('Nama lengkap: $name');
          print('Email: $email');
          print('Passwor: $password');
        }
      },
      child: Text('Daftar'),
    );
  }

...

Rebuild aplikasi yang sedangkan kita buat dengan menekan tombol shift + r, maka hasil yang akan diperoleh ketika validasi gagal terlihat seperti ini.

membuat form di flutter

Sedangkan jika berhasil maka akan tampak seperti ini

membuat validasi form di flutter

Kesimpulan

Flutter menyediakan widget catalog yang siap untuk digunakan sesuai dengan kebutuhan penggunanya, kita hanya perlu merangkainya menjadi bagian bagian yang di-inginkan. Sepanjang artikel ini kita telah belajar bagaimana membuat Text Input, Handle user input with form, membuat validasi, menampung value yang telah di-input kedalam variable dan yang terpenting adalah bagaimana berkomunikasi antar file sehingga kita dapat memisahkan bagian bagian yang di-inginkan agar tidak tertumpuk pada satu file yang sama, sehingga akan lebih mudah untuk di maintenance.

Ohya kamu dapat melihat dokumentasi code dari artikel ini di Github.

Category:
Share:

Comments