Master Data Perusahaan

Pada tutorial kali ini kita akan membuat master data perusahaan. Master data perusahaan ini akan kita gunakan untuk mengelola data perusahaan. Pada data ini juga kita akan coba implementasikan AJAX dan DataTable.

Untuk membuatnya, kita akan melalui tahapan-tahapan sebagai berikut:

  1. Pembuatan table a_company dan sample isinya
  2. Pembuatan concern dan model a_company
  3. Penyesuaian JI_Controller untuk validasi dan API
  4. Pembuatan controller untuk API dan view
  5. Pembuatan view dan komponen HTML untuk datatable, form tambah dan edit, dan juga detail
  6. Menambahkan ke menu sidebar

Kemudian untuk file yang akan diubah atau dibuat baru melingkupi:

app/
├── core/
│ └── ji_controller.php
├── controller/
│ └── admin/
│ │ └── perusahaan/
│ │   └── masterdata.php
│ └── api_admin/
│  └── perusahaan/
│    └── masterdata.php
└── view/
 └── admin/
  ├── page/
  │  ├──  component/
  │  │  ├── filter_button.php
  │  │  ├── simpan_button.php
  │  │  └── simpan_perubahan_button.php
  │  └── page/
  │    └── sidebar.php
  └── perusahaan/
    └── masterdata/
      ├── _option_utype.php
      ├── baru_bottom.php
      ├── baru_modal.php
      ├── baru.php
      ├── detail_bottom.php
      ├── detail_modal.php
      ├── detail.php
      ├── edit_bottom.php
      ├── edit_modal.php
      ├── edit.php
      ├── home_bottom.php
      ├── home_modal.php
      └── home.php

Pembuatan table a_company dan sample isinya

Pertama-tama kita akan membuat tabel baru untuk penyimpanan data data master perusahaan. Data user pada tutorial kali ini akan disimpan dalam sebuah tabel bernama a_company. Pastikan database sudah dibuat sebelumnya dan juga sudah terpilih. Kemudian Copy paste kode SQL dibawah ini dan jalankan di PhpMyAdmin atau MySQL query-nya langsung untuk membuat tabel secara otomatis.

SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

DROP TABLE IF EXISTS `a_company`;

CREATE TABLE `a_company` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `utype` enum('Pusat','Cabang') NOT NULL DEFAULT 'Pusat',
  `kode` varchar(16) NOT NULL,
  `nama` varchar(100) NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `negara` varchar(128) DEFAULT NULL,
  `provinsi` varchar(78) DEFAULT NULL,
  `kabkota` varchar(150) DEFAULT NULL,
  `kecamatan` varchar(78) DEFAULT NULL,
  `desakel` varchar(78) DEFAULT NULL,
  `telp` varchar(24) DEFAULT NULL,
  `is_active` int(1) unsigned NOT NULL DEFAULT 1,
  `is_deleted` int(1) unsigned NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

SET FOREIGN_KEY_CHECKS=1;

Kemudian setelah itu, kita akan masukan 2 sample data perusahaan, Copy paste kode SQL dibawah ini dan jalankan di PhpMyAdmin atau MySQL query-nya langsung untuk menambahkan user admin baru.

insert into `a_company`(
	utype,
	kode,
	nama,
	created_at,
	updated_at,
	negara,
	provinsi,
	kabkota
)
values(
	'Cabang',
	'Cetek',
	'PT Cipta Esensi Teknologi',
	NOW(),
	null,
	'Indonesia',
	'Jawa Barat',
	'Kab. Bandung'
),(
	'Pusat',
	'CENAH',
	'PT Cipta Esensi Merenah',
	NOW(),
	null,
	'Indonesia',
	'Jawa Barat',
	'Kab. Bandung'
);

Pembuatan concern dan model a_company

Setelah mengimport tabel a_company kedalam database, sekarang saatnya membuat concern class untuk tabel a_company. Caranya buat file baru di app/model/a_company_concern.php, kemudian copy paste kode dibawah ini dan simpan perubahan pada file tersebut.

<?php
namespace Model;

register_namespace(__NAMESPACE__);
/**
 * Define all general method(s) and constant(s) for a_pengguna table,
 *   can be inherited a Concern class also can be reffered as class constants
 *
 * @version 1.0.0
 *
 * @package Model\Concern
 * @since 1.0.0
 */
class A_Company_Concern extends \JI_Model
{
    public $table = 'a_company';
    public $table_alias = 'ac';

    public function __construct()
    {
        parent::__construct();
        $this->db->from($this->table, $this->table_alias);
    }

    protected function filter_utype($utype='')
    {
        if (strlen($utype)) {
            $this->db->where_as("$this->table_alias.utype",  $this->db->esc($utype));
        }

        return $this;
    }

    protected function filter_is_active($is_active='')
    {
        if (strlen($is_active)) {
            $this->db->where_as("$this->table_alias.is_active", $this->db->esc($is_active));
        }

        return $this;
    }

    protected function filter_keyword($keyword='')
    {
        if (strlen($keyword) > 2) {
            $this->db
                ->where_as("$this->table_alias.kode", $keyword, 'OR', '%like%', 1, 0)
                ->where_as("$this->table_alias.nama", $keyword, 'OR', '%like%', 0, 0)
                ->where_as("$this->table_alias.telp", $keyword, 'and', '%like%', 0, 1);
        }

        return $this;
    }
}

Pembuatan Model a_company untuk PoV API Admin

Kemudian sekarang membuat model a_company hanya untuk ruang lingkup api_admin saja. Ini berarti model yang ini hanya akan dipakai dibawah controller/api_admin/. Hal ini dilakukan supaya kode dapat dimaintenance dengan mudah apabila nanti ada perubahan. unutk itu buatlah file baru di app/model/api_admin/a_company_model.php, kemudian copy paste kode dibawah ini dan simpan perubahan pada file tersebut.

<?php
namespace Model\Admin\API;

register_namespace(__NAMESPACE__);
/**
 * Scoped `api_admin` model for `a_company` table
 *
 * @version 1.0.0
 *
 * @package Model\Admin\API
 * @since 1.0.0
 */
class A_Company_Model extends \Model\A_Company_Concern
{

    public function __construct()
    {
        parent::__construct();
    }

    private function filter($keyword='', $uytpe='', $is_active='')
    {
        $this
            ->filter_utype($uytpe)
            ->filter_is_active($is_active)
            ->filter_keyword($keyword);
        return $this;
    }

    public function count($keyword, $utype, $is_active)
    {
        $this->db->select_as("COUNT(1)", 'total');
        $this->db->from($this->table, $this->table_alias);
        $this->filter($keyword, $utype, $is_active);
        $result = $this->db->get_first();
        if (isset($result->total)) {
            return $result->total;
        } else {
            return 0;
        }
    }

    public function data($page, $pagesize, $sorting_column, $sorting_direction, $keyword, $utype, $is_active)
    {
        $this->db
            ->select_as("$this->table_alias.id", 'id')
            ->select_as("$this->table_alias.utype", 'utype')
            ->select_as("$this->table_alias.kode", 'kode')
            ->select_as("$this->table_alias.nama", 'nama')
            ->select_as("CONCAT($this->table_alias.kabkota, ' ', $this->table_alias.provinsi)", 'alamat')
            ->select_as("$this->table_alias.telp", 'telp')
            ->select_as("$this->table_alias.is_active", 'is_active')
            ->select_as("$this->table_alias.is_deleted", 'is_deleted');
        $this->db->from($this->table, $this->table_alias);
        $this->filter($keyword, $utype, $is_active);
        $this->db->order_by($sorting_column, $sorting_direction)->limit($page, $pagesize);

        return $this->db->get();
    }
}

Pembuatan Model a_company untuk PoV Admin

Setelah PoV API Admin, selanjutnya kita akan membuat untuk Admin. File model ini akan digunakan di controller/admin/ saja. Buat lagi file baru di app/model/admin/a_company_model.php, kemudian copy paste kode dibawah ini dan simpan perubahan pada file tersebut.

<?php
namespace Model\Admin;

register_namespace(__NAMESPACE__);
/**
 * Scoped `admin` model for `a_company` table
 *
 * @version 1.0.0
 *
 * @package Model\Admin
 * @since 1.0.0
 */
class A_Company_Model extends \Model\A_Company_Concern
{

    public function __construct()
    {
        parent::__construct();
    }
}

Penyesuaian kode di JI_Controller dan JI_Model

Kelas JI_Controller merupakan kelas yang dipanggil oleh semua controller. untuk itu, apabila ada method-method atau fungsi-fungsi yang ingin tersedia pada setiap kelas controller, harus di definisikan disini.

Contoh: Fungsi untuk menampilkan JSON pada HTTP response untuk keperluan API itu pasti selalu ada untuk controller pada PoV API.

Sekarang kita ubah code pada app/core/ji_controller.php, menjadi seperti ini:

<?php
/**
 * Core class for all controller
 *   contains general purpose methods that nice to have in all controllers
 *
 * @version 1.0.0
 *
 * @package Core\Controller
 * @since 1.0.0
 */
class JI_Controller extends \SENE_Controller
{
    protected $user_login = false;
    protected $admin_login = false;
    private $session_current = null;
    
    public function __construct()
    {
        parent::__construct();
        $this->session_current_check();
    }

    public function session_current_check()
    {
        $session = $this->session_current;
        if (!is_null($session) && isset($session->user->id) && isset($session->admin->id)) {
            return  $session;
        }

        $session = $this->getKey();
        if (!is_object($session)) {
            $session = new stdClass();
            $session->user = new stdClass();
            $session->admin = new stdClass();
        }
        if (!isset($session->user)) {
            $session->user = new stdClass();
        }
        if (isset($session->user->id)) {
            $this->user_login = true;
        }

        if (!isset($session->admin)) {
            $this->sessions->admin = new stdClass();
        }
        if (isset($session->admin->id)) {
            $this->admin_login = true;
        }
        $this->session_current = $session;

        return $this;
    }

    protected function config_semevar($key, $default='')
    {
        if (isset($this->config->semevar->{$key})) {
            return $this->config->semevar->{$key};
        } else {
            return $default;
        }
    }

    public function __init()
    {
        $data = array();
        $data['sess'] = $this->session_current;

        return $data;
    }

    private function __json_response_default($data)
    {
        $data = array();
        $data["status"]  = (int) $this->status;
        $data["message"] = $this->message;
        $data["data"]  = $data;

        return $data;
    }

    protected function response_missing_required_parameter()
    {
        $this->status = 422;
        $this->message = 'One or more parameter was missing';
        header("HTTP/1.0 422 missing some required parameter(s)");
        $this->__json_out(array());
        die();
    }

    protected function response_no_data()
    {
        $this->status = 204;
        $this->message = 'No data';
        header("HTTP/1.0 204 no data");
        $this->__json_out(array());
        die();
    }

    protected function validate_id($id)
    {
        $id = intval($id);
        if ($id <= 0) {
            $id = 0;
        }

        if (empty($id)) {
            $this->response_missing_required_parameter();
        }

        return $id;
    }

    /**
     * API need to protected from unauthorized access
     *
     * @param  mixed $dt input object or array
     * @return string     sting json formatted with its header
     */
    public function __protect_api($data=array())
    {
        if (!$this->admin_login) {
            $this->status = 400;
            $this->message = 'Harus login';
            header("HTTP/1.0 400 Harus login");
            $this->__json_out($data);
            die();
        }
    }

    private function sorting_direction()
    {
        $sorting_direction = strtoupper($this->input->post("sSortDir_0", 'DESC'));
        if ($sorting_direction != "ASC") {
            return 'DESC';
        } else {
            return 'ASC';
        }
    }

    private function sorting_column()
    {
        return trim(strtoupper($this->input->post("iSortCol_0", 'id')));
    }

    private function filter_keyword()
    {
        return trim(strip_tags($this->input->post("sSearch", '')));
    }

    /**
     * Build data table request
     *
     * @return object     datatable request object
     */
    public function __datatable_request()
    {
        $datatable_request = new stdClass();
        $datatable_request->sorting =  new stdClass();
        $datatable_request->sorting->column = $this->sorting_column();
        $datatable_request->sorting->direction = $this->sorting_direction();
        $datatable_request->filter = new stdClass();
        $datatable_request->filter->keyword = $this->filter_keyword();
        $datatable_request->pagination = new stdClass();
        $datatable_request->pagination->page = $this->input->post("iDisplayStart");
        $datatable_request->pagination->size = intval($this->input->post("iDisplayLength", 0));
        
        return $datatable_request;
    }

    /**
     * Procedure for output the json formatted string
     *   to HTTP Response
     *
     * @param  mixed $dt input object or array
     * @return string     sting json formatted with its header
     */
    public function __json_out($data)
    {
        $this->lib('sene_json_engine', 'sene_json');
        $this->sene_json->out($this->__json_response_default($data));
        die();
    }
    

    /**
     * Procedure for generating output for datatable response
     *   on JSON format
     * 
     * This can be consumed for DataTable Ajax request API
     *
     * @param array $data    array of object
     * @param int   $count   number of counted row
     * @param array $another array of array for addition information
     * 
     * @return      Datatable array of array response
     */
    public function __json__datatable($data, $count, $another=array())
    {
        $this->lib('sene_json_engine', 'sene_json');
        $rdata = array();
        if (!is_array($data)) {
            $data = array();
        }
        $dt1 = array();
        $dt2 = array();
        if (!is_array($data)) {
            trigger_error('jsonDataTable first params need array!');
            die();
        }
        foreach ($data as $dat) {
            $dt2 = array();
            if (is_int($dat)) {
                trigger_error('[ERROR: '.$dat.'] Data table not well performed because a query execution error!');
            }
            foreach ($dat as $dt) {
                $dt2[] = $dt;
            }
            $dt1[] = $dt2;
        }

        if (is_array($another)) {
            $rdata = $another;
        }
        $rdata['data'] = $dt1;
        $rdata['recordsFiltered'] = $count;
        $rdata['recordsTotal'] = $count;
        $rdata['status'] = (int) $this->status;
        $rdata['message'] = $this->message;
        $this->sene_json->out($rdata);
        die();
    }

    public function index() { }
}

Kemudian untuk file app/core/ji_model.php, buatlah menjadi seperti ini.

<?php
/**
* Define all general method for all tables
*   For class models
*
* @package Core\Model
* @since 1.0
*/
class JI_Model extends \SENE_Model
{
    /** @var string  */
    public $table;

    /** @var string  */
    public $table_alias;

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Insert a row data
     *
     * @param  array   $d   Contain associative array that represent the pair of column and value
     * @return int          Return last ID if succeed, otherwise will return 0
     */
    public function set($d)
    {
        $this->db->insert($this->table, $d, 0, 0);
        return $this->db->last_id;
    }

    /**
     * Update a row data by supplied ID
     *
     * @param  int      $id    Positive integer
     * @return boolean         True if succeed, otherwise false
     */
    public function update($id, $d)
    {
        $this->db->where("id", $id);
        return $this->db->update($this->table, $d, 0);
    }

    /**
     * Delete row data by ID
     *
     * @param  int      $id    Positive integer
     * @return boolean         True if succeed, otherwise false
     */
    public function del($id)
    {
        $this->db->where("id", $id);
        return $this->db->delete($this->table);
    }

    /**
     * Get single row data by ID
     *
     * @param  int      $id     Positive integer
     * @return stdClass         Will return single row object, otherwise will return empty object
     */
    public function id($id)
    {
        $this->db->where("id", $id);
        return $this->db->from($this->table, $this->table_alias)->get_first('', 0);
    }

    /**
     * Open the database transaction session
     * @return boolean True if succeed, otherwise false
     */
    public function trans_start()
    {
        $r = $this->db->autocommit(0);
        if ($r) {
            return $this->db->begin();
        }
        return false;
    }

    /**
     * Execute `commit` SQL command
     * @return boolean True if succeed, otherwise false
     */
    public function trans_commit()
    {
        return $this->db->commit();
    }

    /**
     * Rollback the database transaction session
     * @return boolean True if succeed, otherwise false
     */
    public function trans_rollback()
    {
        return $this->db->rollback();
    }

    /**
     * Finalize the database transaction session
     * @return boolean True if succeed, otherwise false
     */
    public function trans_end()
    {
        return $this->db->autocommit(1);
    }
}

Membuat Controller untuk halaman perusahaan master data

Setelah selesai penyesuaian kode pada kelas core (JI_Controller dan JI_Model), sekarang kita akan membuat file baru untuk halaman data master perusahaan. Pada kelas controller kali ini akan ada Point of View (sudut pandang) yaitu API_Admin dan Admin.

Controller untuk PoV Admin

Pada versi admin hanya digunakan untuk memanggil view saja, mari kita buat file di app/controller/admin/perusahaan/masterdata.php, dan copy paste kode dibawah ini

<?php
/**
* Main Controller Class for Perusahaan Master Data
*   on PoV Admin
*
* Mostly for this controller will resulting HTTP Body Content in HTML format
*
* @version 1.0.0
*
* @package Controller\Admin\Perusahaan
* @since 1.0.0
*/
class MasterData extends JI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->setTheme('admin');
        $this->load("a_company_concern");
        $this->load("admin/a_company_model", 'acm');
        $this->lib("seme_purifier");
        $this->current_parent = 'perusahaan';
        $this->current_page = 'perusahaan_masterdata';
    }
    public function index()
    {
        $data = $this->__init();
        if(!$this->admin_login) {
            redir(base_url_admin('login'));
            die();
        }

        $this->setTitle('Perusahaan: Master Data '.$this->config_semevar("admin_site_suffix"));

        $this->putThemeContent("perusahaan/masterdata/home_modal", $data);
        $this->putThemeContent("perusahaan/masterdata/home", $data);
        $this->putJsContent("perusahaan/masterdata/home_bottom", $data);
        $this->loadLayout('col-2-left', $data);

        $this->render();
    }

    public function baru()
    {
        $data = $this->__init();
        if(!$this->admin_login) {
            redir(base_url_admin('login'));
            die();
        }

        $this->setTitle('Perusahaan: Master Data: Baru '.$this->config_semevar("admin_site_suffix"));

        $this->putThemeContent("perusahaan/masterdata/baru_modal", $data);
        $this->putThemeContent("perusahaan/masterdata/baru", $data);
        $this->putJsContent("perusahaan/masterdata/baru_bottom", $data);
        $this->loadLayout('col-2-left', $data);

        $this->render();
    }

    public function edit($id)
    {
        $data = $this->__init();
        if (!$this->admin_login) {
            redir(base_url_admin('login'));
            die();
        }

        $acm = $this->acm->id(intval($id));
        if(!isset($acm->id)) {
            redir(base_url_admin('perusahaan/masterdata/'));
            die();
        }

        $data['acm'] = $acm;

        $this->setTitle('Perusahaan: Master Data: Edit #'.$acm->id.' '.$this->config_semevar("admin_site_suffix"));

        $this->putThemeContent("perusahaan/masterdata/edit_modal", $data);
        $this->putThemeContent("perusahaan/masterdata/edit", $data);
        $this->putJsContent("perusahaan/masterdata/edit_bottom", $data);
        $this->loadLayout('col-2-left', $data);

        $this->render();
    }

    public function detail($id)
    {
        $data = $this->__init();
        if (!$this->admin_login) {
            redir(base_url_admin('login'));
            die();
        }
        $id = (int) $id;
		
        $acm = $this->acm->id(intval($id));
        if(!isset($acm->id)) {
            redir(base_url_admin('perusahaan/masterdata/'));
            die();
        }
		
        $data['acm'] = $acm;
        
		$this->setTitle('Perusahaan: Master Data: Detail #'.$acm->id.' '.$this->config_semevar("admin_site_suffix"));
        
		$this->putThemeContent("perusahaan/masterdata/detail", $data);
        $this->putJsContent("perusahaan/masterdata/detail_bottom", $data);
        $this->loadLayout('col-2-left', $data);

        $this->render();
    }
}

Controller untuk PoV API Admin

Selanjutnya kita akan membuat untuk PoV API_Admin. Pada PoV API admin, controller akan bertindak sebagai middleware sekaligus data source. Buat file di app/controller/api_admin/perusahaan/masterdata.php, lalu copy paste kode dibawah ini

<?php
/**
* Main Controller Class for Perusahaan Master Data
*   on PoV API Admin
*
* Mostly for this controller will resulting HTTP Body Content in HTML format
*
* @version 1.0.0
*
* @package Controller\Admin\API\Perusahaan
* @since 1.0.0
*/
class MasterData extends \JI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->lib("seme_purifier");
        $this->load("a_company_concern");
        $this->load("api_admin/a_company_model", 'acm');
    }

    /**
     * Mapping the column number from datatable request into column name
     *
     * @param  int     $column_number
     * 
     * @return string  Full qualified column name with table prefix
     */
    private function sorting_column($column_number)
    {
        // define all table aliases here
        $table_alias = $this->acm->table_alias;

        // translate number column from datatable request to
        //   column name
        switch ($column_number) {
            case 0:
                $sorting_column = "$table_alias.id";
                break;
            case 1:
                $sorting_column = "$table_alias.utype";
                break;
            case 2:
                $sorting_column = "$table_alias.kode";
                break;
            case 3:
                $sorting_column = "$table_alias.nama";
                break;
            case 4:
                $sorting_column = "concat($table_alias.kabkota, ' ', $table_alias.provinsi)";
                break;
            case 5:
                $sorting_column = "$table_alias.telp";
                break;
            case 6:
                $sorting_column = "$table_alias.is_active";
                break;
            default:
                $sorting_column = "$table_alias.id";
        }

        return $sorting_column;
    }

    public function index()
    {
        $init_data = $this->__init();
        $this->__protect_api();
        
        $request = $this->__datatable_request();
        $utype = $this->input->post("utype", '');
        $is_active = $this->input->post("is_active", '');
        
        $this->status = 200;
        $this->message = 'Berhasil';
        $result_data = $this->acm->data($request->pagination->page, $request->pagination->size, $this->sorting_column($request->sorting->column), $request->sorting->direction, $request->filter->keyword, $utype, $is_active);
        $result_count = $this->acm->count($request->filter->keyword, $utype, $is_active);

        foreach($result_data as &$gd){
            if (isset($gd->nama)) {
                $gd->nama = htmlentities(rtrim($gd->nama, ' - '));
            }
            if (isset($gd->utype)) {
                $gd->utype = ucfirst($gd->utype);
            }
            if (isset($gd->alamat)) {
                $gd->alamat = htmlentities(ltrim($gd->alamat, ', '));
            }
            if (isset($gd->is_active)) {
                if (!empty($gd->is_active)) {
                    $gd->is_active = '<label class="label label-success">Aktif</label>';
                }else{
                    $gd->is_active = '<label class="label label-default">Tidak Aktif</label>';
                }
            }
        }

        $this->__json__datatable($result_data, $result_count);
    }

    private function validate_input()
    {
        $data_to_insert = $_POST;

        foreach ($data_to_insert as &$di){
            $di = trim(strip_tags($di));
        }

        if (!isset($data_to_insert['nama'])) {
            $this->response_missing_required_parameter();
        }

        return $data_to_insert;
    }
    
    public function baru()
    {
        $init_data = $this->__init();
        $this->__protect_api();
        
        $this->acm->trans_start();
        $res = $this->acm->set($this->validate_input());
        if ($res) {
            $this->acm->trans_commit();
            $this->status = 200;
            $this->message = 'Data baru berhasil ditambahkan';

        }else{
            $this->status = 901;
            $this->message = 'Tidak dapat menyimpan data ke database';
            $this->acm->trans_rollback();
        }
        $this->acm->trans_end();

        $this->__json_out(array());
    }

    public function detail($id)
    {
        $init_data = $this->__init();
        $this->__protect_api();

        $data = $this->acm->id($this->validate_id($id));
        if (!isset($data->id)) {
            $this->response_no_data();
        }
        
        $this->status = 200;
        $this->message = 'Berhasil';
        $this->__json_out($data);
    }

    public function edit($id)
    {
        $init_data = $this->__init();
        $this->__protect_api();

        $acm = $this->acm->id($this->validate_id($id));
        if (!isset($acm->id)) {
            $this->response_no_data();
        }

        $res = $this->acm->update($id, $this->validate_input());
        if ($res) {
            $this->status = 200;
            $this->message = 'Success';
        }else{
            $this->status = 901;
            $this->message = 'Tidak dapat merubah data ke database';
        }
        $this->__json_out(array());
    }

    public function hapus($id)
    {
        $init_data = $this->__init();
        $this->__protect_api();

        $acm = $this->acm->id($this->validate_id($id));
        if (!isset($acm->id)) {
            $this->response_no_data();
        }
        
        $res = $this->acm->del($id);
        if ($res) {
            $this->status = 200;
            $this->message = 'Berhasil';
        }else{
            $this->status = 902;
            $this->message = 'Tidak dapat menghapus data ke database';
        }
        $this->__json_out(array());
    }
    
}

Membuat Komponen HTML dan View untuk Halaman Master Data Perusahaan

Setelah controller sudah siap, kini saatnya untuk membuat komponen HTML seperti button dan lain-lain, juga halaman dari master data perusahaan itu sendiri beserta form untuk input dan edit data.

Pembuatan Komponen HTML

Komponen yang pertama yang akan kita buat yaitu komponen filter button. Buatlah file baru di app/view/admin/page/component/filter_button.php, kemudian copy paste kode dibawah ini

<button id="filter_button" class="btn btn-info btn-alt btn-block btn-submit">
    Filter <i class="fa fa-filter icon-submit"></i>
</button>

Selanjutnya komponen untuk button simpan yang akan digunakan oleh setiap isian form. Buatlah file baru di app/view/admin/page/component/simpan_button.php, kemudian copy paste kode dibawah ini

<button type="submit" class="btn btn-primary btn-submit">
    Simpan <i class="fa fa-save icon-submit"></i>
</button>

Lalu kita buat komponen untuk list option di modul perusahaan saja, filenya ada di app/view/admin/perusahaan/masterdata/_option_utype.php, kemudian copy paste kode dibawah ini

<option value="Pusat">Pusat</option>
<option value="Cabang">Cabang</option>

Terakhir komponen untuk button simpan perubahan yang akan digunakan oleh setiap isian form. Buatlah file baru di app/view/admin/page/component/simpan_perubahan_button.php, kemudian copy paste kode dibawah ini

<button type="submit" class="btn btn-primary btn-submit">
    Simpan Perubahan <i class="fa fa-save icon-submit"></i>
</button>

View HTML untuk Home di Master Data Perusahaan

Setelah selesai dengan komponen HTML, sekarang kita akan membuat viewnya yang akan digunakan untuk menampilkan data master perusahaan dalam bentuk tabel. Bukan hanya itu saja, pada halaman ini kita juga akan menambahkan filter berdasarkan kata kunci keyword dan juga filter berdasarkan Flag.

Akan ada 3 file yang akan dibuat untuk halaman ini, yaitu:

  1. home.php
  2. home_modal.php
  3. home_bottom.php

Sekarang mari kita buat file baru di app/view/admin/perusahaan/masterdata/home.php, seperti biasa copy paste kode dibawah ini.

<div id="page-content">
	<!-- Static Layout Header -->
	<div class="content-header">
		<div class="row">
			<div class="col-md-6">&nbsp;</div>
			<div class="col-md-6">
				<div class="btn-group pull-right">
					<a id="" href="<?=base_url_admin('perusahaan/masterdata/baru/')?>" class="btn btn-info"><i class="fa fa-plus"></i> Baru</a>
				</div>
			</div>
		</div>
	</div>
	<ul class="breadcrumb breadcrumb-top">
		<li>Admin</li>
		<li>Perusahaan</li>
		<li>Master Data</li>
	</ul>
	<!-- END Static Layout Header -->

	<!-- Content -->
	<div class="block full">
		<div class="block-title">
			<h4><strong>Master Data Perusahaan</strong></h4>
		</div>

		<div class="row row-filter">
			<div class="col-lg-1 col-md-2 col-sm-6">
				<label>Jenis</label>
				<select id="fl_utype" class="form-control">
					<option value="">-- Semua --</option>
					<?php $this->getThemeElement('perusahaan/masterdata/_option_utype', $__forward); ?>
				</select>
			</div>
			<div class="col-lg-1 col-md-2 col-sm-6">
				<label>Status</label>
				<select id="fl_is_active" class="form-control">
					<option value="">-- Semua --</option>
					<option value="1">Aktif</option>
					<option value="0">Tidak Aktif</option>
				</select>
			</div>
			<div class="col-lg-9 col-md-6 col-sm-8 col-xs-6">&nbsp;</div>
			<div class="col-lg-1 col-md-2 col-sm-4 col-xs-6">
				<label>&nbsp;</label>
				<button id="filter_button" class="btn btn-info btn-alt btn-block btn-submit">
					Filter <i class="fa fa-filter icon-submit"></i>
				</button>
			</div>
		</div>

		<div class="table-responsive">
			<table id="drTable" class="table table-vcenter table-condensed table-bordered">
				<thead>
					<tr>
						<th class="text-center">ID</th>
						<th>Jenis</th>
						<th>Kode</th>
						<th>Nama</th>
						<th>Alamat</th>
						<th>Telp</th>
						<th>Status</th>
					</tr>
				</thead>
				<tbody>
				</tbody>
			</table>
		</div>

	</div>
	<!-- END Content -->
</div>

Selanjutnya kode untuk view modal. Pada file view modal ini digunakan untuk menyimpan komponen modal (Pop Up) menu pilihan ketika baris data pada DataTable di klik. Buatlah file baru di app/view/admin/perusahaan/masterdata/home_modal.php, Kemudian copy paste kode dibawah ini.

<!-- modal option -->
<div id="modal_option" class="modal fade " tabindex="-1" role="dialog" aria-hidden="true">
	<div class="modal-dialog modal-sm">
		<div class="modal-content">

			<!-- Modal Header -->
			<div class="modal-header text-center">
				<h2 class="modal-title">Pilihan</h2>
			</div>
			<!-- END Modal Header -->

			<!-- Modal Body -->
			<div class="modal-body">
				<div class="row">
					<div class="col-xs-12 btn-group-vertical">
						<a id="adetail" href="#" class="btn btn-info btn-left"><i class="fa fa-info-circle"></i> Detail</a>
						<a id="aedit" href="#" class="btn btn-info btn-left"><i class="fa fa-pencil"></i> Edit</a>
						<button id="bhapus" type="button" class="btn btn-danger btn-left btn-submit"><i class="fa fa-trash-o icon-submit"></i> Hapus</button>
					</div>
				</div>
				<div class="row" style="margin-top: 1em; ">
					<div class="col-md-12" style="border-top: 1px #afafaf dashed;">&nbsp;</div>
					<div class="col-xs-12 btn-group-vertical" style="">
						<button type="button" class="btn btn-default btn-block text-left" data-dismiss="modal"><i class="fa fa-trash"></i> Tutup</button>
					</div>
				</div>
				<!-- END Modal Body -->
			</div>
		</div>
	</div>
</div>

Terakhir kita akan membuat code JavaScript supaya datatablenya dapat tampil dan datanya pun dapat terambil melalui API. Begitu juga dengan fungsionalitas filternya. Untuk itu buatlah file baru di app/view/admin/perusahaan/masterdata/home_bottom.php, Kemudian copy paste kode dibawah ini.

public drTable = {};
public ieid = '';

App.datatables();

if(jQuery('#drTable').length>0){
	drTable = jQuery('#drTable')
	.on('preXhr.dt', function ( e, settings, data ){
		$().btnSubmit();
	}).DataTable({
			"order"				: [[ 0, "desc" ]],
			"responsive"	  	: true,
			"bProcessing"		: true,
			"bServerSide"		: true,
			"sAjaxSource"		: "<?=base_url('api_admin/perusahaan/masterdata/')?>",
			"fnServerParams": function ( aoData ) {
				aoData.push(
					{ "name": "a_company_id_parent", "value": $("#fl_a_company_id_parent").val() },
					{ "name": "badan_hukum", "value": $("#fl_badan_hukum").val() },
					{ "name": "is_vendor", "value": $("#fl_is_vendor").val() },
					{ "name": "is_active", "value": $("#fl_is_active").val() },
					{ "name": "utype", "value": $("#fl_utype").val() }
				);
			},
			"fnServerData": function (sSource, aoData, fnCallback, oSettings) {
				oSettings.jqXHR = $.ajax({
					dataType 	: 'json',
					method 		: 'POST',
					url 		: sSource,
					data 		: aoData
				}).done(function (response, status, headers, config) {
					console.log(response);

					$('#drTable > tbody').off('click', 'tr');
					$('#drTable > tbody').on('click', 'tr', function (e) {
						e.preventDefault();
						public id = $(this).find("td").html();
						ieid = id;
						$("#adetail").attr("href","<?=base_url_admin('perusahaan/masterdata/detail/')?>"+ieid);
						$("#aedit").attr("href","<?=base_url_admin('perusahaan/masterdata/edit/')?>"+ieid);
						$("#modal_option").modal("show");
					});

					$().btnSubmit('done');

					fnCallback(response);
				}).fail(function (response, status, headers, config) {
					gritter("<h4>Error</h4><p>Tidak dapat mengambil data sekarang, silahkan coba lagi nanti</p>",'warning');
					$().btnSubmit('done');
				});
			},
	});

	// pencarian data default text
	$('.dataTables_filter input').attr('placeholder', 'Cari kode, nama, telp');
	
	$("#filter_button").on("click",function(e){
		e.preventDefault();
		drTable.ajax.reload();
	});
}


//hapus
$("#bhapus").on("click",function(e){
	e.preventDefault();
	if(ieid){
		let c = confirm('Apakah kamu yakin?');
		if(c){
			$().btnSubmit();
			let url = '<?=base_url("api_admin/perusahaan/masterdata/hapus/")?>'+ieid;
			$.get(url).done(function(response){
				NProgress.done();
				if(response.status==200){
					gritter('<h4>Sukses</h4><p>Data berhasil dihapus</p>','success');
					$('.icon-submit').removeClass('fa-circle-o-notch fa-spin');
					$('.btn-submit').prop('disabled',false);
					NProgress.done();

					drTable.ajax.reload();
					$("#modal_option").modal("hide");
					$("#modal_edit").modal("hide");
				}else{
					gritter('<h4>Gagal</h4><p>'+response.message+'</p>','danger');
					$().btnSubmit('done');
				}
			}).fail(function() {
				gritter('<h4>Error</h4><p>Tidak dapat menghapus data ke database, Cobalah beberapa saat lagi</p>', 'danger');
				$().btnSubmit('done');
			});
		}
	}
});

View HTML untuk Form Tambah Data Baru di Master Data Perusahaan

Sekarang kita akan membuat kode HTML untuk menampilkan form input data di halaman Master Data Perusahaan.

Akan ada 3 file yang akan dibuat untuk halaman ini, yaitu:

  1. baru.php
  2. baru_modal.php
  3. baru_bottom.php

Sekarang mari kita buat file baru di app/view/admin/perusahaan/masterdata/baru.php, seperti biasa copy paste kode dibawah ini.

<div id="page-content">
	<!-- Static Layout Header -->
	<div class="content-header">
		<div class="row">
			<div class="col-md-12">
				<div class="btn-group">
					<a id="aback" href="<?=base_url_admin('perusahaan/masterdata/')?>" class="btn btn-default"><i class="fa fa-chevron-left"></i> Kembali </a>
				</div>
			</div>
		</div>
	</div>
	<ul class="breadcrumb breadcrumb-top">
		<li>Admin</li>
		<li>Perusahaan</li>
		<li><a href="<?=base_url_admin("perusahaan/masterdata/")?>">Master Data</a></li>
		<li>Baru</li>
	</ul>
	<!-- END Static Layout Header -->

	<!-- Content -->
	<div class="block full row">
		<div class="block-title">
			<h4><strong>Form Tambah Data</strong></h4>
		</div>

		<form id="form_tambah" action="<?=base_url_admin()?>" method="post" enctype="multipart/form-data" class="form-bordered form-horizontal" onsubmit="return false;">
			<div class="form-group">
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="iiutype" class="control-label">Jenis *</label>
					<select id="iiutype" class="form-control" name="utype" required>
						<option value="">-- Pilih --</option>
						<?php $this->getThemeElement('perusahaan/masterdata/_option_utype', $__forward); ?>
					</select>
				</div>
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="iis_active" class="control-label">Aktif?</label>
					<select id="iis_active" class="form-control" name="is_active" >
						<option value="1">Iya</option>
						<option value="0">Tidak</option>
					</select>
				</div>
			</div>
			<div class="form-group">
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="iikode" class="control-label">Kode *</label>
					<input id="iikode" class="form-control" name="kode" placeholder="Kode Perusahaan" minlength="1" maxlength="16" required />
				</div>
				<div class="col-lg-11 col-md-9 col-sm-8">
					<label for="iinama" class="control-label">Nama *</label>
					<input id="iinama" class="form-control" name="nama" placeholder="Nama Perusahaan / Kode Cabang" maxlength="100" required/>
				</div>
			</div>

			<div class="form-group">
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="inegara" class="control-label">Negara *</label>
					<input id="inegara" class="form-control" name="negara" placeholder="Negara" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="iprovinsi" class="control-label">Provinsi *</label>
					<input id="iprovinsi" class="form-control" name="provinsi" placeholder="Provinsi" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="ikabkota" class="control-label">Kabupaten / Kota</label>
					<input id="ikabkota" class="form-control" name="kabkota" placeholder="Kab. / Kota" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="ikecamatan" class="control-label">Kecamatan</label>
					<input id="ikecamatan" class="form-control" name="kecamatan" placeholder="Kecamatan" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="idesakel" class="control-label">Desa / Kelurahan</label>
					<input id="idesakel" class="form-control" name="desakel" placeholder="Desa / Kelurahan" required />
				</div>
			</div>

			<div class="form-group form-actions">
				<div class="col-xs-12 text-right">
					<div class="btn-group pull-right">
						<?php $this->getThemeElement('page/component/simpan_button', $__forward); ?>
					</div>
				</div>
			</div>

		</form>
	</div>
</div>

Sementara untuk file modal kita tidak pakai untuk saat ini, jadi cukup buat file baru saja di app/view/admin/perusahaan/masterdata/baru_modal.php, dan biarkan isinya kosong.

Terakhir kita akan membuat code JavaScript untuk menyimpan data secara Asynchronous dengan memanfaatkan keunggulan dari javascript. Untuk itu buatlah file baru di app/view/admin/perusahaan/masterdata/baru_bottom.php, Kemudian copy paste isinya dari kode dibawah ini.

$("#form_tambah").on("submit",function(e){
	e.preventDefault();
	$().btnSubmit();

	public fd = new FormData($(this)[0]);
	public url = '<?= base_url("api_admin/perusahaan/masterdata/baru/")?>';
	$.ajax({
		type: $(this).attr('method'),
		url: url,
		data: fd,
		processData: false,
		contentType: false,
		success: function(respon){
			if(respon.status==200){
				gritter('<h4>Sukses</h4><p>Data berhasil ditambahkan</p>','success');
				setTimeout(function(){
					window.location = '<?=base_url_admin('perusahaan/masterdata/')?>';
				},3000);
			}else{
				gritter('<h4>Gagal</h4><p>'+respon.message+'</p>','danger');
				$().btnSubmit('done');
			}
		},
		error:function(){
			setTimeout(function(){
				gritter('<h4>Error</h4><p>Tidak dapat menyimpan data sekarang, coba lagi nanti</p>','warning');
			}, 666);

			$().btnSubmit('done');
			return false;
		}
	});
});

View HTML untuk Form Edit Data di Master Data Perusahaan

Sekarang kita akan membuat kode HTML untuk menampilkan form untuk edit data di halaman Master Data Perusahaan. Kenapa filenya kita pisah antara edit dan tambah data baru, supaya nanti ketika ada perubahanyang hanya bersifat pada edit saja atau tambah baru saja, form HTML nya dapat di maintenance dengan mudah.

Akan ada 3 file yang akan dibuat untuk halaman ini, yaitu:

  1. edit.php
  2. edit_modal.php
  3. edit_bottom.php

Sekarang mari kita buat file baru di app/view/admin/perusahaan/masterdata/edit.php, seperti biasa copy paste kode dibawah ini.

<div id="page-content">
	<!-- Static Layout Header -->
	<div class="content-header">
		<div class="row">
			<div class="col-md-12">
				<div class="btn-group">
					<a id="aback" href="<?=base_url_admin('perusahaan/masterdata/')?>" class="btn btn-default"><i class="fa fa-chevron-left"></i> Kembali </a>
				</div>
			</div>
		</div>
	</div>
	<ul class="breadcrumb breadcrumb-top">
		<li>Admin</li>
		<li>Perusahaan</li>
		<li><a href="<?=base_url_admin("perusahaan/masterdata/")?>">Master Data</a></li>
		<li>Edit #<?=$acm->id?></li>
	</ul>
	<!-- END Static Layout Header -->

	<!-- Content -->
	<div class="block full">
		<div class="block-title">
			<h4><strong>Form Edit Data</strong></h4>
		</div>

		<form id="form_edit" action="<?=base_url_admin()?>" method="post" enctype="multipart/form-data" class="form-bordered form-horizontal" onsubmit="return false;">
		<div class="form-group">
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="ieutype" class="control-label">Jenis *</label>
					<select id="ieutype" class="form-control" name="utype" required>
						<option value="">-- Pilih --</option>
						<?php $this->getThemeElement('perusahaan/masterdata/_option_utype', $__forward); ?>
					</select>
				</div>
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="ieis_active" class="control-label">Aktif?</label>
					<select id="ieis_active" class="form-control" name="is_active" >
						<option value="1">Iya</option>
						<option value="0">Tidak</option>
					</select>
				</div>
			</div>
			<div class="form-group">
				<div class="col-lg-1 col-md-3 col-sm-4">
					<label for="iekode" class="control-label">Kode</label>
					<input id="iekode" class="form-control" name="kode" placeholder="Kode Perusahaan" minlength="1" maxlength="16" required />
				</div>
				<div class="col-lg-11 col-md-9 col-sm-8">
					<label for="ienama" class="control-label">Nama *</label>
					<input id="ienama" class="form-control" name="nama" placeholder="Nama Perusahaan / Kode Cabang" required/>
				</div>
			</div>

			<div class="form-group">
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="ienegara" class="control-label">Negara *</label>
					<input id="ienegara" class="form-control" name="negara" placeholder="Negara" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="ieprovinsi" class="control-label">Provinsi *</label>
					<input id="ieprovinsi" class="form-control" name="provinsi" placeholder="Provinsi" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="iekabkota" class="control-label">Kabupaten / Kota</label>
					<input id="iekabkota" class="form-control" name="kabkota" placeholder="Kab. / Kota" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="iekecamatan" class="control-label">Kecamatan</label>
					<input id="iekecamatan" class="form-control" name="kecamatan" placeholder="Kecamatan" required />
				</div>
				<div class="col-lg-3 col-md-6 col-sm-6">
					<label for="iedesakel" class="control-label">Desa / Kelurahan</label>
					<input id="iedesakel" class="form-control" name="desakel" placeholder="Desa / Kelurahan" required />
				</div>
			</div>

			<div class="form-group form-actions">
				<div class="col-xs-12 text-right">
					<div class="btn-group pull-right">
						<?php $this->getThemeElement('page/component/simpan_perubahan_button', $__forward); ?>
					</div>
				</div>
			</div>

		</form>
	</div>
</div>

Sementara untuk file modal kita tidak pakai untuk saat ini, jadi cukup buat file baru saja di app/view/admin/perusahaan/masterdata/edit_modal.php, dan biarkan isinya kosong.

Terakhir kita akan membuat code JavaScript untuk mengisi nilai default dari hasil lookup data berdasarkan ID yang akan di edit. Dan juga sama seperti pada JS di halaman tambah baru, disini juga akan mengimplementasikan AJAX untuk penyimpanan datanya. Selanjutnya kita tinggal membuat file baru di app/view/admin/perusahaan/masterdata/edit_bottom.php, Kemudian copy paste isinya dari kode dibawah ini.

// fill data
public data_fill = <?=json_encode($acm)?>;
$.each(data_fill, function(k,v){
	$("#ie"+k).val(v);
});

//submit form
$("#form_edit").on("submit",function(e){
	e.preventDefault();
	$().btnSubmit();

	public fd = new FormData($(this)[0]);
	public url = '<?=base_url("api_admin/perusahaan/masterdata/edit/".$acm->id)?>';

	$.ajax({
		type: $(this).attr('method'),
		url: url,
		data: fd,
		processData: false,
		contentType: false,
		success: function(respon){
			if(respon.status == 200){
				gritter('<h4>Sukses</h4><p>Perubahan data berhasil disimpan</p>', 'success');
				setTimeout(function(){
					window.location = '<?=base_url_admin('perusahaan/masterdata/')?>';
				}, 3456);
			}else{
				gritter('<h4>Gagal</h4><p>'+respon.message+'</p>','danger');
				$().btnSubmit('done');
			}
		},
		error:function(){
			setTimeout(function(){
				gritter('<h4>Error</h4><p>Tidak dapat menyimpan data sekarang, coba lagi nanti</p>','warning');
			}, 666);
        
      $().btnSubmit('done');
			return false;
		}
	});

});

View HTML untuk Detail Data di Master Data Perusahaan

Terakhhir kita akan buat view untuk halaman detail data dari Master Data Perusahaan.

Akan ada 2 file yang akan dibuat untuk halaman ini, yaitu:

  1. detail.php
  2. detail_bottom.php

Sekarang mari kita buat file baru di app/view/admin/perusahaan/masterdata/detail.php, seperti biasa copy paste kode dibawah ini.

<div id="page-content">
	<!-- Static Layout Header -->
	<div class="content-header">
		<div class="row">
			<div class="col-md-6 col-sm-6">
				<div class="btn-group">
					<a id="" href="<?=base_url_admin('perusahaan/masterdata/')?>" class="btn btn-default"><i class="fa fa-chevron-left"></i> Kembali</a>
				</div>
			</div>
			<div class="col-md-6 col-sm-6">
				<div class="btn-group pull-right">
					<a id="" href="<?=base_url_admin('perusahaan/masterdata/edit/'.$acm->id)?>" class="btn btn-info"><i class="fa fa-edit"></i> Edit</a>
				</div>
			</div>
		</div>
	</div>
	<ul class="breadcrumb breadcrumb-top">
		<li>Admin</li>
		<li>Perusahaan</li>
		<li><a href="<?=base_url_admin("perusahaan/masterdata/")?>">Master Data</a></li>
		<li>Detail #<?=$acm->id?></li>
	</ul>
	<!-- END Static Layout Header -->

	<div class="block full">
		<div class="block-title">
			<h4><strong>Informasi Detail</strong></h4>
		</div>
		<div class="row">
			<div class="col-md-12">
				<table class="table table-bordered">
					<tbody>
						<tr>
							<th class="col-md-2">Nama</th>
							<td class="col-md-1">:</td>
							<td><?=$acm->nama?></td>
						</tr>
						<tr>
							<th>Jenis</th>
							<td>:</td>
							<td><?=$acm->utype?></td>
						</tr>
						<tr>
							<th>Kode</th>
							<td>:</td>
							<td><?=$acm->kode?></td>
						</tr>
						<tr>
							<th>Alamat</th>
							<td>:</td>
							<td>
								<?=isset($acm->desakel)?$acm->desakel:''?>
								<?=isset($acm->kecamatan)?$acm->kecamatan:''?><br />
								<?=isset($acm->kabkota)?$acm->kabkota:''?>
								<?=isset($acm->provinsi)?$acm->provinsi:''?><br />
								<?=isset($acm->negara)?$acm->negara:''?>
							</td>
						</tr>
						<tr>
							<th>Telp</th>
							<td>:</td>
							<td><?=$acm->telp?></td>
						</tr>
						<tr>
							<th>Status</th>
							<td>:</td>
							<td><?=!empty($acm->is_active) ? '<label class="label label-success">Aktif</label>': '<label class="label label-default">Tidak Aktif</label>'?></td>
						</tr>
					</tbody>
				</table>
			</div>
		</div>
	</div>
</div>

Sementara untuk file bottom kita tidak pakai untuk saat ini, jadi cukup buat file baru saja di app/view/admin/perusahaan/masterdata/detail_bottom.php, dan biarkan isinya kosong.

Menambahkan Modul Master Data Perusahaan Ke Menu

Untuk menambahkan modul Master Data Perusahaan Ke Menu sidebar itu sangat mudah sekali. Kita cukup isikan kode HTML list (<li>) dan unordered list (<ul>) beserta link pada isi listnya. Namun lain hal cerita apabila kita telah menerapkan metode Authorization seperti RBAC, ACL, ataupun ABAC Ini pasti akan menjadi tantangan tersendiri.

Karena sekarang kita belum menerapkan metode Authorization pada aplikasi yang kita bikin, editlah file app/view/admin/page/html/sidebar.php, buatlah jadi seperti ini.

<?php
	$admin_name = $sess->admin->username ?? '';
	if(isset($sess->admin->nama)) if(strlen($sess->admin->nama)>1) $admin_name = $sess->admin->nama;
	if(!isset($this->current_page)) $this->current_page = "";
	if(!isset($this->current_parent)) $this->current_parent = "";
	$current_page = $this->current_page;
	$current_parent = $this->current_parent;
	$parent = array();
	foreach(($sess->admin->menus->left ?? []) as $key=>$v){
		$parent[$v->identifier] = 0;
		if(count($v->childs)>0){
			foreach($v->childs as $f){
				if($current_page==$f->identifier){
					$current_page = $v->identifier;
					$parent[$v->identifier] = 1;
				}
			}
		}
	}
	$admin_foto = '';
	if(isset($sess->admin->foto))$admin_foto = $sess->admin->foto;
	if(empty($admin_foto)) $admin_foto = 'media/user-default.png';
	$admin_foto = $this->cdn_url($admin_foto);
    $admin_logo_url = '';
    if (isset($this->config->semevar->admin_logo) && strlen($this->config->semevar->admin_logo) > 4) {
        $admin_logo_url = $this->cdn_url($this->config->semevar->admin_logo);
    }
?>
<div id="sidebar">
	<!-- Wrapper for scrolling functionality -->
	<div id="sidebar-scroll">
		<!-- Sidebar Content -->
		<div class="sidebar-content">
			<!-- Brand -->
			<a href="<?=base_url_admin(); ?>" class="sidebar-brand">
				<img src="<?=$admin_logo_url?>" onerror="this.onerror=null;this.src='https://seme-framework-storage.b-cdn.net/images/seme-framework-logo.png';" style="width: 90%;" />
			</a>
			<!-- END Brand -->
			<!-- User Info -->
			<div class="sidebar-section sidebar-user clearfix sidebar-nav-mini-hide">
				<div class="sidebar-user-avatar">
					<a href="<?=base_url_admin('profil'); ?>">
						<img src="<?=$admin_foto?>" alt="avatar" onerror="this.onerror=null;this.src='https://seme-framework-storage.b-cdn.net/images/user-default.png';" />
					</a>
				</div>
				<div class="sidebar-user-name"><?=$admin_name; ?></div>
				<div class="sidebar-user-links">
					<a href="<?=base_url_admin('profil'); ?>" data-toggle="tooltip" data-placement="bottom" title="Profile"><i class="gi gi-user"></i></a>
					<a href="<?=base_url_admin("logout"); ?>" data-toggle="tooltip" data-placement="bottom" title="Logout"><i class="gi gi-exit"></i></a>
				</div>
			</div>
			<!-- END User Info -->
			<!-- Sidebar Navigation -->
			<ul class="sidebar-nav">
				<li class="">
					<a href="<?=base_url_admin('')?>" class=" ">
						<i class=" sidebar-nav-mini-hide"></i>
						<i class="fa fa-home sidebar-nav-icon"></i>
						<span class="sidebar-nav-mini-hide">Dashboard</span>
					</a>
				</li>
				<li class="">
					<a href="#" class="sidebar-nav-menu ">
						<i class="fa fa-angle-left sidebar-nav-indicator sidebar-nav-mini-hide"></i>
						<i class="fa fa-building sidebar-nav-icon"></i>
						<span class="sidebar-nav-mini-hide">Perusahaan</span>
					</a>
					<ul class="">
						<li>
							<a href="<?=base_url_admin('perusahaan/masterdata/')?>" class="">
								Data Master Perusahaan
							</a>
						</li>
					</ul>
				</li>
			</ul>
			<!-- END Sidebar Navigation -->
		</div>
		<!-- END Sidebar Content -->
	</div>
	<!-- END Wrapper for scrolling functionality -->
</div>

Setelah selesai nanti bisa kita lihat, menu baru bernama perusahaan dan ada sub menu di bawahnya bernama master data perusahaan.

Selesai...!

Untuk mencoba hasil dari tutorial ini, buka alamat http://localhost/seme_framework/admin/logout pada browser. Harusnya akan muncul halaman login. Kemudian login dengan menggunakan username dan password pada tutorial sebelumnya. Setelah itu hover pada menu sidebar (samping kiri), nanti akan muncul menu baru. Klik saja pada menu tersebut.