flutter crud simpan

Tutorial Flutter kali ini akan mempelajari bagaimana membuat CRUD untuk fungsi simpan menggunakan database SQL Lite.

Table of Contents

CRUD?

CRUD adalah singkatan dari Create, Read, Update dan Delete. CRUD merupakan sebuah fungsi-fungsi dasar dalam membuat sebuah aplikasi, didalam aplikasi tentunya akan terdapat fungsi-fungsi untuk melakukan simpan data, menampilkan data, mengubah maupun menghapus data yang terdapat didalam database, fungsi-fungsi tersebut dikenal dengan istilah CRUD.

Untuk menggunakan CRUD kita membutuhkan sebuah database, baik dalam ukuran besar maupun kecil. Pada tutorial kali ini kita akan menggunakan sebuah database yang memiliki ukuran kecil yaitu SQL Lite yang terdapat pada Framework Flutter yaitu plugin sqflite.

Bagi kalian yang belum mengenal SQL Lite, kalian bisa mempelajari lebih jauh dengan mengunjungi link ini.

Let’s get started…!!!

Untuk memulai tutorial ini, kita buka project yang telah dibuat sebelumnya. Jika kalian belum membuat project tersebut, kalian bisa mengikuti link berikut ini terlebih dahulu.

Tutorial ini merupakan lanjutan dari tutorial sebelumnya, jadi pastikan kalian mengikuti dan telah membuat form input yang ada pada postingan sebelumnya disini.

Baiklah, kita mulai dengan membuat sebuah model kelas karyawan. Buatlah sebuah folder didalam lib dengan nama Model, didalam folder tersebut buatlah file dengan nama KaryawanModel.dart.

Buat beberapa properti seperti Nama, Telp, Email, Departmen dan Jabatan, berikut isi file tersebut.

Karyawan Model

class KaryawanModel
{
  final int id;
  final String nama;
  final String telp;
  final String email;
  final int department;
  final int jabatan;

  KaryawanModel({
    this.id,
    this.nama,
    this.telp,
    this.email,
    this.department,
    this.jabatan,
  });

  Map<String, dynamic> mapToDbClient(){
    return {
      "ID": this.id,
      "Nama": this.nama,
      "Telp": this.telp,
      "Email": this.telp,
      "Department": this.department,
      "Jabatan": this.jabatan
    };
  }

  factory KaryawanModel.fromMap(Map<String, dynamic> map) {
    final data = KaryawanModel(
      id: map["ID"],
      nama: map["Nama"],
      telp: map["Telp"],
      email: map["Email"],
      department: map["Department"],
      jabatan: map["Jabatan"]
    );
    return data;
  }

}

Selanjutnya, kita buat sebuah kelas baru untuk mendeklarasikan database sqllite serta membuat beberapa fungsi didalamnya. Sebelumnya, kita harus menambahkan plugin sqflite ke dalam file pubspec.yml.

sqflite: ^1.2.0
path_provider: ^1.3.0

Masukkan baris code tersebut pada bagian dependenies.

Setelah plugin terpasang, maka buatlah folder baru dengan nama Repository lalu buat file didalamnya dengan nama DbLite.dart dan masukkan kode berikut.

DB Lite

import 'dart:async';
import 'dart:io' as io;

import 'package:belajar_flutter_karywan_app/Model/KaryawanModel.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';

class DbLite{
  static final DbLite _instance = new DbLite.internal();
  factory DbLite() => _instance;

  static Database _db;

  Future<Database> get db async{
    if(_db != null)
      return _db;
    _db = await initDb();
    return _db;
  }
  
  DbLite.internal();

  initDb() async{
    io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
    String path = join(documentsDirectory.path, "dbbelajar.db");
    var theDB = await openDatabase(path, version: 1, onCreate: _onCreate);
    return theDB;
  }

  //create db table
  void _onCreate(Database db, int version) async{
    String dbCreate = "CREATE TABLE Karyawan(ID INTEGER PRIMARY KEY AUTOINCREMENT, Nama TEXT, Telp TEXT, Email TEXT, Department int, Jabatan int)";
    await db.execute(dbCreate);
    print("sukses crate table: " + dbCreate);
  }

  //simpan data karyawan
  Future<int> saveKaryawan(KaryawanModel karyawanModel) async{
    var dbClient = await db;
    int res = await dbClient.insert("Karyawan", karyawanModel.mapToDbClient());
    return res;
  }

  //select data karyawan
  Future<List<KaryawanModel>> getDataKaryawan() async{
    var dbClient = await db;
    List<KaryawanModel> list = List<KaryawanModel>(); 
    List<Map> res = await dbClient.query("Karyawan");
    list = res.map((i) => KaryawanModel.fromMap(i)).toList();
    return list;
  }

}

Perhatikan pada file tersebut, terdapat beberpa fungsi didalamnya, yaitu initDb, fungsi ini nantinya akan membuat sebuah database yaitu dbbelajar.db. Kemudian ada _onCreate, ini berfungsi untuk membuat sebuah table dengan nama Karyawan, script pembuatan table menggunakan bahasa sql pada umunnya.

Dan untuk fungsi saveKaryawan dan getDataKaryawan ini berfungsi untuk menyimpan dan menampilkan data yang telah tersimpan.

Baiklah kita sekarang telah memiliki sebuah model kelas dari form karyawan dan juga database serta tablenya. Selanjutnya, kita perlu mengubah form karyawan yang sebelumnya telah dibuat untuk kita masukkan fungsi simpan yang berada pada file DbLite.

Karyawan Form

import 'package:belajar_flutter_karywan_app/MainMenu.dart';
import 'package:belajar_flutter_karywan_app/Model/KaryawanModel.dart';
import 'package:belajar_flutter_karywan_app/Repository/DbLite.dart';
import 'package:belajar_flutter_karywan_app/WidgetHelper/PopupHelper.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

class Karyawan extends StatefulWidget {
 const Karyawan({Key key}) : super(key: key);
  
  @override
  _KaryawanState createState() => new _KaryawanState();
}

class _KaryawanState extends State<Karyawan>{
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  final _ctrTxtName = TextEditingController(), 
        _ctrTxtPhone = TextEditingController(),
        _ctrTxtEmail = TextEditingController();

  int _idDepartment, _idJabatan;
  List<DropdownClass> _jabatan = new List<DropdownClass>();
  List<DropdownClass> _department = new List<DropdownClass>();
    
  
  @override
  void initState() {

    final db = new DbLite(); 
    db.getDataKaryawan().then((value) {
      print(value);
    });   
   
    //list jabatan
    _jabatan.add(new DropdownClass(0, "Officer"));
    _jabatan.add(new DropdownClass(1, "Senior Officer"));
    _jabatan.add(new DropdownClass(2, "Assistant Manager"));
    _jabatan.add(new DropdownClass(3, "Manager"));
   
    //list department
    _department.add(new DropdownClass(0, "Operation"));
    _department.add(new DropdownClass(1, "Marketing"));
    _department.add(new DropdownClass(2, "IT"));
    _department.add(new DropdownClass(3, "SDM"));
   super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final _width = MediaQuery.of(context).size.width;
    final _height = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: AppBar(
        title: Text("Form Karyawan"),
        backgroundColor: Colors.redAccent,
        elevation: 0.0,
      ),
      body: Container(
        color: Colors.white,
        height: _height,
        width: _width,
        child: Scaffold(
          backgroundColor: Colors.white,
          body: new SingleChildScrollView(
            child: Form(
              key: _formKey,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(top: 20.0, right: 180.0),
                        child: Text("Input Data", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),)
                      ),
                    ]
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0, right: 45.0, left: 45.0),
                    child: new TextFormField(
                      controller: _ctrTxtName,
                      decoration:  InputDecoration(
                        labelText: 'Nama', 
                        icon: Icon(Icons.person),
                      ),
                      style: new TextStyle(color: Colors.redAccent),
                      keyboardType: TextInputType.text,
                      validator: (value){
                        return _validateName(value);
                      },
                    ),
                  ),  
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0, right: 45.0, left: 45.0),
                    child: new TextFormField(
                      controller: _ctrTxtPhone,
                      decoration: const InputDecoration(labelText: 'No Telp', icon: Icon(Icons.phone)),
                      keyboardType: TextInputType.number,
                      maxLength: 12,
                      style: new TextStyle(color: Colors.redAccent),
                      validator: (value){
                        return _validateTelp(value);
                      },
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0, right: 45.0, left: 45.0),
                    child: new TextFormField(
                      controller: _ctrTxtEmail,
                      decoration: const InputDecoration(labelText: 'Email', icon: Icon(Icons.email)),
                      keyboardType: TextInputType.emailAddress,
                      style: new TextStyle(color: Colors.deepOrange),
                      validator: (value){
                        return _validateEmail(value);
                      },
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0, right: 45.0, left: 45.0),
                      child: new FormField(
                      builder: (FormFieldState state) {
                        return InputDecorator(
                          decoration: InputDecoration(
                            icon: const Icon(Icons.business),
                            labelText: 'Department',
                          ),
                          child: new DropdownButtonHideUnderline(
                            child: new DropdownButton(
                              isDense: true,
                              onChanged: (newValue) {
                                setState(() {
                                  _idDepartment = newValue;
                                });
                              },
                              items: _department.map((item) {
                                return DropdownMenuItem(
                                  child: Text(item.value),
                                  value: item.id,
                                );
                              }).toList(),
                              value: _idDepartment,
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0, right: 45.0, left: 45.0),
                      child: new FormField(
                      builder: (FormFieldState state) {
                        return InputDecorator(
                          decoration: InputDecoration(
                            icon: const Icon(Icons.recent_actors),
                            labelText: 'Jabatan',
                          ),
                          child: new DropdownButtonHideUnderline(
                            child: new DropdownButton(
                              value: _idJabatan,
                              isDense: true,
                              onChanged: (newValue) {
                                setState(() {
                                  _idJabatan = newValue;
                                });
                              },
                              items: _jabatan.map((item) {
                                return DropdownMenuItem(
                                  child: Text(item.value),
                                  value: item.id,
                                );
                              }).toList(),
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(top: 20.0, bottom: 20.0),
                        child: SizedBox(
                          width: 300.0, // match_parent
                          child: new RaisedButton(
                            onPressed: (){
                              if(_formKey.currentState.validate()){
                                
                                var karyawanModel = new KaryawanModel(nama: _ctrTxtName.text.trim(), 
                                  telp: _ctrTxtPhone.text.trim(), email: _ctrTxtEmail.text.trim(),
                                  department: _idDepartment, jabatan: _idJabatan);
                                _saveKaryawan(karyawanModel);
                              }

                            },
                            color: Colors.blue,
                            textColor: Colors.white,
                            child: new Text('Simpan'),
                            shape: RoundedRectangleBorder(
                              borderRadius: new BorderRadius.circular(20.0),
                            ),
                          ),
                        )
                      ),
                    ],
                  )
                ],
              ),
            ) 
          )
        ),
      ),
    );
  }

  //validasi
  String _validateName(String value) {
    if (value.length < 3)
      return 'Nama maksimal lebih dari 3 karakter';
    else
      return null;
  }

  String _validateTelp(String value) {
    if (value.length != 12)
      return 'Nomor telp harus berisi 12 digit';
    else
      return null;
  }

  String _validateEmail(String value) {
    Pattern pattern =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regex = new RegExp(pattern);
    if (!regex.hasMatch(value))
      return 'Alamat email tidak benar';
    else
      return null;
  }

  //fungsi save 
  void _saveKaryawan(KaryawanModel karayawanModel){
    final db = new DbLite(); 
    PopupHelper().alertDialogCuprtino(context, "Mohon tunggu...");
    db.saveKaryawan(karayawanModel).then((value){
      if(value > 0){
        Navigator.of(context, rootNavigator: true).pop();
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return new WillPopScope(
                onWillPop: () async => false,
                child: new CupertinoAlertDialog(
                title: new Text("Yeay, data berhasil disimpan", style: TextStyle(fontSize: 12), ),
                actions: <Widget>[
                  new FlatButton(
                    onPressed: (){
                      Navigator.of(context).push(MaterialPageRoute(builder: (context) => 
                          new MainMenu() 
                        )
                      );
                    },
                    child: new Text("Ok"),
                  )
                ],
              ),
            );
          }
        );
      }else{
        Navigator.of(context, rootNavigator: true).pop();
        PopupHelper().alertDialogCuprtinoMsg(context, "Oops, terjadi kesalahan!");
      }
    }); 
  }
}

class DropdownClass {
  final int id;
  final String value;
  
  DropdownClass(this.id, this.value);
}

Pada form karyawan, kita menambahkan Widget Form serta membuat validasi untuk setiap input yang ada pada form tersebut. Pada baris kode bagian bawah kita juga membuat fungsi baru yaitu _saveKaryawan, pada fungsi tersebut kita panggil fungsi sumpan, dan juga terdapat widget dialog.

Widget Dialog ini digunakan untuk menampilkan loading pada saat proses simpan dilakukan, ketika proses simpan berhasil ataupun terdapat error, maka akan muncul dialog baru berisi informasi proses simpan apakah berhasil atau gagal.

Nah untuk menampilkan Widget Dialog ini, kita perlu membuat sebuah file baru. Buat sebuah folder dengan nama WidgetHelper dan buat file PopupHelper.dart didalamnya.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class PopupHelper {

  void alertDialogCuprtino(BuildContext context, String sType){
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return new WillPopScope(
          onWillPop: () async => false,
          child: new CupertinoAlertDialog(
          title: new Text(sType),
          content: new CupertinoActivityIndicator(radius: 13.0),
        ),
        );
      }
    );
  }

  void alertDialogCuprtinoMsg(BuildContext context, String sMsg){
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return new WillPopScope(
            onWillPop: () async => false,
            child: new CupertinoAlertDialog(
            title: new Text(sMsg, style: TextStyle(fontSize: 12), ),
            actions: <Widget>[
              new FlatButton(
                onPressed: (){
                  Navigator.of(context).pop();
                },
                child: new Text("Ok"),
              )
            ],
          ),
        );
      }
    );
  }
}

Oke, setelah kita membuat semua file diatas, kita coba jalankan project tersebut. Maka kita sudah bisa melakukan simpan data karyawan.

flutter crud simpan

Woowww, that’s cool brooo.

babagih congratulation

Selamat anda telah berhasil membuat salah satu fungsi CRUD yaitu simpan. Dalam tutorial ini kita telah mempelajari beberapa hal berikut:

  1. Membuat sebuah kelas model
  2. Membuat Database dan Table SQL Lite
  3. Membuat Form Validasi Input
  4. Membuat Popup Loading dan Memunculkan pesan.

Oke pada tutorial selanjutnya kita akan aplikasi fungsi CRUD lainnaya itu membaca data dan menampilkannya ke layar serta edit data.

Terimakasih, semoga bermanfaat.

Advertisements
Share: