Tepat 1 minggu yg lalu, saya bersama dengan Isdah, menyelesaikan website GrahaPromo.com—website iklan. Sempet muncul beberapa konsep baru yg emang pengen banget saya share ke pembaca semua. Salah satunya adalah options Propinsi dan Kota. Dua buah select input yg satu berisi daftar propinsi dan yg lain berisi daftar kota. Apabila select propinsi kita pilih “Jawa Timur” Maka select kota akan berisi daftar kota di Jawa Timur aja.

Pengennya sih mau langsung implementasi pakai XmlHttpRequest alias AJAX. Tetapi, ketika saya browsing2 di Aleto.ch, saya nemu sebuah cara untuk buat fungsi ini bekerja tanpa XmlHttpRequest. Alternatifnya kita pakai kemampuan DOM untuk memanipulasi tag <script> dan meng-edit atribut src nya mengarah kepada file PHP penghasil daftar kota kita.

Contoh Kode nya sbb:

// fungsi ini berguna untuk menambah tag html baru lewat
// dom. Ini saya ambil dari http://aleto.ch
function newEle(type, content, toNode, attrs, before) {	
    if(type) {        
        var ele=toNode.ownerDocument.createElement(type), i;
        if(attrs) for(i=0;i<attrs.length;i+=2) ele[attrs[i]]=attrs[i+1];
        if(content) {
            if(content=="empty") ele.appendChild(
                toNode.ownerDocument.createTextNode(" "));
            else ele.appendChild(toNode.ownerDocument.createTextNode(content));
        }
        if(before) toNode.parentNode.insertBefore(ele, toNode);
        else toNode.appendChild(ele);
        return ele;
        
    } else {
        toNode.appendChild(toNode.ownerDocument.createTextNode(content));
    }
}

Dengan fungsi di atas, kita bisa memanipulasi tag <script> untuk mengakses URL php kita, dimana file PHP mengoutputkan kode JavaScript yg akan mengisi select kita dengan data kota yg di-inginkan.

Kemudian kita buat fungsi Callback yang akan dipanggil oleh aplikasi server kita—dalam hal ini sebuah script PHP yang mengoutputkan kode2 javascript.

// dipanggil oleh file PHP yang kita akan request via tag <script>
// kerjanya cuman nge-reset isi select propinsi dan kota, kemudian
// mengisi dengan data baru
function setCity(selProp, selKota) {
    if (p = document.getElementById("propinsi")) {
        if (p.options.length == 0) {
            selIndex = -1;
            for(i=0;i<arrPropinsi.length;i++) {
                p.options[i] = new Option(arrPropinsi[i], arrPropinsi[i]);
                if (arrPropinsi[i] == selProp) selIndex = i;
            }
            p.selectedIndex = selIndex;
        }
    }

    if (k = document.getElementById("kota")) {
        k.options.length = 0;
        k.selectedIndex = -1;
        selIndex = -1;
        for(i=0;i<arrKota.length;i++) {
            k.options[i] = new Option(arrKota[i], arrKota[i]);
            if (arrKota[i] == selKota) selIndex = i;
        }
        k.selectedIndex = (selIndex == -1) ? 0 : selIndex;
    }
}

OK. JavaScript nya kita putus sebentar, kita buat kode PHP nya.

<?php 
header("Content-Type: text/javascript");

$conn = mysql_connect($host,$user,$pass) or die(mysql_error());
mysql_select_db($data) or die(mysql_error());

$p = isset($_GET["p"]) ? $_GET["p"] : "";
$k = isset($_GET["k"]) ? $_GET["k"] : "";

$arr_propinsi[] = "";
$arr_kota = array();

$rs = mysql_query("SELECT DISTINCT propinsi FROM kota", $conn) 
    or die(mysql_error());
while($row = mysql_fetch_array($rs)) {
    $arr_propinsi[] = $row["propinsi"];
}
mysql_free_result($rs);

if ($p) {
    $rs = mysql_query("SELECT * FROM kota WHERE propinsi LIKE '$p'", $conn) 
        or die(mysql_error());
    while($row = mysql_fetch_array($rs)) {
        $arr_kota[] = $row["kota"];
    }
}
?>

arr_propinsi = ['<?php echo implode("','", $arr_propinsi); ?>'];
arr_kota = ['<?php echo implode("','", $arr_kota); ?>'];

// pemanggilan fungsi setCity kita tulis di sini,
setCity('<?php echo $p; ?>', '<?php echo $k; ?>');

INGAT: kode diatas adalah kode PHP yang outputnya berupa JavaScript, bukan HTML, jadi jangan lupa, content-type header kita set ke javascript, bukan standard PHP yang text/html.

Kita lanjutkan ke JavaScript kita, sekarang tinggal kita sambungkan “missing-link” dari keduanya dengan menggunakan DOM.

function getCity() {
    propinsi = ((p=document.getElementById("propinsi")) && p.selectedIndex > -1) 
        ? p.value 
	: currProp;
    kota = ((k=document.getElementById("kota")) && k.selectedIndex > -1) ? k.value : currCity;
    if(server=document.getElementById("server")) server.parentNode.removeChild(server);
    newEle("script","",document.getElementsByTagName("head")[0],
        ["src","/getcity.php?p="+propinsi+"&k="+kota,"type","text/javascript","id","server"]);
}

currProp="";
currCity="";

window.onload = function() { getCity(); }

Fungsi diatas, akan kita sambung dengan event onClick select propinsi. Tugas utamanya cuman mengambil isi dari propinsi & kota yang kita pilih, kemudian mencari tag <script> dengan atribut id = server di bagian head html, dan mengganti atribut src nya dengan URL getCity.php?p=nilai_propinsi&k=nilai_kota
Untuk inisialisasi awal, hook event onLoad, dengan fungsi diatas, untuk inisialisasi select propinsi dan kota, dan variabel global inisialisasi.

Tinggal setting html nya

Propinsi: <select id="propinsi" name="state" 
	onchange="getCity()" 
	onkeyup="getCity()"></select><br />
Kota: <select id="kota" 
	name="city"></select><br />

Pengen liat hasilnya? Silahkan coba Live Demo nya. Bila anda ingin men-download dan mencobanya sendiri, silahkan download attachment di bawah. Mungkin anda perlu database propinsi dan kota se-Indonesia untuk menjalankannya. Anda juga bisa lang meng-execute file insertkota.php yang saya generate dari wikipedia, untuk mengisi data propinsi dan kota anda.

Attachment: