Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

Tutorial CRUD Codeigniter 4 dan Flutter #2 – Create Data

4 min read

CRUD Codeigniter 4 + Flutte - Create Data

Tutorial CRUD Codeigniter 4 dan Flutter #2 – Create Data. Kali ini saya akan melanjutkan pembahasan sebelumnya ke halaman create dan simpan data.

Jika Anda belum membaca dan mempraktikan part ke 1, silahkan kunjungi:

Rekomendasi: Tutorial CRUD Codeigniter 4 dan Flutter #1 – Tampil Data

Apabila sudah, sekarang kita akan melanjutkan langkah berikutnya. Yaitu membuat halaman create data di Flutter dan mengirimkan data (method POST) melalui REST API Codeigniter 4.

Silahkan ikuti beberapa langkah di bawah ini:

Step 1 – Tambahkan Function Create User di Model

Tambahkan function createUser($data) tepat di bawah function getUser($id = false) pada file mode User_model.php.

app/Models/User_model.php:

public function createUser($data)
{
    return $this->db->table($this->table)->insert($data); 
}

Step 2 – Tambahkan Function Create di Controller

Tambahkan function create() tepat di bawah function index() pada file controller User.php.

Oh iya, saya sedikit memodifikasi function index(). Jadi, perhatikan juga ya.

app/Controllers/User.php:

public function index()
{
    $data = $this->user->getUser();

    foreach ($data as $row) { 

        $user[] = [
            'id' => intval($row->id),
            'fullname' => $row->fullname,
            'gender' => $row->gender,
            'grade' => $row->grade,
            'phone' => $row->phone 
        ];
        
    
    }	
    return $this->respond($user, 200);
}

public function create()
{
    $fullname   = $this->request->getPost('fullname');
    $grade      = $this->request->getPost('grade');
    $gender     = $this->request->getPost('gender');
    $phone      = $this->request->getPost('phone');
    
    $data = [
        'fullname' => $fullname,
        'grade' => $grade,
        'gender' => $gender,
        'phone' => $phone
    ];
    
    $simpan = $this->model->createUser($data);
    
    if($simpan){
        $msg = ['message' => 'Created user successfully'];
        $response = [
            'status' => 200,
            'error' => false,
            'data' => $msg,
        ];
        return $this->respond($response, 200);
    }
}

Step 3 – Testing Create Melalui Postman

Cara 1: Masukan URL di bawah ini dengan menggunakan Method POST dan isi beberapa data:

localhost:8080/user/create

Cara 2: Menggunakan URL modifikasi ini:

http://localhost/belajar-codeigniter-4/ci4_restapi_flutter/public/index.php/user/create 

Catatan: Jika menggunakan cara ke 2, silahkan sesuaikan dengan tempat penyimpanan folder project Anda.

Jika sudah, silahkan isi data pada bagian fullname, gender, grade dan phone.

Perhatikan gambar berikut:

Tutorial CRUD Codeigniter 4 dan Flutter #2 - Create Data - gambar 1

Nah, jika sudah berhasil seperti pada gambar di atas, maka kita akan menuju ke bagian flutter. Sedikit lagi, tutorial crud codeigniter 4 dan flutter bagian create data akan selesai.

Step 4 – Structur Project Tambahan di Flutter

Saya menambahkan folder baru bernama widget di folder lib. Di dalamnya terdapat file form_label.dart dan radio_button.dart yang akan kita butuhkan untuk membuat halaman create.

… dan satu file tambahan, yaitu user_create.dart yang akan kita ketik pada step ke 5.

Perhatikan gambar berikut:

Pada file form_label.dart silahkan isi dengan kode berikut:

import 'package:flutter/material.dart';

class FormLabel extends StatelessWidget {

  final String data;

  const FormLabel(this.data, {Key key}) : super(key : key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        data,
        style: TextStyle(fontSize: 20.0, color: Theme.of(context).colorScheme.primary),
        textAlign: TextAlign.start,
      ),
    );
  }
}

… dan pada file radio_button.dart silahkan isi dengan kode di bawah ini:

import 'package:flutter/material.dart';

class RadioButton<T> extends StatelessWidget {
  final T value;
  final T groupValue;
  final ValueChanged<T> onChanged;
  final Color activeColor;
  final MaterialTapTargetSize materialTapTargetSize;
  final Widget label;

  const RadioButton({
    Key key,
    @required this.value,
    @required this.groupValue,
    @required this.onChanged,
    @required this.label,
    this.activeColor,
    this.materialTapTargetSize,
  }) : assert(value != null),
        assert(groupValue != null),
        assert(onChanged != null),
        assert(label != null),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        Radio<T>(
          key: key,
          value: value,
          groupValue: groupValue,
          onChanged: (T newValue) {
            onChanged(newValue);
          },
          activeColor: activeColor,
          materialTapTargetSize: materialTapTargetSize,
        ),
        label,
      ],
    );
  }
}

Step 5 – Tambahkan Function Create di Flutter

Sekarang saatnya kita memodifikasi file-file Flutter yang telah kita buat sebelumnya.

… jika Anda kebingungan apa-apa saja yang berubah, Anda bisa melihat proses perubahan pada link commit di bawah ini:

Lihat Perubahan File Codeigniter 4 dan Flutter di Github

Emang, apa aja sih yang berubah?

Ada tambahan di user_list.dart, user_service.dart dan tambahan file user_create.dart.

Oke kita mulai saja ya …

Buka kembali file user_service.dart dan tambahkan function createUser.

lib/service/user_service.dart:

Future<bool> createUser(User data) async {
  final response = await client.post(
    "$baseUrl/user/create",
    body: {
      "fullname" : data.fullName,
      "grade" : data.grade,
      "gender" : data.gender,
      "phone" : data.phone 
    }
  );
  if (response.statusCode == 200) {
    return true;
  } else {
    return false;
  }
}

Kemudian tambahkan floating action button pada file user_list.dart untuk menuju page user_create.dart.

lib/screen/user_list.dart:

....
....
floatingActionButton: FloatingActionButton(
  child: Icon(
    Icons.add,
    color: Colors.white,
  ),
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (BuildContext context) => FormUser()) 
    );
  }
),
...
...

Selanjutnya mari buat screen baru bernama user_create.dart.

Silahkan ketik kode berikut:

import 'package:flutter/material.dart';
import 'package:flutter_crud_ci4/model/user.dart';
import 'package:flutter_crud_ci4/service/user_service.dart';
import 'package:flutter_crud_ci4/util/capitalize.dart';
import 'package:flutter_crud_ci4/widget/form_label.dart';
import 'package:flutter_crud_ci4/widget/radio_button.dart';

class FormUser extends StatefulWidget {

  @override
  _FormUserState createState() => _FormUserState();
}

class _FormUserState extends State<FormUser> {

  UserApiService apiService;

  static const genders = User.genders; // from domain
  static const grades = User.grades; // from domain

  // upayakan menggunakan global key
  final _formKey = GlobalKey<FormState>();
  final GlobalKey<ScaffoldState> _scaffoldkey = GlobalKey<ScaffoldState>();

  bool _autovalidate = false;
  // jarak antar form
  double _gap = 16.0;
  // focus node
  FocusNode _fullnameFocus, _phoneFocus;
  // variabel value null
  String _fullname, _gender, _grade, _phone;

  final List<DropdownMenuItem<String>> _gradeItems = grades
    .map((String val) => DropdownMenuItem<String>(
          value: val,
          child: Text(val.toUpperCase()),
        ))
    .toList();

  @override
  void initState() {
    super.initState();
    _gender = 'pria';
    _fullnameFocus = FocusNode();
    _phoneFocus = FocusNode();
    apiService = UserApiService();
  }

  @override
  void dispose() {
    // Clean up the focus node when the Form is disposed.
    _fullnameFocus.dispose();
    _phoneFocus.dispose();
    _formKey.currentState?.dispose();
    super.dispose();
  }

  _showSnackBar(message){
    final snackbar = SnackBar(content: Text(message),);
    _scaffoldkey.currentState.showSnackBar(snackbar);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () => {
            Navigator.pop(context),
          },
        ),
        title: Text("Create User"),
      ),
      body: SingleChildScrollView(
        child: ConstrainedBox(
          constraints: BoxConstraints(),
          child: Form(
            // key form as csrf
            key: _formKey,
            autovalidate: _autovalidate,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  TextFormField(
                    focusNode: _fullnameFocus,
                    textInputAction: TextInputAction.next,
                    keyboardType: TextInputType.text,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Nama Lengkap',
                    ),
                    onSaved: (String value) {
                      // will trigger when saved
                      print('onsaved _fullname $value');
                      _fullname = value;
                    },
                    onFieldSubmitted: (term) {
                      // process
                    },
                    validator: (val) {
                      if(val.isEmpty){
                        return "Nama lengkap wajib diisi";
                      }
                      return null;
                    },
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  TextFormField(
                    focusNode: _phoneFocus,
                    textInputAction: TextInputAction.next,
                    keyboardType: TextInputType.phone,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'No. Hp',
                    ),
                    onSaved: (String value) {
                      // will trigger when saved
                      print('onsaved _hone $value');
                      _phone = value;
                    },
                    onFieldSubmitted: (term) {
                      // process
                    },
                    validator: (val) {
                      if(val.isEmpty){
                        return "No hp wajib diisi";
                      }
                      return null;
                    },
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  FormLabel('Jenis Kelamin'),
                  Row(
                    children: genders
                        .map((String val) => RadioButton<String>(
                            value: val,
                            groupValue: _gender,
                            label: Text(capitalize(val)),
                            onChanged: (String value) {
                              setState(() => _gender = value);
                            }))
                        .toList(),
                  ),
                  SizedBox(
                    height: _gap,
                  ),
                  FormLabel('Jenjang'),
                  Padding(
                    padding: const EdgeInsets.only(left: 5.0),
                    child: DropdownButton(
                      value: _grade,
                      hint: Text('Pilih jenjang'),
                      items: _gradeItems,
                      isExpanded: true,
                      onChanged: (String value) {
                        setState(() {
                          _grade = value;
                        });
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(
          Icons.save,
          color: Colors.white,
        ),
        onPressed: () {
          final form = _formKey.currentState;
          if (form.validate()) {
            // Process data.
            form.save(); // required to trigger onSaved props
            User _user = User();

            if(_grade == null){
              _showSnackBar("Jenjang tidak boleh kosong");
            } else if(_gender == null){
              _showSnackBar("Gender tidak boleh kosong");
            } else {
              _user.fullName = _fullname;
              _user.grade = _grade;
              _user.gender = _gender;
              _user.phone = _phone;
              print(_user);

              // snackbar success dan error
              final onSuccess = (Object success) => Navigator.pop(context);
              final onError = (Object error) => _showSnackBar("Tidak bisa simpan data");
              
              apiService.createUser(_user).then(onSuccess).catchError(onError);
            }
          } else {
            setState(() {
              _autovalidate = true;
            });
          }
        }
      ),
    );
  }
}

Sekarang, jalankan kembali dengan perintah flutter run.

Jika berhasil, maka berikut hasilnya:

Halaman Create Data

Tutorial CRUD Codeigniter 4 dan Flutter #2 - Create Data - gambar 2

Halaman List Data

Tutorial CRUD Codeigniter 4 dan Flutter #2 - Create Data - gambar 3

Apa Selanjutnya?

Alhamdulillah kita telah menyelesaikan tutorial CRUD menggunakan Codeigniter 4 dan Flutter Part 1 yang membahas create data.

Jika ingin melihat perubahan-perubahan yang terjadi pada kode di atas, Anda bisa simak commit melalui link di bawah ini:

Commit Part 2 – Create Data

Semoga tutorial ini bermanfaat.

Selamat belajar …

Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

4 Replies to “Tutorial CRUD Codeigniter 4 dan Flutter #2 – Create…”

Leave a Reply

Your email address will not be published. Required fields are marked *

Jika terbantu dengan artikel ini, silahkan share, beri komentar dan "klik" 1 kali pada iklan ya.