flutter crud hapus

Setelah sebelumnya kita sudah membuat fungsi Simpan, pada tutorial flutter kali ini kita melanjutkan bagaimana membuat fungsi Hapus yang merupakan bagian dari CRUD.

Table of Contents

Penjelasan Singkat

Fungsi hapus merupakan bagian dari CRUD, dimana fungsi ini akan melakukan penghapusan data pada sebuah database. Pembuatan script fungsi ini juga sangatlah mudah, seperti script sql pada umunnya seperti berikut ini:

delete from Karyawan where id = 1

Dalam plugin sqflite kita dapat menggunakan 2 pendekatan, pertama menggunakan statement sql seperti diatas dan yang kedua dapat menggunakan fungsi bawaan dari plugin tersebut, berikut ini contohnya:

await dbClient.delete("Karyawan", where: "id = ?", whereArgs: [id]);

Pembuatan fungsi tersebut dimaksudkan untuk mempermudah programmer dalam membuat fungsi sql pada umumnya, jika kalian mencoba untuk melakukan debug pada fungsi tersebut, plugin sqflite akan secara otomatis merubah fungsi yang dibuat menjadi sebuah perintah sql.

Sama seperti fungsi simpan sebelumnya dimana kita hanya perlu menambahkan method insert kemudian masukkan model yang telah kita mapping terhadap setiap kolom yang ada pada table.

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

Sqflite memberikan kemudahan bagi programmer untuk membuat fungsi CRUD menjadi lebih mudah dan sederhana. Baiklah mari kita mulai membuat fungsi hapus dan tentunya menampilkan data yang akan di hapus.

Let’s get started…!!!

Pertama kita membutuhkan plugin baru yaitu Slidable untuk menampilkan aksi yang akan kita buat. Masukkan plugin berikut kedalam file pubspec.yaml.

flutter_slidable: ^0.5.4

Setelah plugin dimasukkan, selanjutnya buat file baru untuk untuk menampilkan data karyawan dengan nama KaryawanReport.dart, kemudian masukkan kode berikut.

Karyawan Report

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';
import 'package:flutter_slidable/flutter_slidable.dart';

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

class _KaryawanReportState extends State<KaryawanReport>{
  final db = new DbLite(); 
  List<KaryawanModel> modelList = List<KaryawanModel>();

  @override
  void initState() {
    super.initState();
    db.getDataKaryawan().then((value) {
      modelList = value;
    });
  }

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

  Future<bool> getData() async {
    await Future.delayed(const Duration(milliseconds: 200));
    return true;
  }

  @override
  Widget build(BuildContext context) {
    final _width = MediaQuery.of(context).size.width;
    final _height = MediaQuery.of(context).size.height;
    return FutureBuilder(
      future: getData(),
      builder: (context, snapshot){
        if(snapshot.connectionState == ConnectionState.waiting){
          return Container();
        }
        else{
          return Scaffold(
            appBar: AppBar(
              title: Text("Laporan Karyawan"),
              backgroundColor: Colors.redAccent,
              elevation: 0.0,
            ),
            body: Container(
              color: Colors.white,
              height: _height,
              width: _width,
              child: Scaffold(
                backgroundColor: Colors.white,
                body: SingleChildScrollView(
                  child: 
                  Column(
                    children: [
                      Padding(
                        padding: EdgeInsets.all(5),
                        child: Padding(
                          padding: EdgeInsets.only(top: 20, left: 20, bottom: 20),
                          child: Row(
                            children: [
                              Icon(Icons.view_list, color: Colors.grey),
                              Padding(
                                padding: EdgeInsets.only(left: 10),
                                child: Text("Laporan Data Karyawan", style: TextStyle(fontSize: 20),),
                              )
                            ],
                          ),
                        ) 
                      ),
                      Padding(
                        padding: EdgeInsets.only(left:50, right: 10),
                        child: Divider(thickness: 2,),
                      ),
                      Padding(
                        padding: EdgeInsets.only(left:100, right: 10, bottom: 10),
                        child: Divider(thickness: 2,),
                      ),
                      Card(
                        elevation: 3.0,
                        child: Padding(
                          padding: EdgeInsets.only(top: 15, bottom: 15),
                          child: ListView.builder(
                            itemCount: modelList.length,
                            physics: NeverScrollableScrollPhysics(),
                            shrinkWrap: true,
                            itemBuilder: (context, index){
                              return Slidable(
                                actionPane: SlidableDrawerActionPane(),
                                actionExtentRatio: 0.25,
                                child: ListTile(
                                  leading: Container(
                                    width: 40,
                                    height: 40,
                                    decoration: BoxDecoration(
                                      borderRadius: BorderRadius.circular(40),
                                      color: Colors.redAccent
                                    ),
                                    child: Row(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      crossAxisAlignment: CrossAxisAlignment.center,
                                      children: [
                                        Text(modelList[index].id.toString()),
                                      ],
                                    ) 
                                  ), 
                                  title: Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      Text(modelList[index].nama),
                                      Padding(
                                        padding: EdgeInsets.only(top: 5),
                                        child: Row(
                                          mainAxisAlignment: MainAxisAlignment.start,
                                          children: [
                                            Icon(Icons.phone, size: 13, color: Colors.green,),
                                            Text(" " + modelList[index].telp, style: TextStyle(fontSize: 12, color: Colors.grey),),
                                            Container(
                                              height: 20,
                                              child: VerticalDivider(color: Colors.red, thickness: 1,),
                                            ),
                                            Icon(Icons.email, size: 13, color: Colors.orangeAccent,),
                                            Text(" " + modelList[index].email, style: TextStyle(fontSize: 12, color: Colors.grey),),
                                          ],
                                        ) 
                                      ),
                                      (index == modelList.length -1) ? Container() : Divider(thickness: 2,)
                                    ],
                                  ) 
                                ),
                                secondaryActions: [
                                  IconSlideAction(
                                    caption: 'Ubah',
                                    color: Colors.green,
                                    icon: Icons.edit,
                                    onTap: () {},
                                  ),
                                  IconSlideAction(
                                    caption: 'Hapus',
                                    color: Colors.red,
                                    icon: Icons.delete,
                                    onTap: () => {
                                      _deleteKaryawan(modelList[index])
                                    },
                                  ),
                                ],
                              );
                            },
                          ),
                        ) 
                      )
                    ],
                  ) 
                )
              ),
            ),
          );
        }
      }
    );
  }

  //fungsi save 
  void _deleteKaryawan(KaryawanModel model){
    final db = new DbLite(); 
    PopupHelper().alertDialogCuprtino(context, "Mohon tunggu...");
    Future.delayed( Duration(seconds: 3), (){
      db.deleteKaryawan(model.id).then((value){ //hapus data yg ada di database
        if(value > 0){
          setState(() {
            modelList.remove(model); //hapus data yg ada di list
          });
          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 dihapus", style: TextStyle(fontSize: 12), ),
                  actions: <Widget>[
                    new FlatButton(
                      onPressed: (){
                        Navigator.of(context, rootNavigator: true).pop();
                      },
                      child: new Text("Ok"),
                    )
                  ],
                ),
              );
            }
          );
        }else{
          Navigator.of(context, rootNavigator: true).pop();
          PopupHelper().alertDialogCuprtinoMsg(context, "Oops, terjadi kesalahan!");
        }
      });
    });
  }
}

Pada bagian initState, disana kita memanggil fungsi untuk mendapatkan data dari database sqlite yang telah kita buat pada class DbLite. Pemanggilan data dilakukan sengaja dilakukan pada initState ini karena kita akan memanggil terlebih dahulu data yang ada pada table kemudian hasil data yang didapat akan dimasukkan kedalam sebuah variable list.

@override
  void initState() {
    super.initState();
    db.getDataKaryawan().then((value) {
      modelList = value;
    });
  }

Lalu kita buat sebuah Widget Colomn yang kita masukkan kedalam sebuah Container, Widget Column ini untuk membagi 2 bagian yang ada di layar yaitu bagian pertama untuk judul dari halaman dan kedua untuk list data karyawan.

Column(
                  children: [
                    Padding(
                      padding: EdgeInsets.all(5),
                      child: Padding(
                        padding: EdgeInsets.only(top: 20, left: 20, bottom: 20),
                        child: Row(
                          children: [
                            Icon(Icons.view_list, color: Colors.grey),
                            Padding(
                              padding: EdgeInsets.only(left: 10),
                              child: Text("Laporan Data Karyawan", style: TextStyle(fontSize: 20),),
                            )
                          ],
                        ),
                      ) 
                    ),
                    Padding(
                      padding: EdgeInsets.only(left:50, right: 10),
                      child: Divider(thickness: 2,),
                    ),
                    Padding(
                      padding: EdgeInsets.only(left:100, right: 10, bottom: 10),
                      child: Divider(thickness: 2,),
                    ),
                    Card(
                      elevation: 3.0,
                      child: Padding(
                        padding: EdgeInsets.only(top: 15, bottom: 15),
                        child: ListView.builder(
                          itemCount: modelList.length,
                          shrinkWrap: true,
                          itemBuilder: (context, index){
                            return Slidable(
                              actionPane: SlidableDrawerActionPane(),
                              actionExtentRatio: 0.25,
                              child: ListTile(
                                leading: Container(
                                  width: 40,
                                  height: 40,
                                  decoration: BoxDecoration(
                                    borderRadius: BorderRadius.circular(40),
                                    color: Colors.redAccent
                                  ),
                                  child: Row(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    crossAxisAlignment: CrossAxisAlignment.center,
                                    children: [
                                      Text(modelList[index].id.toString()),
                                    ],
                                  ) 
                                ), 
                                title: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(modelList[index].nama),
                                    Padding(
                                      padding: EdgeInsets.only(top: 5),
                                      child: Row(
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        children: [
                                          Icon(Icons.phone, size: 13, color: Colors.green,),
                                          Text(" " + modelList[index].telp, style: TextStyle(fontSize: 12, color: Colors.grey),),
                                          Container(
                                            height: 20,
                                            child: VerticalDivider(color: Colors.red, thickness: 1,),
                                          ),
                                          Icon(Icons.email, size: 13, color: Colors.orangeAccent,),
                                          Text(" " + modelList[index].email, style: TextStyle(fontSize: 12, color: Colors.grey),),
                                        ],
                                      ) 
                                    ),
                                    (index == modelList.length -1) ? Container() : Divider(thickness: 2,)
                                  ],
                                ) 
                              ),
                              secondaryActions: [
                                IconSlideAction(
                                  caption: 'Ubah',
                                  color: Colors.green,
                                  icon: Icons.edit,
                                  onTap: () {},
                                ),
                                IconSlideAction(
                                  caption: 'Hapus',
                                  color: Colors.red,
                                  icon: Icons.delete,
                                  onTap: () => {
                                    _deleteKaryawan(modelList[index].id)
                                  },
                                ),
                              ],
                            );
                          },
                        ),
                      ) 
                    )
                  ],
                )

Perhatikan pada Widget Listview, disana terdapat Widget Slidable, widget ini berfungsi untuk mendeteksi gesture ketika user menggeser ke kiri maupun kanan dari sebuah list data yang akan dihapus. Disini kita menampilkan tomobol Edit dan Hapus pada saat user menggeser layar ke bagian kanan. Kalian dapat menambahkan tombol baru pada bagian kiri sesuai kebutuhan, untuk detail dari widget tersebut kalian bisa kunjungi link ini.

Pada akhir kode terdapat fungsi _deleteKaryawan, fungsi ini yang akan dijalankan pada saat user memilih tombol hapus, di dalamnya fungsi tersebut akan memanggil fungsi yang ada pada class DBLite. Terdapat 2 fungsi hapus didalamnya, yaitu pertama hapus data yang ada di database dan yang kedua hapus data yang ada pada list. Mengapa dibuat 2 fungsi hapus? karena ketika data yang ada pada database di hapus, kita perlu melakukan refresh data yang ada pada layar. Oleh karena itu, untuk menghemat resource data yang ada dilayar tanpa perlu memanggil kembali fungsi untuk mengambil data ke database sqllite, maka kita hanya perlu menghapus list yang telah dimasukkan didalam variable modelList, dengan hanya menghapus data di list, maka layar akan secara otomatis merefresh data.

//fungsi save 
  void _deleteKaryawan(KaryawanModel model){
    final db = new DbLite(); 
    PopupHelper().alertDialogCuprtino(context, "Mohon tunggu...");
    Future.delayed( Duration(seconds: 3), (){
      db.deleteKaryawan(model.id).then((value){ //hapus data yg ada di database
        if(value > 0){
          setState(() {
            modelList.remove(model); //hapus data yg ada di list
          });
          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 dihapus", style: TextStyle(fontSize: 12), ),
                  actions: <Widget>[
                    new FlatButton(
                      onPressed: (){
                        Navigator.of(context, rootNavigator: true).pop();
                      },
                      child: new Text("Ok"),
                    )
                  ],
                ),
              );
            }
          );
        }else{
          Navigator.of(context, rootNavigator: true).pop();
          PopupHelper().alertDialogCuprtinoMsg(context, "Oops, terjadi kesalahan!");
        }
      });
    });
  }

Selanjutnya kita buat metod baru pada class DBLite, tambahkan fungsi hapus, seperti yang telah dijelaskan di awal bahwa pembuatan script hapus sangatlah mudah dan tidak perlu membuat script sql. Berikut ini fungsi hapus yang di dalam DBLite.

DBLite

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;
  }
  
  //fungsi hapus
  Future<int> deleteKaryawan(id) async{
    var dbClient = await db;
    int res = await dbClient.delete("Karyawan", where: "id = ?", whereArgs: [id]);
    return res;
  }

}

Langkah terakhir yang perlu kita lakukan adalah memanggil KaryawanReport.dart ini didalam dile MainMenu.dart, ubah pada baris 148 yang berisi imageText == “Laporan”, tambahkan script berikut.

if(imageText == "Laporan"){
              Navigator.of(context).push(MaterialPageRoute(builder: (context) => 
                  new KaryawanReport() 
                )
              );
            }

Akhirnya kita telah melakukan semua langkah untuk membuat fungsi hapus dan membuat layar baru untuk menampilkan data, saatnya kita jalankan project tersebut dan hasilnya seperti berikut.

Penampakan

flutter crud hapus

Selamat kalian telah berhasil membuat fungsi hapus. Setelah menyelesaikan tutorial ini, kita telah mempelajari beberapa hal berikut:

  1. Membuat fungsi hapus pada database sqlite
  2. Mengenal Widget Slidable, Listview.

Untuk melihat full source code project kalian bisa dapatkan di sini.

Pada tutorial selanjutnya kita akan membuat menu absen pada aplikasi karyawan.

Terimakasih, semoga bermanfaat.

Advertisements
Share: