Hosting Unlimited Indonesia

Tutorial CRUD Tanpa Reload Page dengan CodeIgniter 4 dan Vue.js

Tutorial CRUD Tanpa Reload Page dengan CodeIgniter 4 dan Vue.js

Pada Tutorial ini Anda akan belajar bagaimana membuat CRUD (Create-Read-Update-Delete) tanpa reload page menggunakan CodeIgniter 4 dan Vue.js.

Tidak hanya itu,

Anda juga akan belajar bagaimana menggunakan modal / dialog sebagai form input data menggunakan vuetify, sehingga aplikasi yang dibangun menjadi lebih user friendly.

Selain itu, Anda juga akan belajar bagaimana mengatur Routes agar dapat menerima method GET, POST, PUT, dan DELETE.

(Step-by-Step)

Mari kita mulai.

 

Step #1. Persiapan

Ini penting!

Berikut beberapa hal yang perlu Anda persiapkan:

1. Vue.js

Vue.js adalah framework JavaScript progresif dan dapat diadopsi secara bertahap untuk membangun User Interface (UI) pada halaman web.

Pada tutorial ini, Anda tidak perlu mendownload Vue.js, karena kita hanya akan menggunakan Vue.js CDN.

2. Axios

Axios merupakan Promise based HTTP Client untuk browser ataupun node.js.

Axios memberikan kemudahan dalam menghandle AJAX request.

Pada tutorial ini, Anda tidak perlu mendownload Axios, karena kita hanya akan menggunakan Axios CDN.

3. Vuetify

Vuetify merupakan library User Interface (UI) untuk vue.js dengan desain yang elegan.

Dengan memanfaatkan vuetify, Anda dapat membuat aplikasi dengan user interface yang elegan dan responsive dengan cepat tanpa memikirkan CSS ataupun Javascript.

Pada tutorial ini, Anda juga tidak perlu mendownload Vuetify, karena kita hanya akan menggunakan vuetify CDN.

 

Step #2. Instalasi Codeigniter 4

Untuk menginstal Codeigniter 4 dapat dilakukan dengan 2 cara yaitu: Instalasi manual dan Instalasi melalui composer.

Pada tutorial ini, saya akan menggunakan installasi manual.

Silahkan download file CodeIgniter 4 pada link berikut:

https://codeigniter.com

Kemudian extract pada web server Anda.

Jika Anda menggunakan WAMPSERVER, extract di folder:

C:/wamp64/www

Jika Anda menggunakan XAMPP, extract di folder:

C:/xampp/htdocs

Pada tutorial ini, saya menggunakan XAMPP.

Kemudian rename (ganti nama) menjadi “crud” seperti gambar berikut:

Kemudian, open folder project “crud” menggunakan code editor.    

Pada tutorial ini, saya menggunakan “Visual Studio Code”, Anda dapat menggunakan Sublime Text, PHP Storm, atapun code editor lainnya.

 

Step #3. Buat database dan table

Buat sebuah database baru pada MySQL, Anda dapat menggunakan tools seperti SQLyog, PHPMyAdmin atau sejenisnya.

Disini saya membuat database dengan nama “crud_db”.

Jika Anda membuat database dengan nama yang sama itu lebih baik.

Untuk  membuat database pada MySQL, dapat dilakukan dengan mengeksekusi query berikut:

CREATE DATABASE crud_db;

Perintah SQL diatas akan membuat sebuah database dengan nama “crud_db”.

Selanjutnya, buat koneksi antara database dengan project codeigniter.

Temukan file env pada root project, kemudian rename (ganti nama) menjadi .env dan open file tersebut.

Kemudian temukan kode berikut:

# database.default.hostname = localhost
# database.default.database = ci4
# database.default.username = root
# database.default.password = root
# database.default.DBDriver = MySQLi

Ubah menjadi seperti berikut:

database.default.hostname = localhost
database.default.database = crud_db
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi

Selanjutnya adalah pembuatan table pada database “crud_db”.

Pada tutorial ini, saya akan menggunakan fitur migration pada codeigniter 4 untuk pembuatan table.

Ketikan perintah berikut pada Terminal / Command Prompt:

php spark migrate:create product

Kemudian Enter, maka CodeIgniter akan membuat sebuah file berinisial “product” pada folder “app/Database/Migrations”.

Seperti gambar berikut:

Buka file tersebut, kemudian ketikan kode berikut:

<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Product extends Migration
{
    public function up()
    {
        //
        $this->forge->addField([
            'product_id'          => [
                    'type'           => 'INT',
                    'constraint'     => 5,
                    'unsigned'       => true,
                    'auto_increment' => true,
            ],
            'product_name'       => [
                    'type'           => 'VARCHAR',
                    'constraint'     => '100',
            ],
            'product_price' => [
                    'type'           => 'INT',
                    'constraint'     => 11,
            ],
        ]);
        $this->forge->addKey('product_id', true);
        $this->forge->createTable('product');
    }

    //--------------------------------------------------------------------

    public function down()
    {
        //
    }
}

Pada kode diatas, kita hanya menambahkan kode pada function up().

Function up(), berfungsi untuk membuat table di database dengan field yang ditetapkan.

Pada kasus diatas, kita membuat sebuah table dengan nama “product” dengan field product_id, product_name, dan product_price beserta type data dan atribut lainnya.

Jika Anda tidak terbiasa dengan migration, mungkin terlihat rumit, tapi sebenarnya tidak.

Selanjutnya, ketikan perintah berikut pada Terminal / Command Prompt:

php spark migrate

Kemudian Enter, maka codeigniter akan otomatis membuat table “product” dengan field product_id, product_name, dan product_price di dalam database “crud_db”.

 

Step #4. Model

Buat sebuah file model bernama “ProductModel.php” pada folder “app/Models”.

Kemudian ketikan kode berikut:

<?php namespace App\Models;

use CodeIgniter\Model;

class ProductModel extends Model
{
    protected $table = 'product';
    protected $primaryKey = 'product_id';
    protected $allowedFields = ['product_name','product_price'];
}

Penjelasan kode:

Pada kode terdapat kode untuk mendefinisikan table yang digunakan dengan kode berikut:

protected $table = 'product';

Kemudian kita mendefinisikan primary key untuk menghindari duplikat data dengan kode berikut:

protected $primaryKey = 'product_id';

Kemudian mendefinisikan field yang boleh dimanipulasi dengan kode berikut:

protected $allowedFields = ['product_name','product_price'];

Pada kasus ini, kita hanya mengizinkan field product_name dan product_price untuk dimanipulasi.

 

Step #5. Controller

Buat sebuah file controller bernama “Product.php” pada folder “app/Controllers”.

Kemudian ketikan kode berikut:

<?php namespace App\Controllers;

use CodeIgniter\Controller;
use App\Models\ProductModel;

class Product extends Controller
{
    public function index()
    {
        echo view('product_view');
    }

    public function getProduct()
    {
        $model = new ProductModel();
        $data = $model->findAll();
        return json_encode($data);
    }

    public function save(){
        $model = new ProductModel();
        $json = $this->request->getJSON();
        $data = [
            'product_name' => $json->product_name,
            'product_price' => $json->product_price
        ];
        $model->insert($data);
    }

    public function update($id = null){
        $model = new ProductModel();
        $json = $this->request->getJSON();
        $data = [
            'product_name' => $json->product_name,
            'product_price' => $json->product_price
        ];
        $model->update($id, $data);
    }

    public function delete($id = null){
        $model = new ProductModel();
        $model->delete($id);
    }

}

Penjelasan kode:

Pada Controller “Product.php”, terdapat beberapa function yaitu function index, function getProduct, function save, function update, dan function delete.

Function index:

public function index()
{
    echo view('product_view');
}

Function index, berfungsi untuk memanggil sebuah view bernama “product_view” yang akan kita buat nantinya.

Function getProduct:

public function getProduct()
{
    $model = new ProductModel();
    $data = $model->findAll();
    return json_encode($data);
}

Function getProduct, berfungsi untuk mengambil data dari table product yang terdapat di database, kemudian di encode ke dalam bentuk json object.

Function save:

public function save(){
    $model = new ProductModel();
    $json = $this->request->getJSON();
    $data = [
        'product_name' => $json->product_name,
        'product_price' => $json->product_price
    ];
    $model->insert($data);
}

Function save, berfungsi untuk menerima request dari client dalam format JSON dengen kode:

$this->request->getJSON();

Kemudian JSON object dipecah menjadi Array Object dengan kode:

$data = [
     'product_name' => $json->product_name,
     'product_price' => $json->product_price
];

Setelah itu, barulah data di insert ke database dengan kode:

$model->insert($data);

Function update:

public function update($id = null){
    $model = new ProductModel();
    $json = $this->request->getJSON();
    $data = [
        'product_name' => $json->product_name,
        'product_price' => $json->product_price
    ];
    $model->update($id, $data);
}

Hampir sama dengan function save, hanya saja function update membawa parameter id dan tidak menambah data baru ke database, melainkan hanya merubahnya.

Function delete:

public function delete($id = null){
    $model = new ProductModel();
    $model->delete($id);
}

Function delete, berfungsi untuk menghapus data di database sesuai dengan parameter id.

 

Step #6. View

Buat sebuah file view bernama “product_view.php” pada folder “app/Views”.

Kemudian ketikan kode berikut:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Product List</title>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
    <div id="app">
    <v-app>
        <v-main>
            <v-container>
                <!-- Table List Product -->
                <template>
                    <!-- Button Add New Product -->
                    <template>
                        <v-btn color="primary" dark @click="modalAdd = true">Add New</v-btn>
                    </template>
                    
                    <v-simple-table>
                        <template v-slot:default>
                        <thead>
                            <tr>
                                <th class="text-left">Product Name</th>
                                <th class="text-left">Price</th>
                                <th class="text-left">Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="product in products" :key="product.product_id">
                                <td>{{ product.product_name }}</td>
                                <td>{{ product.product_price }}</td>
                                <td>
                                <template>
                                    <v-icon small class="mr-2" @click="editItem(product)">
                                        mdi-pencil
                                    </v-icon>
                                    <v-icon small @click="deleteItem(product)">
                                        mdi-delete
                                    </v-icon>
                                </template>
                                </td>
                            </tr>
                        </tbody>
                        </template>
                    </v-simple-table>

                </template>
                <!-- End Table List Product -->
                
                <!-- Modal Save Product -->
                <template>
                    <v-dialog v-model="modalAdd" persistent max-width="600px">
                        <v-card>
                            <v-card-title>
                                <span class="headline">Add New Product</span>
                            </v-card-title>
                            <v-card-text>
                                <v-container>
                                    <v-row>
                                        <v-col cols="12">
                                            <v-text-field label="Product Name*" v-model="productName" required>
                                            </v-text-field>
                                        </v-col>
                                        <v-col cols="12">
                                            <v-text-field label="Price*" v-model="productPrice" required>
                                            </v-text-field>
                                        </v-col>
                                    </v-row>
                                </v-container>
                                <small>*indicates required field</small>
                            </v-card-text>
                            <v-card-actions>
                                <v-spacer></v-spacer>
                                <v-btn color="blue darken-1" text @click="modalAdd = false">Close</v-btn>
                                <v-btn color="blue darken-1" text @click="saveProduct">Save</v-btn>
                            </v-card-actions>
                        </v-card>
                    </v-dialog>
                </template>
                <!-- End Modal Save Product -->

                <!-- Modal Edit Product -->
                <template>
                    <v-dialog v-model="modalEdit" persistent max-width="600px">
                        <v-card>
                            <v-card-title>
                                <span class="headline">Edit Product</span>
                            </v-card-title>
                            <v-card-text>
                                <v-container>
                                    <v-row>
                                        <v-col cols="12">
                                            <v-text-field label="Product Name*" v-model="productNameEdit" required>
                                            </v-text-field>
                                        </v-col>
                                        <v-col cols="12">
                                            <v-text-field label="Price*" v-model="productPriceEdit" required>
                                            </v-text-field>
                                        </v-col>
                                    </v-row>
                                </v-container>
                                <small>*indicates required field</small>
                            </v-card-text>
                            <v-card-actions>
                                <v-spacer></v-spacer>
                                <v-btn color="blue darken-1" text @click="modalEdit = false">Close</v-btn>
                                <v-btn color="blue darken-1" text @click="updateProduct">Update</v-btn>
                            </v-card-actions>
                        </v-card>
                    </v-dialog>
                </template>
                <!-- End Modal Edit Product -->

                <!-- Modal Delete Product -->
                <template>
                    <v-dialog v-model="modalDelete" persistent max-width="600px">
                        <v-card>
                            <v-card-title>
                                <span class="headline"></span>
                            </v-card-title>
                            <v-card-text>
                                <v-container>
                                    <v-row>
                                        <h3>Are sure want to delete <strong>"{{ productNameDelete }}"</strong> ?</h3>
                                    </v-row>
                                </v-container>
                            </v-card-text>
                            <v-card-actions>
                                <v-spacer></v-spacer>
                                <v-btn color="blue darken-1" text @click="modalDelete = false">No</v-btn>
                                <v-btn color="info darken-1" text @click="deleteProduct">Yes
                                </v-btn>
                            </v-card-actions>
                        </v-card>
                    </v-dialog>
                </template>
                <!-- End Modal Delete Product -->

            </v-container>
        </v-main>
    </v-app>
    </div>

    <script src="https://vuejs.org/js/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        new Vue({
            el: '#app',
            vuetify: new Vuetify(),
            data : {
                products: [],
                modalAdd: false,
                productName: '',
                productPrice: '',
                modalEdit: false,
                productIdEdit: '',
                productNameEdit: '',
                productPriceEdit: '',
                modalDelete: false,
                productIdDelete: '',
                productNameDelete: '',
            },
            created: function() {
                axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
                this.getProducts();
            },
            methods: {
                // Get Product
                getProducts: function () {
                    axios.get('product/getproduct')
                        .then(res => {
                             // handle success
                            this.products = res.data;
                        })
                        .catch(err => {
                            // handle error
                            console.log(err);
                        })
                },
                // Save Product
                saveProduct: function(){
                    axios.post('product/save', {
                        product_name: this.productName,
                        product_price: this.productPrice
                    })
                    .then(res => {
                        // handle success
                        this.getProducts();
                        this.productName = '';
                        this.productPrice = '';
                        this.modalAdd = false;
                    })
                    .catch(err => {
                        // handle error
                        console.log(err);
                    })
                },

                // Get Item Edit Product
                editItem: function(product) {
                    this.modalEdit = true;
                    this.productIdEdit    = product.product_id;
                    this.productNameEdit  = product.product_name;
                    this.productPriceEdit = product.product_price;
                },

                //Update Product
                updateProduct: function () {
                    axios.put(`product/update/${this.productIdEdit}`, {
                            product_name: this.productNameEdit,
                            product_price: this.productPriceEdit
                        })
                        .then(res => {
                            // handle success
                            this.getProducts();
                            this.modalEdit = false;
                        })
                        .catch(err => {
                            // handle error
                            console.log(err);
                        })
                },

                // Get Item Delete Product
                deleteItem: function(product){
                    this.modalDelete = true;
                    this.productIdDelete    = product.product_id;
                    this.productNameDelete  = product.product_name;
                },

                // Delete Product
                deleteProduct: function () {
                    axios.delete(`product/delete/${this.productIdDelete}`)
                        .then(res => {
                            // handle success
                            this.getProducts();
                            this.modalDelete = false;
                        })
                        .catch(err => {
                            // handle error
                            console.log(err);
                        })
                }

            },
            
        })
    </script>
</body>
</html>

Untuk penjelasan kode, perhatikan komentar yang saya sertakan pada baris kode!

 

Step #7. Routes

Ini penting!

Buka file “Routes.php” yang terdapat pada folder “app/Config”.

Kemudian temukan kode berikut:

$routes->setDefaultController('Home');

Ubah menjadi seperti berikut:

$routes->setDefaultController('Product');

Pada kode diatas, kita mengatur default controllernya adalah “Product”.

Selanjutnya temukan kode berikut:

$routes->get('/', 'Home::index');

Ubah menjadi berikut:

$routes->get('/', 'Product::index');
$routes->post('product/save', 'Product::save');
$routes->put('product/update', 'Product::update');
$routes->delete('product/delete', 'Product::delete');

Pada kode diatas, kita menjalankan Controller “Product” pada saat project dijalankan.

Tidak hanya itu,

Kita juga mengatur agar function save yang ada di controller “Product” dapat menerima method “POST”, function update agar dapat menerima method “PUT”, dan function delete agar dapat menerima method “DELETE”.

 

Step #8. Testing

Untuk melakukan pengujian, silahkan ketikan perintah berikut pada Terminal / Command Prompt:

php spark serve

Kemudian buka browser Anda, dan kunjungi url berikut:

http://localhost:8080

Jika berjalan dengan baik, maka akan terlihat seperti gambar berikut:

1. Create New Product

Klik tombol “Add New” untuk menambahkan product baru, maka akan muncul modal / dialog seperti berikut:

Ketikan “product name” dan “price”, kemudian klik tombol “Save” untuk menyimpan data.

Jika data berhasil tersimpan, maka akan tampil datanya seperti gambar berikut:

2. Edit Product

Untuk mengedit product, klik icon “pensil” pada kolom “Actions”, maka akan tampil modal/dialog seperti berikut:

Edit product name ataupun price, kemudian klik tombol “Update” untuk mengupdate product.

3. Delete Product

Untuk menghapus product, klik icon “trash” pada kolom “Actions”, maka akan tampil modal/dialog seperti berikut:

Klik tombol “YES” untuk menghapus product.

 

Kesimpulan

Pembahasan kali ini adalah tentang bagaimana membuat CRUD tanpa reload page dengan CodeIgniter 4 dan vue.js.

Untuk membuat CRUD tanpa reload page dengan CodeIgniter 4 dan vue.js, kita membutuhkan Axios untuk menghandle Ajax request.

Selain itu, Anda juga telah belajar bagaimana mengatur Routes agar dapat menerima method GET, POST, PUT, dan DELETE.

Jadi tunggu apa lagi, Let’s Coding!

Download Source Code

Share:




LAINNYA UNTUK ANDA


Komentar (0)

Leave a Comment