Tutorial CRUD Menggunakan Electron JS dan Lumen Laravel

Tutorial CRUD Menggunakan Electron JS dan Lumen Laravel

Sobatcoding.com - Membuat CRUD menggunakan Electron dan Lumen Laravel

Artikel kali ini kita kan mecoba membuat CRUD (Create, Read, Update, Delete) menggunakan Electron JS kolaborasi dengan Lumen Laravel sebagai sumber source data nya.

Langsung saja kita ikuti langkah-langkahnya.

Step 1 : Install Electron JS beserta Dependency nya

Pertama kita buat dahulu folder bernama electron-laravel-crud, kemudian masuk ke folder tersebut dan instal electron beserta dependency nya

npm init -y
npm install electron jquery datatables.net bulma --save-dev

Step 2: Setup dan Config

Buat file index.js di root folder, masukkan kode berikut.

// Modules to control application life and create native browser window
const { app, BrowserWindow, Menu, dialog, ipcMain } = require('electron')
const path = require('path')
var appmenu = require( path.resolve( __dirname, "./menu.js" ) )

let mainWindow
let loginWindow

const createWindow = () => {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        nodeIntegration: true,
        contextIsolation: false,
        webviewTag: true
        
    }
  })

  // and load the index.html of the app.
  mainWindow.setMenu(appmenu)
  mainWindow.maximize();
  mainWindow.loadFile('./app/views/index.html')
  mainWindow.show()

  loginWindow = new BrowserWindow({
    parent: mainWindow,
    modal: true,
    javascript : true,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
      
    }
  })

  loginWindow.loadFile('./app/views/login.html')
  loginWindow.show()
  loginWindow.setMenu(null)
  loginWindow.maximize();

  loginWindow.on('close', (event) => { 
    
    let options = {}
    options.type = "question"
    options.buttons = ["&Yes","&No"]
    options.defaultId = 1
    options.cancelId = 1
    options.title = "Information"
    options.message = "Do you really want to quit?"

    let response = dialog.showMessageBoxSync(loginWindow, options);
    if( response == 1 ) event.preventDefault()
    if( response == 0 ) {
      if (process.platform !== 'darwin') app.quit()
    }
     
  })

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()

}


// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  //Menu.setApplicationMenu(appmenu)
  createWindow()

  app.on('activate', () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

/** Message */
ipcMain.on('login', (evt, arg) => {
  const options = {
      type: "info",
      buttons: ["OK"],
      title: "Login success!",
      message: 'Login success'
  }
  dialog.showMessageBox(loginWindow, options)
  loginWindow.hide()
})

ipcMain.on('login-error', (evt, arg) => {
  const options = {
      type: "info",
      buttons: ["OK"],
      title: "Login failed!",
      message: 'Invalid username/password'
  }
  dialog.showMessageBox(loginWindow, options)
})

ipcMain.on('message', (evt, arg) => {
    const options = {
        type: "info",
        buttons: ["OK"],
        title: "Info",
        message: arg.message
    }
    dialog.showMessageBox(loginWindow, options)
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

Buat juga file bernama menu.js dan tambahkan kode berikut.

const { app, BrowserWindow, Menu, shell, ipcMain } = require('electron');
const path = require('path')
const isMac = process.platform === 'darwin'
const template = [
  {
    label: 'File',
    submenu: [
      {
        label: 'Console',
        role: 'toggleDevTools',
      },
      {
        label: 'Refresh',
        role: 'reload',
      },
      {
        label: 'Exit',
        role: isMac ? 'close' : 'quit',
      }
    ]
  },
  {
    label: 'CRUD',
    submenu: [
      {
        label: 'List Data',
        click: function (menuItem, browserWindow, event) {
          browserWindow.webContents.send('add-tab', {
            title: 'Data table',
            id: 'table',
            src: path.resolve( __dirname, "./app/views/table.html"),
            visible: true
          })          
        }
      },
      {
        label: 'Add Data',
        click: function (menuItem, browserWindow, event) {
          browserWindow.webContents.send('add-tab', {
            title: 'Form Data',
            id: 'form',
            src: path.resolve( __dirname, "./app/views/form.html"),
            visible: true
          })          
        }
      }
    ]
  }
];

module.exports = Menu.buildFromTemplate(template);

 

Step 3: Install Lumen Laravel via Composer

Instal lumen laravel menggunakan via composer dengan command berikut

composer create-project --prefer-dist laravel/lumen api

Untuk setting lumen silahkan kalian set sendiri ya. Untuk referensi bisa kalian baca di link berikut ini

 

Baca :  Membuat REST API Menggunakan Lumen Laravel

 

Buat sebuah model bernama Users.php di dalam folder App\Models;

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Users extends Model
{

    protected $primaryKey = 'id';

    protected $table = 'm_users';

    public $timestamps = true;

}

Buat controller UserController.php

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator;
use Illuminate\Support\Facades\Crypt;

use App\Models\Users;

class UserController extends Controller
{
    function index()
    {
        $row = Users::get();

        return response()->json(['data' => $row]);
    }

    function create(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'fullname'        => 'required',
            'username'        => 'required|min:6|unique:m_users',
            'password'        => 'required|min:6',
            'address'         => 'required',
            'phone'           => 'required',
        ],
        [
            'required'  => ':attribute harus diisi',
            'numeric'   => ':attribute harus angka',
            'min'       => ':attribute minimal :min karakter'
        ]);

        if ($validator->fails()) {
            $resp = [
                'success' => false,
                'message' => $validator->errors()->first(),
                ];
            return response()->json($resp, 422);
            die();
        }

        $user = new Users;
        $user->name = $request->get('fullname');
        $user->username = $request->get('username');
        $user->password = Crypt::encrypt($request->get('password'));
        $user->address = $request->get('address');
        $user->phone = $request->get('phone');
        $user->save();

        return response()->json(['success' => true, 'message' => 'Data user berhasil diinput']);

    }

    function update($id, Request $request)
    {
        $validator = Validator::make($request->all(), [
            'fullname'        => 'required',
            'username'        => 'required|min:6|unique:m_users,username,'. $id,
            'address'         => 'required',
            'phone'           => 'required',
        ],
        [
            'required'  => ':attribute harus diisi',
            'numeric'   => ':attribute harus angka',
            'min'       => ':attribute minimal :min karakter'
        ]);

        if ($validator->fails()) {
            $resp = [
                'success' => false,
                'message' => $validator->errors()->first(),
                ];
            return response()->json($resp, 422);
            die();
        }

        $user = Users::where('id', $id)->update([
                    'name' => $request->get('fullname'),
                    'username' => $request->get('username'),
                    'address' => $request->get('address'),
                    'phone' => $request->get('phone')
                ]);

        return response()->json(['success' => true, 'message' => 'Data user berhasil diupdate']);

    }

    function delete($id)
    {
        Users::where('id', $id)->delete();

        return response()->json(['success' => true, 'message' => 'Data user berhasil dighapus']);

    }
}

Tambahkan route ke dalam app\routes\web.php

$router->get('users', [ 'uses' => 'UserController@index']);
$router->post('users', [ 'uses' => 'UserController@create']);
$router->post('users/update/{id}', [ 'uses' => 'UserController@update']);
$router->get('users/delete/{id}', [ 'uses' => 'UserController@delete']);

 

Step 4: Membuat view HTML

Buatlah sebuah file html bernama index.html dan simpan di root folder.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">        
        <title>Laravel Electron</title>
        <link rel="stylesheet" href="../assets/css/style.css" />
        <link rel="stylesheet" href="../assets/css/tab.css" />
        <link rel="stylesheet" href="../assets/css/bulma.min.css" />
        <link rel="stylesheet" href="../assets/css/datTables.bulma.min.css" />

    </head>
    <body>
        <script>
            const { ipcRenderer } = require('electron')
            let $ = jQuery = require('jquery')
            let dt = require( 'datatables.net' )( window, $ );
    
            ipcRenderer.on('add-tab', (event, arg) => {
                if( $('#'+arg.id).length )
                {
                    $('input[radio]').prop('checked', false);
                    $('#'+arg.id).prop('checked', true);
                }else{
                    addTab(arg.id, arg.title, arg.src)
                }
            })
    
            /* Javascript here */
    
            $(document).on('click', '.close-tab', function(e) {
                console.log('click!');
                $(this).parent().parent().remove();
                $('input[radio]').prop('checked', false);
                $('input[name=css-tabs]:last').prop('checked', true);
            })
    
            function addTab(tabid, title, URL)
            {
                $.get(URL, function(result, success)
                {
                    $('input[radio]').prop('checked', false);
                    var elm = '<div class="tab-sobatcoding">\
                        <input type="radio" name="css-tabs" id="'+tabid+'" class="tab-switch" checked >\
                        <label for="'+tabid+'" class="tab-label">'+title+'&nbsp;<span class="close-tab">x</span></label>\
                        <div class="tab-content">'+result+'</div>\
                    </div>';
    
                    $('.tabs-sobatcoding').append(elm);
    
                })
                
    
            }
    
        </script>
        <script src="../assets/js/dataTables.bulma.min.js" ></script>
        
        <div class="tab-wrapper">
            <div class="tabs-sobatcoding">
            </div>
        </div>
        
    </body>
    

</html>

Buat juga file bernama login.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Login</title>
        <link rel="stylesheet" href="../assets/css/login.css" />
    </head>
    <body>
        <div class="background">
            <div class="shape"></div>
            <div class="shape"></div>
        </div>
        <form id="form-login" method="POST">
            <h3>Login Here</h3>
    
            <label for="username">Username</label>
            <input type="text" name="username" id="username" placeholder="Email or Phone" autocomplete="off" >
    
            <label for="password">Password</label>
            <input type="password" name="password" id="password" placeholder="Password" autocomplete="off">
    
            <button type="submit">Log In</button>
        </form>
        <script>
            const {ipcRenderer, dialog} = require('electron');
            let $ = jQuery = require('jquery');

            $('#username').trigger('select');

            $(document).on('submit', '#form-login', function() {
        
                let username = $('#username').val();
                let pwd = $('#password').val();
                if( username == 'admin' && pwd == 'admin' )
                {
                    ipcRenderer.send('login')
                }else{
                    ipcRenderer.send('login-error')
                }
            
                return false;
                
            })
        </script>
    </body>
</html>

 

Selain file login.html dan index.html, kita juga buat file table.html dan form.html. Tapi tidak kita bahas disini. Nanti kalian bisa cek di full source code yang diberikan.

 

Step 5: Running Aplikasi

Untuk running aplikasi, pertama kita jalankan dulu Lumen Laravel dengan command berikut

php -S localhost:8080 -t public

Kemudian kita jalankan electron dengan perintah

npm start

 

Demikian tutorial kali ini. Semoga artikel ini bermanfaat.

Untuk full source code bisa kalian baca di link berikut https://github.com/sobatcoding21/Electron-Laravel-CRUD