Aplikasi Database dengan Form Ajax
Pada tulisan ini, saya akan memberikan contoh aplikasi database sederhana dengan menggunakan template Go-Fusebox. Ditambah penggunaan metode Ajax ketika proses tambah/ubah data. Sebelum kita lanjutkan ke pembahasan, ada baiknya Anda melihat demo dari contoh ini disini
Anggap kita mempunyai database yang mempunyai tabel-tabel: data_anggota, provinces, kabupaten,kecamatan dan kelurahan. Tabel data_anggota mempunyai field untuk menghubungkan ke tabel provinces,kabupaten,kecamatan dan kelurahan.
Sebelum memulainya, atur konfigurasi database Anda pada apps/common/config/db.php dengan benar. Setelah itu buatlah definisi circuit dan class yang dibutuhkan pada fusebox.xml.php:
pada tag <circuits>
<circuit alias="bps" path="circuits/bps/" /> <circuit alias="data" path="circuits/data/" />
pada tag <classes>
<class alias="Anggota" classpath="classes/anggota.php"/> <class alias="BPS" classpath="classes/bps.php"/>
Circuit bps adalah circuit untuk mengambil data-data propinsi,kabupaten,kecamatan dan kelurahan yang dapat dipilih ketika input data anggota pada circuit data.
Selanjutnya adalah membuat file class (Anggota dan BPS)
@filename: anggota.php
<?php
class Anggota {
private $db;
function __construct(&$ADOdb) {
$this->db = $ADOdb;
}
public function listAll(){
$sql = "select a.id,a.nama,a.alamat," .
"a.province_id,b.name as propinsi," .
"a.kabupaten_id,c.name as kabupaten," .
"a.kecamatan_id,d.name as kecamatan, " .
"a.kelurahan_id,e.name as kelurahan " .
"from data_anggota a " .
"left join provinces b on a.province_id=b.id " .
"left join kabupaten c on a.kabupaten_id=c.id " .
"left join kecamatan d on a.kecamatan_id=d.id " .
"left join kabupaten e on a.kabupaten_id=e.id";
$rs = $this->db->Execute($sql);
if ($rs->EOF) {
$ret = false;
$rs->Close();
} else {
$ret = $rs;
}
return $ret;
}
public function byID($id=null){
if (!is_null($id) && $id != "") {
return $this->db->GetRow("select * from data_anggota where id=?",array($id));
} else {
return false;
}
}
private function setInput($inputs) {
$colunms = array("nama","alamat","province_id","kabupaten_id","kecamatan_id","kelurahan_id");
$ret = array();
foreach($colunms as $in) {
if (is_null($inputs[$in])) {
array_push($ret,null);
} else {
array_push($ret,$inputs[$in]);
}
}
return $ret;
}
public function insert($postData){
$sql = "insert into data_anggota (nama,alamat,province_id,kabupaten_id,kecamatan_id,kelurahan_id) values (?,?,?,?,?,?)";
$inputs = $this->setInput($postData);
$ret = $this->db->Execute($sql,$inputs);
$status = false; $insert_id = 0;
if ($ret) {
$status = true;
$insert_id = $this->db->Insert_ID();
}
return array(
"status"=>$status,
"insert_id"=>$insert_id
);
}
public function update($postData){
$sql = "update data_anggota set nama=?,alamat=?,province_id=?,kabupaten_id=?,kecamatan_id=?,kelurahan_id=? where id=?";
$inputs = $this->setInput($postData);
array_push($inputs,$postData["id"]);
$ret = $this->db->Execute($sql,$inputs);
$status = false; $affected = 0;
if ($ret) {
$status = true;
$affected = $this->db->Affected_Rows( );
}
return array(
"status"=>$status,
"affected"=>$affected
);
}
public function delete($id) {
$sql = "delete from data_anggota where id=?";
$ret = $this->db->Execute($sql,array($id));
$status = false; $affected = 0;
if ($ret) {
$status = true;
$affected = $this->db->Affected_Rows( );
}
return array(
"status"=>$status,
"affected"=>$affected
);
}
}
?>
@filename: bps.php
<?php
class BPS {
private $db;
function __construct(&$ADOdb) {
$this->db = $ADOdb;
}
public function getKab($province_id){
$data = $this->db->GetAll(
"select * from kabupaten where province_id=?",
array($province_id)
);
return $data;
}
public function getKec($province_id,$kabupaten_id){
$data = $this->db->GetAll(
"select * from kecamatan where province_id=? and kabupaten_id=?",
array($province_id,$kabupaten_id)
);
return $data;
}
public function getKel($province_id,$kabupaten_id,$kecamatan_id){
$data = $this->db->GetAll(
"select * from kelurahan where province_id=? and kabupaten_id=? and kecamatan_id=?",
array($province_id,$kabupaten_id,$kecamatan_id)
);
return $data;
}
}
?>
Langkah selanjutnya adalah membuat alur program pada circuit.xml di setiap circuit(direktori), dalam hal ini bps dan data.
circuit.xml.php (bps):
<?xml version="1.0" encoding="utf-8"?>
<circuit access="public" xmlns:php="php/">
<prefuseaction>
<if condition="$originalFuseaction == $myFusebox->thisFuseaction">
<true>
<instantiate class="BPS" object="bps" arguments="$adodb"/>
<php:include file="apps/vendors/FastJSON.class.php"/>
</true>
</if>
</prefuseaction>
<fuseaction name="getKab">
<invoke
object="bps"
methodcall="getKab($_POST['province_id'])"
returnvariable="data" />
<do action="echo"/>
</fuseaction>
<fuseaction name="getKec">
<invoke
object="bps"
methodcall="getKec($_POST['province_id'],$_POST['kabupaten_id'])"
returnvariable="data" />
<do action="echo"/>
</fuseaction>
<fuseaction name="getKel">
<invoke
object="bps"
methodcall="getKel($_POST['province_id'],$_POST['kabupaten_id'],$_POST['kecamatan_id'])"
returnvariable="data" />
<do action="echo"/>
</fuseaction>
<fuseaction name="echo" access="private">
<if condition="$_GET['ajax']=='1'">
<true><set value="echo FastJSON::encode(\$data);" evaluate="true"/></true>
</if>
</fuseaction>
</circuit>
circuit.xml.php (data):
<?xml version="1.0" encoding="utf-8"?>
<circuit access="public" xmlns:php="php/">
<prefuseaction>
<if condition="$originalFuseaction == $myFusebox->thisFuseaction">
<true><instantiate class="Anggota" object="anggota" arguments="$adodb"/></true>
</if>
</prefuseaction>
<fuseaction name="list">
<set name="fbx_pagetitle" value="Data Anggota" />
<xfa name="add" value="add"/>
<xfa name="edit" value="edit"/>
<xfa name="delete" value="delete"/>
<include template="dsp_list" contentvariable="fbx_maincontent"/>
</fuseaction>
<fuseaction name="form" access="private">
<xfa name="list" value="list"/>
<xfa name="add" value="add"/>
<include template="dsp_form" />
</fuseaction>
<fuseaction name="add">
<xfa name="action" value="insert"/>
<set name="fbx_pagetitle" value="Tambah Data Anggota"/>
<do action="form" contentvariable="fbx_maincontent"/>
</fuseaction>
<fuseaction name="edit">
<xfa name="action" value="update"/>
<set name="fbx_pagetitle" value="Ubah Data Anggota"/>
<do action="form" contentvariable="fbx_maincontent"/>
</fuseaction>
<fuseaction name="insert">
<invoke
object="anggota"
methodcall="insert($_POST)"
returnvariable="ret" />
<do action="echo"/>
</fuseaction>
<fuseaction name="update">
<invoke
object="anggota"
methodcall="update($_POST)"
returnvariable="ret" />
<do action="echo"/>
</fuseaction>
<fuseaction name="delete">
<invoke
object="anggota"
methodcall="delete($_POST['id'])"
returnvariable="ret" />
<do action="echo"/>
</fuseaction>
<fuseaction name="echo" access="private">
<if condition="$_GET['ajax'] == '1'">
<true>
<php:include file="apps/vendors/FastJSON.class.php"/>
<set value="echo FastJSON::encode(\$ret);" evaluate="true"/>
</true>
</if>
</fuseaction>
</circuit>
Yang perlu diperhatikan pada kedua circuit.xml diatas adalah fuseaction “echo”, fungsi dari fuseaction itu adalah mengubah nilai kembali suatu proses kedalam format JSON jika ada parameter querystring yang menandakan sebuah request Ajax ($_GET['ajax] == ‘1′). File FastJSON.class.php adalah class dari pihak ketiga, yang dapat di download dari : PHP Classes
Langkah selanjutnya adalah membuat file-file fuse yang dibutuhkan, dapat kita lihat ada dua fuse yang dibutuhkan pada circuit data yaitu dsp_list dan dsp_form. Kita lewati fuse dsp_list karena tidak ada yang istimewa, hanya file untuk menampilkan data yang disimpan (source dapat di download pada akhir artikel ini). Kita beralih ke fuse dsp_form. Buat kode dasarnya:
<?php
$data = $anggota->byID($attributes["id"]);
$dataProp = $adodb->GetAll("select * from provinces");
?>
<h2><?php echo $fbx_pagetitle; ?></h2>
<form id="myForm" action="<?php echo $myself.$XFA["action"]; ?>" method="post">
<?php if ($data) : ?>
<input type="hidden" name="id" value="<?php echo $data["id"] ?>"/>
<?php endif; ?>
<table>
<tr>
<td><strong>Nama</strong></td>
<td><input type="text" name="nama" id="nama" value="<?php echo $data["nama"] ?>" size="50"/></td>
</tr>
<tr>
<td><strong>Alamat</strong></td>
<td><input type="text" name="alamat" id="alamat" value="<?php echo $data["alamat"] ?>" size="70"/></td>
</tr>
<tr>
<td><strong>Propinsi</strong></td>
<td><?php
echo '<select name="province_id" id="province_id">';
echo '<option value="">-- Pilih Propinsi --</option>';
foreach($dataProp as $prop) {
if ($data["province_id"] == $prop["id"]) $sel = ' selected="selected"';
echo '<option value="'.$prop["id"].'"'.$sel.'>'.$prop["name"].'</option>';
}
echo '</select>';
?>
</td>
</tr>
<tr>
<td><strong>Kabupaten/Kota</strong></td>
<td><select name="kabupaten_id" id="kabupaten_id">
<option value="">-- Pilih Kab/Kota --</option>
</select>
<span id="kabupaten_loader"></span> </td>
</tr>
<tr>
<td><strong>Kecamatan</strong></td>
<td><select name="kecamatan_id" id="kecamatan_id">
<option value="">-- Pilih Kecamatan --</option>
</select>
<span id="kecamatan_loader"></span> </td>
</tr>
<tr>
<td><strong>Kelurahan</strong></td>
<td><select name="kelurahan_id" id="kelurahan_id">
<option value="">-- Pilih Kelurahan --</option>
</select>
<span id="kelurahan_loader"></span> </td>
</tr>
<tr>
<td> </td>
<td><button type="button" id="btnSave">Simpan</button>
<button type="reset">Reset</button>
<span id="save_loader"></span> | <a href="<?php echo $myself.$XFA["list"] ?>">List Anggota</a> | <a href="<?php echo $myself.$XFA["add"] ?>">Data Baru</a> </td>
</tr>
</table>
</form>
Kita akan membuat input bertingkat untuk memudahkan seleksi propinsi,kabupaten,kecamatan dan kelurahan. Combo box propinsi dibuat sebagaimana mestinya, sedangkan sisanya hanya berupa combo box yang kosong. Untuk membuat seleksi bertingkat kita menggunakan metode Ajax dengan bantuan script dari prototype.js . Ada dua file .js yang diperlukan, saya beri nama keduanya my_common.js dan bps.js, file-file .js (termasuk prototype.js) saya letakkan pada direktori assets/js/
Jangan lupa menambahkan kode untuk me-link file prototype.js, my_common.js dan bps.js pada dsp_form:
<script src="assets/js/prototype.js"></script> <script src="assets/js/my_common.js"></script> <script> var post_province_id = "<?php echo $data["province_id"] ?>"; var post_kabupaten_id = "<?php echo $data["kabupaten_id"] ?>"; var post_kecamatan_id = "<?php echo $data["kecamatan_id"] ?>"; var post_kelurahan_id = "<?php echo $data["kelurahan_id"] ?>"; </script> <script src="assets/js/bps.js"></script>
Langkah terakhir adalah mengaktifkan tombol Simpan agar mengirim request Ajax ke server untuk pemrosesan data (insert/update). Kita buat file .js dengan nama update.js dan kita letakkan pada circuit aktif (apps/index/circuits/data/). Jangan lupa untuk menambahkan link ke file tersebut pada dsp_form:
<script src="<?php echo $originalCircuitPath."update.js"; ?>"></script>
Happy Fuseboxing
Source Code : gofusebox-demo-ajax
Keterangan: Source code berisi dump sql database, direktori apps dan assets untuk dipasang(di-replace) pada template go-fusebox.
Wah keren banget tutor2nya BOS… Jadi ngerti ane ttg fusebox… Dari kemaren2 gak mudeng belajar fbx ini… Skrg jd agak mudeng… Mantabs abis… Banyakin lagi tuto2nya ttg fbx bos… Like it
Halo bro…
mantabs demonya…
btw…, boleh minta dbnya?
Makasih
@Rius
db-nya ada di : http://blog.fbxphpindonesia.com/wp-content/uploads/2010/09/gofusebox-demo-ajax.zip
kalo mau test di lokal, download template gofusebox dulu di: http://fbxphpindonesia.com/projects/GoFusebox/GoFusebox.zip (kalo belom punya), setting database di apps/common/config/db.php
mas,mantabs bnget ne ilmunya..boleh minta script dan database yang seperti demo g?lagi butuh nie mas bro..mohon bantuanya..