Rabu, 28 September 2011

Membuat Menu Drop-Down dengan CSS

Membuat menu Drop-Down tanpa Javascript

Pada awalnya ada pertanyaan bagaimana membuat menu dropdown yang ringkas dan tanpa kode Javascript yang njlimet. Pertanyaannya sebenarnya sudah dijawab tapi saya ingin membahas lebih rinci tentang hal ini agar mungkin saja dapat menambah wawasan dan pengetahuan tentang penggunaan CSS. Nantinya saya akan mencoba memberikan penjelasan yang lengkap tentang arti dari kode CSS yang digunakan.

1. Kode HTML

Kita mulai dengan membuat sebuah dokumen HTML sederhana yang hanya berisi menu yang akan kita buat. Tentu saja kamu bisa menambah isinya agar menjadi halaman web yang lebih lengkap tapi sekarang kita fokuskan hanya pada bagian menu dropdown yang akan kita buat saja. Berikut ini kode HTML-nya:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="id">
<head>
<title>Menu Drop-Down</title>
<style type="text/css" media="screen, projection">
/* CSS-nya ditulis di disini ! */

</style>
</head>
<body>
<ul id="menu">
<li><a href="#">Beranda</a></li>
<li><a href="#">Tentang</a>
<ul>
<li><a href="#">Sejarah</a></li>
<li><a href="#">Tim</a></li>
<li><a href="#">Kantor</a></li>
</ul>
</li>
<li><a href="#">Layanan</a>
<ul>
<li><a href="#">Desain Web</a></li>
<li><a href="#">Internet Marketing</a></li>
<li><a href="#">Hosting</a></li>
<li><a href="#">Domain Names</a></li>
<li><a href="#">Broadband</a></li>
</ul>
</li>
    </ul>
</body>
</html>

Catatan: untuk mempersingkat penulisan, kode berikutnya harus kamu letakkan di dalam blok style di bagian head (yang ada tulisan "CSS-nya ditulis disini !").

2. Mulai membentuk menu dropdown

Kamu perhatikan bahwa saya menggunakan unordered list (ul) untuk membuat menu karena dengan penggunaan tag ul maka susunan menu akan nampak lebih jelas. Untuk membuat submenu maka saya membuat ul dalam ul yang bisa saja kamu kembangkan dan tambah lagi kedalaman menunya. Perhatikan bahwa tag ul terluar saya beri nama id "menu" sehingga untuk CSS selector bisa menggunakan: ul#menu atau cukup dengan #menu saja.

Sebelumnya saya akan memberitahukan bahwa menu utama nanti akan saya buat berjajar kesamping secara horizontal, untuk membuat menu utama bertumpuk kebawah kamu cukup membuang properti "float: left" pada li. Untuk bentuk list saya buat secara umum saja hiasannya karena nanti terserah kamu ingin diberi hiasan gambar atau apapun sesuai keinginannmu. Kita mulai memberi style pada tag ul utamanya. (*sekali lagi kode berikut letakkan di bagian style!)

#menu {
margin: 0;
padding: 0;
list-style: none;
min-width: 450px;
}

Dimulai pada bagian ul utama: Pemberian margin dan padding dengan nilai 0 akan membuat "efek" list akan hilang karena pada umumnya list item akan menjorok masuk kedalam. Kemudian list-style diberi nilai "none" agar list yang muncul tidak memiliki style apapun (beberapa list-style yang mungkin kamu kenal antara lain circle, square, dan disc). Pemberian nilai min-width: 450px; dikarenakan saya memiliki tiga menu utama yaitu Beranda, Tentang dan Layanan yang masing-masing memiliki lebar 150px (150 pixel). Jika kamu memiliki menu yang lebih banyak kamu bisa menambahkan angka ini. Penggunaan properti min-width akan berguna bila kita ingin suatu elemen memiliki lebar minimal dimana jika isinya lebih panjang maka dia akan memanjang dengan sendirinya. Jika kamu menggunakan properti "width" dan bukan "min-width" maka elemen itu akan tetap segitu biarpun isinya lebih panjang.

#menu li {
position: relative;
width: 150px;
height: 25px;
float: left;
}

Kita lanjutkan ke tag li (list item) yang berlaku pada semua tag li dibawah ul utama. Penggunaan properti "position: relative" agar kita bisa menempatkan elemen ul dibawahnya secara tepat / absolute (kamu akan lihat nanti di kode berikutnya). Saya tentukan lebar dan tinggi dari menu kita adalah 150 pixel dan 25 pixel. Kemudian pemberian properti "float: left" akan membuat tiap list item akan memaksa berjejer ke kiri dan tidak turun kebawah (defaultnya li akan turun kebawah). Ada dua kelompok elemen di HTML yaitu elemen "inline" (elemen ini akan berusaha mengisi ruang disebelahnya dan akan turun kebawah bila tidak ada ruang lagi, contohnya: a, img, span, em) dan elemen "block" (elemen ini akan selalu turun kebawah elemen sebelumnya seperti kalau ditekan tombol "Enter", contohnya: p, div, ul). Perilaku default tiap elemen bisa diubah dengan menggunakan properti "display", misalkan tag a yang inline bisa diubah menjadi block dengan memberi properti "display: block;".

#menu li a {
display: block;
width: 150px;
height: 25px;
border: 1px solid #ccc;
background-color: whitesmoke;
}

Kita akan memberi efek pada tag a yang ada di dalam tag li. Seperti yang saya bilang sebelumnya kita akan mengubah perilaku tag a yang inline menjadi block agar tag a dapat mengisi semua ruang kosong di li. Kemudian kita buat lebar dan tinggi tag a sama dengan tag li containernya dan kita beri border berupa garis tipis 1 pixel dengan warna #ccc menggunakan perintah "border: 1px solid #ccc". Dan baris terakhir pada kode diatas kita memberi warna background whitesmoke pada tag a.

#menu li ul {
margin: 0;
padding: 0;
position: absolute;
top: 26px;
list-style: none;
display: none;
}

Selanjutnya kita memberi style pada elemen ul dalam ul utama, yang hampir sama dengan ul utama dalam hal margin dan padding serta list-style (diset 0 dan list-stylenya none). Perhatikan bahwa saya memberi properti "position: absolute;" sehingga saya dapat meletakkan elemen ini dengan tepat per pixelnya menggunakan perintah "left" dan "top" (kamu juga bisa menggunakan perintah "right" dan "bottom"). Nilai top saya beri angka 26 pixel agar elemen ul tidak menutupi link sebelumnya karena tiap tag a memiliki tinggi 25 pixel (tambah 1 pixel lagi menjadi 26).

Kalau kamu lihat di browser sekarang mungkin kamu akan menyadari bahwa kita tidak melihat submenu lagi disitu dan cuma ada tiga menu utama saja yang nampak. Hal ini dikarenakan kita menggunakan properti "display: none;" sehingga elemen ul tersebut hilang (beda dengan tidak kelihatan). Untuk menyembunyikan elemen kita bisa menggunakan dua macam cara yaitu "display: none" dan "visibility: hidden" dan untuk memunculkan lagi (jangan2 kamu cuma bisa menyembunyikan tapi tidak bisa memunculkannya lagi :D) dengan "display: block" dan "visibility: visible". Lalu apa perbedaan keduanya? Jika kamu menggunakan "display: none" maka elemen tersebut benar-benar hilang dan tidak mengambil ruang apapun di layar sedangkan "visibility: hidden" elemen tersebut cuma tidak kelihatan tapi tetap mengambil ruang disekitarnya. Tahu kan maksud saya?

#menu li:hover ul {
display: block;
}

Ini dia "keajaiban" dari CSS nya yaitu penggunaan pseudo-class :hover pada elemen li. Sebenarnya ada beberapa pseudo-class lain seperti :link, :visited, :active (ketiganya biasanya untuk tag a). Beberapa browser jadul tidak mendukung penggunakan pseudo-class :hover pada elemen selain a tapi saya tidak akan membahasnya karena sebagian besar browser sekarang sudah dapat menjalankan kode ini dengan benar. Technically, menu kita sudah jadi :), coba lintaskan mouse ke menu maka submenunya akan tampil.

3. Sentuhan terakhir

Kamu tambahkan baris berikut ke dalam bagian #menu li a:

text-decoration: none;
text-indent: 7px;
color: #4B4B4B;

Kode diatas akan membuat teks link tidak memiliki "hiasan" garis bawah, membuat teks agak menjorok kedalam sebanyak 7 pixel (biar tidak terlalu mepet ke kiri) dan terakhir kita memberi warna pada teks link yang kita buat. Selanjutnya kita ingin memberi efek mouse melintas pada tag a dengan mengubah warna background yang dimilikinya. Ini kodenya dan kamu bisa letakkan dimana saja.

#menu li a:hover {
background-color: #C7C7C7;
}

#menu li ul li a:hover {
background-color: #727272;
color: #FFF;
}

Ehm, saya kira menunya sudah lumayan jelek :), dan gak enak dilihat.. jadi untuk hiasan atau pengembangan selanjutnya terserah kamu. Mungkin nanti kamu akan menambah banyak properti atau dengan mengubah kode HTML-nya (misalkan dengan menambah nama class tertentu), itu semua terserah kamu dan tidak ada seorang pun yang melarang. Dan jika gagal tidak ada seorangpun yang akan menolong :D. Kode lengkap dari apa yang kita lakukan dari awal sampai akhir adalah seperti ini:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="id">
<head>
<title>Menu Drop-Down</title>
<style type="text/css" media="screen, projection">
#menu {
margin: 0;
padding: 0;
list-style: none;
min-width: 450px;
}
#menu li {
position: relative;
width: 150px;
height: 25px;
float: left;
}
#menu li a {
display: block;
width: 150px;
height: 25px;
border: 1px solid #ccc;
background-color: whitesmoke;
text-decoration: none;
text-indent: 7px;
color: #4B4B4B;
}
#menu li a:hover {
background-color: #C7C7C7;
}
#menu li ul li a:hover {
background-color: #727272;
color: #FFF;
}
#menu li ul {
margin: 0;
padding: 0;
position: absolute;
top: 26px;
list-style: none;
display: none;
}
#menu li:hover ul {
display: block;
}
</style>
</head>
<body>
<ul id="menu">
<li><a href="#">Beranda</a></li>
<li><a href="#">Tentang</a>
<ul>
<li><a href="#">Sejarah</a></li>
<li><a href="#">Tim</a></li>
<li><a href="#">Kantor</a></li>
</ul>
</li>
<li><a href="#">Layanan</a>
<ul>
<li><a href="#">Desain Web</a></li>
<li><a href="#">Internet Marketing</a></li>
<li><a href="#">Hosting</a></li>
<li><a href="#">Domain Names</a></li>
<li><a href="#">Broadband</a></li>
</ul>
</li>
    </ul>
</body>
</html>

4. Kesimpulan

Menjadi web master tidaklah harus dengan menguasai kode Javascript atau kode PHP dengan baik tapi sebenarnya jika mau berusaha maka cukup dengan HTML dan CSS kamu sudah bisa menunjukkan ke-master-anmu dalam bidang web. Jujur tidak lah mudah untuk menguasai CSS karena dibutuhkan banyak sekali pengetahuan dasar yang harus dipelajari dan dilatih. CSS bukanlah bahasa mudah yang bisa dikesampingkan karena justru CSS akan menjadi "muka" dari apa yang kita kerjakan. Serumit dan sebagus apapun kode PHP dan Javascript yang kita buat tapi jika kode CSS-nya hancur dan berakibat halaman web kita juga hancur maka semua akan menjadi percuma dan sia-sia. User awam tidak peduli Javascript, tidak peduli PHP, yang mereka tahu bahwa tampilan web kita bagus, itu saja.

Selamat berlatih dan belajar, karena berlatih dan belajar akan kita lakukan bersama-sama dan akan terus kita lakukan sampai akhir hayat kita. Sampai jumpa :D

.... oh iya, ini screenshot hasil akhir kerja kita:

Jumat, 23 September 2011

Javascript 3 (DOM dan AJAX)

Sudah pernahkah kamu mendengar istilah DOM (Document Object Model) dan AJAX (Asynchronous JavaScript and XML)? Jika belum, kamu bisa membaca terus tulisan ini dan jika sudah kamu juga bisa terus membaca tulisan ini :). Sebaiknya kamu membaca dulu tulisan bagian 1 (Pengetahuan Dasar) dan 2 (Konsep OOP) agar kamu punya sedikit gambaran Javascript yang ada dalam pembahasan kali ini.

        a. DOM (Document Object Model)
       
Ketika browser yang mendukung CSS membaca dokumen HTML yang kamu buat, mereka akan menganalisa strukturnya dan membuat sebuah titik-titik struktur (nodes), yang dapat kamu bayangkan sebagai potongan kecil informasi yang mendeskripsikan dokumenmu. Setiap node berasal dari setiap tag HTML yang kamu tulis dan akan menjadi sebuah object yang saling berhubungan dengan node lain. Sebagai ilustrasi saya berikan kode HTML berikut:

<body>
<p>
   Teks awal
   <img src="gambar.jpg">
   <em>Teks lagi</em>
</p>
</body>

Jika kamu pernah belajar struktur data, terdapat salah satu struktur data yang dikenalkan yaitu TREE. Nah, struktur dari kode HTML diatas mirip dengan tree. Diawali dengan "body" yang memiliki child node "p" dan "p" memiliki tiga child node yaitu "#text" (berisi "Teks awal"), "img" dan child terakhir adalah "em" yang memiliki satu child "#text" berisi teks "Teks lagi". Dari dokumen diatas dapat diambil beberapa pernyataan seperti berikut:

1. parentNode dari "p" adalah "body"
2. firstChild dari "p" adalah "#text" dan lastChild nya adalah "em"
3. "p" berarti juga memiliki array childNodes
4. "img" memiliki previousSibling (saudara) "#text" dan memiliki nextSibling yaitu "em"
5. karena "#text" tidak memiliki node disebelumnya dan tidak memiliki elemen lagi didalamnya maka previousSibling dan firstChild nya memiliki nilai null

Pada umumnya nama node berasal dari nama tag tapi menggunakan huruf kecil (lowercase). Kata-kata parentNode, firstChild, lastChild dan sebagainya akan sering kamu temui dalam DOM. Tapi kamu jangan merasa diintimidasi dulu dengan kata-kata yang mungkin asing dan terkesan ribet bagimu karena nanti kalau sudah terbiasa maka istilah tersebut akan kamu ingat diluar kepala. Jika kamu menggunakan jQuery, akan ada perbedaan istilah yang mungkin akan mempermudah dirimu untuk mengingatnya, misalkan "parentNode" akan diganti dengan kata "parent" saja atau childNodes akan diganti dengan "child".

        b. CARA MENDAPATKAN ELEMEN MENJADI NODE
       
Javascript memiliki beberapa method yang dapat digunakan untuk mendapatkan sebuah object dalam dokumen yang kita buat untuk melakukan analisa struktur dokumen HTML. Untuk mendapatkan object dari node-node tersebut ada tiga method yang umum digunakan dan semuanya ada di class "document" yaitu:

1. document.getElementById
2. document.getElementsByName
3. document.getElementsByTagName

Biasanya saya sering menggunakan method yang pertama dan ketiga saja sedangkan method yang kedua hampir tidak pernah saya gunakan. Method pertama yaitu "getElementById" akan mencari node dengan nama ID yang dijadikan parameter dalam fungsi ini (contoh: <div id="blok">, berarti elemen div dengan id "blok"). Dalam satu dokumen tidak boleh ada node yang memiliki nama id yang sama karena itu method ini menggunakan kata "getElement" dan bukan "getElements". Contoh penggunaannya:

var blok = document.getElementById('blok');
if (blok == null) { alert('node tidak ketemu!'); }

Pada kode diatas, jika elemen dengan id "blok" ditemukan kita dapat melakukan bermacam operasi pada object blok. Sedangkan method getElementByName dan getElementByTagName sesuai dengan namanya kamu pasti sudah tahu kegunaannya. Dua method ini biasanya akan mengembalikan hasil berupa array dari object. Misalkan di dokumen kita ada beberapa tag paragraf (p) tapi kita ingin melakukan operasi pada paragraf yang pertama saja maka kita dapat menggunakan cara seperti berikut:

var paragraf = document.getElementsByTagName('p')[0];
paragraf.className = 'pertama';

Kode diatas memberikan nama class "pertama" pada paragraf pertama dalam dokumen. Karena method getElementsByTagName mereturn array maka kita langsung dapat mengakses elemen pertama dari array tersebut menggunakan tanda "[0]" setelah pemanggilan method getElementsByTagName seperti pada contoh diatas.

    c. DOM ready
   
Jika kamu membuat kode dengan DOM yang dijalankan saat browser meload halaman (otomatis dijalankan saat halaman muncul) maka kamu harus memastikan bahwa semua elemen sudah dirender oleh browser agar tidak menghasilkan nilai NULL. Pada umumnya kita membuat kode Javascript di dalam bagian HEAD yang dieksekusi oleh browser sebelum masuk ke bagian BODY. Jika bagian BODY belum dirender oleh browser maka kodemu di HEAD akan gagal karena node-node nya belum ada. Nah agar kodemu dijalankan setelah browser selesai merender semua elemen kamu bisa menggunakan event "onload" di class "window" seperti contoh berikut:

<html>
<head>
<title>DOM ready</title>
<script type="text/javascript">
window.onload = function(e) {
    var p = document.getElementsByTagName('p');
    alert(p[0].innerHTML);
}
</script>
</head>
<body>
<p>Paragraf pertama</p>
<p>Paragraf kedua</p>
</body>
</html>

Cara atau alternatif lain agar kode DOM kita tidak gagal adalah dengan meletakkan blok kode Javascript di akhir document sebelum tag tutup body karena dijamin semua elemen pasti sudah dirender oleh browser.

    d. Membuat elemen secara dinamis dengan DOM

Sekarang kita buat contoh sederhana pengaplikasian DOM untuk membuat beberapa elemen secara dinamis tanpa mengetikkan secara langsung kode HTMLnya. Saya akan menambahkan tag P (paragraf) dan A (anchor, untuk link) pada elemen body dengan DOM.

<html>
<head>
<title>DOM</title>
<script type="text/javascript">
function buatTagElement(nama) {
    return document.createElement(nama); // membuat element
}
function buatTextElement(teks) {
    return document.createTextNode(teks); // membuat text node
}

window.onload = function(e) {
    var p     = buatTagElement('p'),
        br    = buatTagElement('br'),
        a    = buatTagElement('a'),
        b    = document.getElementsByTagName('body')[0];
    a.href = 'www.posank.com';
    a.appendChild(buatTextElement('posank?'));
    p.style.fontSize = '20px';
    p.appendChild(buatTextElement('kamu'));
    p.appendChild(br);
    p.appendChild(a);
    // hapus elemen sebelumnya
    b.removeChild(document.getElementsByTagName('p')[0]);
    // tambahkan elemen baru
    b.appendChild(p);
}
</script>
</head>
<body>Teks default</body>
</html>

Jika kamu jalankan kode diatas di browser maka akan muncul beberapa elemen yang kita tambahkan secara dinamis seperti pada contoh diatas (kamu posank? :). Untuk dapat melakukan pemrograman menggunakan DOM secara baik diperlukan banyak latihan karena ada banyak kata kunci dan logika yang harus dipelajari dan dilatih. Untuk daftar lengkap method dan property yang digunakan dalam DOM bisa kamu cari di sumber lain atau jika kamu menggunakan browser Google Chrome cukup klik kanan tampilan lalu pilih menu inspect elements atau periksa elemen dan lihat di bagian Elements.

    e. innerHTML
   
innerHTML bukanlah bagian dari DOM tapi property innerHTML sangatlah powerful untuk melakukan beragam operasi pada elemen HTML. Jika pada contoh sebelumnya untuk menghapus atau menambahkan elemen terkesan ribet dan berbelit-belit maka dengan innerHTML kita dapat langsung mengubah isi dari suatu elemen dengan sangat cepat. Perhatikan contoh berikut yang menghasilkan output yang sama dengan kode sebelumnya tapi sekarang kita menggunakan innerHTML.

<html>
<head>
<title>DOM</title>
<script type="text/javascript">
window.onload = function() {
    // string isi yang akan ditambahkan
    var isi = '<p>kamu<br /><a href="www.posank.com">'
            + 'posank?</a></p>';
    // tambahkan isi ke body
    document.getElementsByTagName('body')[0].innerHTML = isi;
    // berikan style ke p
    document.getElementsByTagName('p')[0].style.fontSize = '20px';
}
</script>
</head>
<body>Teks default</body>
</html>

Mudahkan? Nah, bicara soal AJAX, pada umumnya operasi AJAX menggunakan innerHTML ini untuk mengubah sebagian isi dari halaman dengan content dari hasil request yang dilakukan olehnya.

    f. AJAX (Asynchronous JavaScript and XML)
   
Javascript juga dapat melakukan koneksi dibalik layar tanpa kita sadari menggunakan XMLHttpRequest untuk meminta content dari server. Jika kamu menggunakan facebook dan muncul gambar loading lalu tiba-tiba bagian tersebut berubah sendiri maka perubahan tersebut dilakukan dengan AJAX. Karena sifatnya yang Asynchronous itu maka kita tidak perlu merefresh atau mereload keseluruhan halaman tapi Javascript cukup mengubah sebagian elemen menggunakan DOM ataupun innerHTML berdasarkan hasil request yang dilakukannya.

Kamu mungkin tidak perlu tahu kode sesungguhnya untuk melakukan koneksi XMLHttpRequest karena sudah ada banyak class atau framework yang menyediakan interface mudah yang tinggal kamu pakai untuk melakukan koneksi menggunakan AJAX. Tapi jika kamu belum pernah mencoba menggunakan AJAX sama sekali, saya akan berikan source file untuk melakukan koneksi AJAX sederhana menggunakan XMLHttpRequest. Kamu bisa download DISINI. Didalamnya ada tiga file yaitu: "conn.js" sebuah file javascript sebagai penghubung koneksinya, "test.php" sebagai interface contoh koneksinya dan terakhir file "tests.php" sebagai responder bila ada koneksi ajax.

Cara penggunaannya letakkan tiga file tersebut ke webserver atau jika kamu menggunakan mesin lokal dan menggunakan XAMPP letakkan di folder htdocs. Buka browser dan akses file 'test.php' (misal: localhost/test.php). Disitu akan muncul sebuah isian nama yang jika kamu mencoba mengetikkan satu huruf disitu maka akan muncul semacam popup dibawah inputan yang mana isi dari popup ini berasal dari hasil request AJAX ke file 'tests.php'.

Jika saya jelaskan secara detil teknisnya mungkin akan terkesan bertele-tele jadi silakan kamu lihat dan analisa apa dan bagaimana cara melakukan koneksi sederhana menggunakan AJAX. File yang perlu kamu perhatikan adalah file 'test.php' sebagai interfacenya, lalu kamu lihat file 'tests.php' sebagai pemroses dari request yang dikirim oleh file 'test.php' melalui AJAX.

    g. eventListener
   
Pada setiap elemen HTML yang kita buat bisa kita tambahkan event listener yang akan merespon bila ada sebuah event yang terjadi pada element tersebut. Jika kamu pernah menulis atribut "onclick" pada link, maka sebenarnya kamu sudah menambahkan eventlistener pada link tersebut untuk merespon bila terjadi event click. Beberapa event lain antara lain "onchange", "onblur", "onkeypress", "onkeyup", "onload", "onmouseover", dsb. Dengan DOM kita bisa menambahkan eventlistener pada hampir semua elemen dengan menggunakan method addEventListener() pada node yang ada. Method ini mememiliki tiga parameter yaitu:
    1. nama event (tanpa kata "on")
    2. nama fungsi yang dipanggil bila event terjadi
    3. apakah menggunakan capture (true jika iya, false jika menggunakan bubbling)
contohnya adalah seperti: box.addEventListener('click', expand, false) yang berarti kita menambahkan eventlistener pada node box untuk event click yang akan memanggil fungsi expand dan jenis event yang digunakan adalah bubbling. Berikut ini saya buatkan contoh pengaplikasian eventlistener dan DOM untuk membuat animasi sederhana di halaman web.
   
<html>
<head>
<title>Animasi</title>
<script type="text/javascript">
var c = {
    'i'            : null,
    'box'        : null,
    'state'        : 'b',
    'init'        : function() {
        this.box = document.getElementById('box');
        this._setStyle();
        this.box.addEventListener('click', c.ubahUkuran, false);
    },
    '_setStyle'    : function() {
        var bs = this.box.style;
        bs.width = '300px';
        bs.height = '300px';
        bs.margin = '20px auto';
        bs.border = '1px solid #000';
        bs.background = 'orange';
    },
    'ubahUkuran': function() {
        var w = parseInt(c.box.style.width.replace('px', ''));
        var l = c.state == 'b' ? 80 : 300;
        if (w == l) {
            clearInterval(c.i);
            c.i = null;
            c.state = c.state == 'b' ? 's' : 'b';
            c.box.addEventListener('click', c.ubahUkuran, false);
            return;
        } else {
            w = c.state == 'b' ? w - 5 : w + 5;
            c.box.style.width = w + 'px';
            c.box.style.height = w + 'px';
            c.box.removeEventListener('click', c.ubahUkuran, false);
        }
        if (c.i == null)
            c.i = setInterval(c.ubahUkuran, 13);
    }
}
window.onload = function() {
    c.init();
}
</script>
</head>
<body><div id="box"></div>
</body>
</html>

Coba kamu klik kotak yang ada di tengah halaman web dari hasil kode diatas maka kotak berwarna oranye tersebut akan mengecil. Klik sekali lagi maka kotak kembali membesar dan begitu seterusnya.

    h. Membuat teks berkedip dan bergerak dengan DOM dan CSS

Sekarang kita buat sesuatu yang real yang bisa kita rasakan kegunaan dari DOM. Untuk membuat animasi ini kamu harus sedikit paham tentang Cascading Style Sheet (CSS) karena yang kita lakukan hanya mengubah-ubah properti CSS pada elemen yang akan kita animasikan. Kode lengkapnya adalah seperti berikut:

<html>
<head>
<title>Animasi</title>
<style type="text/css">
#wadah { width: 90%; margin: 50px 5%; position: relative; }
#teks {
    font: bold 20px 'lucida grande', sans-serif;
    position: absolute; left: 0px; opacity: 1.0;
}
</style>
<script type="text/javascript">
// object untuk animasi
var anim = {
    intval        : null, // timer untuk animasi
    objek        : null, // objek dari elemen
    state        : ['dim', 'right'], // opacity dan arah gerakan
    speed        : 3, // kecepatan gerakan
    stop        : function() {
        clearInterval(anim.intval);
        anim.intval = null;
        anim.init();
    },
    init        : function() {
        if (this.objek == null)
            this.objek = document.getElementById('teks');
        // kecepatan animasi per 20 milisecond
        this.intval = setInterval(anim.animasi, 20);
    },
    animasi        : function() {
        // untuk berkedip gunakan opacity, IE 6 gak bisa!
        var opac = parseFloat(getComputedStyle(anim.objek, null).opacity);
        opac = anim.state[0] == 'dim' ? opac - 0.1 : opac + 0.1;
        if (opac == 0.1)
            anim.state[0] = 'highlight';
        if (opac == 1)
            anim.state[0] = 'dim';
        anim.objek.style.opacity = opac;
       
        // untuk bergerak gunakan left
        var left = parseInt(getComputedStyle(anim.objek, null).left.replace('px', ''));
        left = anim.state[1] == 'right' ? left + anim.speed : left - anim.speed;
        if (left > 500)
            anim.state[1] = 'left';
        if (left < 0)
            anim.state[1] = 'right';
        anim.objek.style.left = left + 'px';
       
        // refresh counter
        if (anim.intval > 500)
            anim.stop();
    }
};
window.onload = function() {
    anim.init();
}
</script>
</head>
<body>
<div id="wadah">
    <div id="teks">Teks ini terus bergerak dan berkedip</div>
</div>
</body>
</html>

Oh iya, kode diatas tidak akan dapat berjalan di browser Internet Explorer 6 bawaan XP jadi kamu harus gunakan browser lain yang lebih standar dan mendukung DOM seperti Firefox atau Chrome.

    i. DOM di PHP

DOM tidak hanya ada di JavaScript tapi PHP juga memiliki beberapa class untuk beroperasi dengan DOM. Nama method yang digunakan juga hampir sama seperti getElementById, dsb. jadi jika kamu terbiasa dengan DOM menggunakan JavaScript maka dijamin akan dengan mudah menggunakan fitur DOM di PHP. Berikut ini saya beri contoh kode PHP sederhana untuk membuat dokumen HTML dengan DOM (hasilnya akan sama dengan DOM Javascript pada contoh sebelumnya):

<?php
function buatTagElement($o, $e = '') { return $o->createElement($e); }
function buatTextElement($o, $s = '') { return $o->createTextNode($s); }

$html = '<html>
<head>
<title>Cek</title>
</head>
<body></body>
</html>';

$doc = new DOMDocument('1.0');
$doc->loadHTML($html);

$p     = buatTagElement($doc, 'p');
$br    = buatTagElement($doc, 'br');
$a    = buatTagElement($doc, 'a');
$b     = $doc->getElementsByTagName('body')->item(0);
$a->setAttribute('href', 'www.posank.com');
$a->appendChild(buatTextElement($doc, 'posank?'));
$p->setAttribute('style', 'font-size: 20px');
$p->appendChild(buatTextElement($doc, 'kamu'));
$p->appendChild($br);
$p->appendChild($a);
$b->appendChild($p);

echo $doc->saveHTML();
?>

    j. Kesimpulan :)
   
Jika kamu berminat menjadi web designer yang ingin membuat halaman yang dinamis dan menarik maka pengetahuan tentang DOM mutlak kamu kuasai. Dengan DOM kamu bisa memanipulasi semua elemen yang ada pada dokumen, mengubah atributnya, menambah elemen baru atau menghilangkan elemen yang lain serta membuat animasi ringan dengan Javascript dan CSS. Semua animasi yang pernah kamu lihat pada website modern pasti menggunakan DOM (kecuali animasinya pakai Flash). Pertama mungkin terkesan ruwet dan banyak yang harus dipelajari tapi begitu kamu masuk sedikit kedalam DOM maka kamu akan merasa ketagihan dan dibuat terkagum-kagum dengan hasil kerjamu :D.

Pembahasan berikutnya kita akan membahas jQuery, sebuah framework Javascript yang membuat kerjamu dengan DOM akan semudah membalik telapak tangan. Membuat animasi, memanipulasi elemen, semua dilakukan dengan sedikit kode dan logika jika kamu menggunakan jQuery. Sekian dulu pembahasan kali ini dan sampai jumpa!!

Javascript 2 (Konsep OOP di Javascript)

Pembahasan tentang konsep OOP di bagian kedua ini mungkin cenderung teoritis karena membahas fitur dari bahasa pemrograman dan biasanya dilakukan oleh orang sudah benar-benar paham. Tapi saya akan berusaha membahas sebatas kemampuan saya dan apabila ada kesalahan mohon diingatkan. Tulisan ini mencoba mengulas tentang tiga konsep dari OOP yaitu Encapsulation, Inheritance dan Polymorphism yang diterapkan di bahasa pemrograman Javascript serta isu lain yang berhubungan dengan object.

        a. PEMBUATAN OBJECT
       
Sebelum membuat sebuah object maka kita harus mendefinisikan class terlebih dahulu. Tidak seperti bahasa pemrograman lain yang menggunakan kata kunci "class", pembuatan class di Javascript sama seperti saat kita membuat fungsi biasa. Mungkin yang sedikit membedakan adalah adanya kesepakatan bahwa untuk pembuatan class maka nama fungsinya diawali dengan huruf kapital dan biasanya berupa kata benda sedangkan untuk pembuatan fungsi biasa diawali dengan huruf kecil (lowercase) dan berupa kata kerja. Berikut ini contoh definisi class di Javascript:

// ini class
function Kalkulator() {
    // ... disini method dan property
}
var kalk = new Kalkulator;

// ini fungsi biasa
function kalikan(a, b) {
    return a*b;
}

Pada dasarnya semua fungsi di Javascript bisa menjadi class :). Jika suatu fungsi diberi kata "new", maka dia akan menjadi fungsi constructor (fungsi yang otomatis dipanggil pertama kali saat object dibuat) seperti fungsi Kalkulator diatas.

        b. PROPERTY dan METHOD
       
Sebuah class pada umumnya memiliki setidaknya satu property ataupun method. Property adalah variabel yang didefinisikan dalam class tersebut sedangkan method adalah fungsi yang biasanya bekerja dengan property dari class. Untuk mengakses property atau method digunakan operator titik/dot "." setelah nama object/class yang ditentukan. Contohnya adalah "Math.PI" (mengakses property PI di class Math) dan "kalk.kalikan(2,3)" (mengakses method kalikan() di object kalk).

Class "Kalkulator" pada contoh sebelumnya masih belum memiliki property atau method yang didefinisikan. Di Javascript kamu bisa menambahkan property setiap saat secara dinamis pada object buatan class tersebut. Contohnya seperti ini:

function Kalkulator() { }
var kalk = new Kalkulator;
kalk.angka1 = 5;

alert(kalk.angka1); // 5

Masalahnya property "angka1" hanya dimiliki oleh objek "kalk" saja dan tidak dimiliki oleh objek lain seandainya kita membuat object lagi dari class Kalkulator. Kita bisa menggunakan kata kunci "this" di fungsi constructor untuk membuat property yang akan selalu ada pada semua object yang dibuat dari class Kalkulator dengan cara seperti berikut:

function Kalkulator() {
    this.angka1 = 5;
}
var kalk = new Kalkulator; // object baru
var kalk2 = new Kalkulator; // object lain

Kata kunci "this" untuk menggantikan nama object dirinya sendiri atau bisa dikatakan sebagai object saat ini. Sekarang semua object yang dibuat dari class Kalkulator pasti memiliki property "angka1". Tapi class Kalkulator masih kurang lengkap karena dia tidak memiliki method. Untuk menambahkan method sama seperti saat menambahkan property dan disini aku akan menggunakan fungsi anonim (baca bagian 1 - Javascript Pengetahuan Dasar).

function Kalkulator() {
    this.angka1 = 5;
    this.angka2 = 4;
    this.kalikan = function() {
        return this.angka1 * this.angka2;
    };
}
var kalk = new Kalkulator;
alert( kalk.angka1 ); // contoh akses dari luar object
alert( kalk.kalikan() ); // 20

        c. ENCAPSULATION
       
Pada class Kalkulator diatas kita dapat mengakses property angka1 dan angka2 dari luar object sehingga variabel ini terekspos secara umum (kita bisa mengubah nilai di angka1 dan angka2 dengan mudah dari luar object yang mungkin tidak kita inginkan). Salah satu konsep dari OOP adalah Encapsulation dimana kita bisa menyembunyikan property atau method dari akses yang berasal dari luar object sehingga anggota object lebih terlindungi dan objek dapat berjalan seperti yang diharapkan. Setiap property atau method bisa diberi hak akses apakah dia bisa diakses dari luar atau hanya bisa diakses dari dalam object saja. Encapsulation dianalogikan, adalah seperti tidak semua barang yang kita pakai bisa dan boleh dilihat orang kan?

Untuk membuat property atau method yang memiliki hak akses private (hanya bisa diakses dari dalam object saja) maka kita mengganti kata kunci "this" menjadi "var" di dalam fungsi constructornya. Sekarang kita ingin agar variabel "angka1" dan "angka2" memiliki akses private yaitu dengan cara:

function Kalkulator() {
    var angka1 = 5;
    var angka2 = 4;
    this.kalikan = function() {
        return angka1 * angka2;
    };
}
var kalk = new Kalkulator;
alert( kalk.angka1 ); // undefined karena sekarang private
alert( kalk.kalikan() ); // 20

Sekarang kita tidak bisa lagi mengakses property angka1 dan angka2 dari luar object seperti pada contoh diatas (baris kedua dari bawah) jika kita mencoba mengakses property angka1 yang muncul adalah tipe data "undefined" (tidak terdefinisikan). Dapat disimpulkan bahwa dengan menggunakan kata kunci "var" untuk property maka otomatis property tersebut akan memiliki hak akses private dan hanya dapat diakses dari dalam class saja. Sekarang muncul pertanyaan, bagaimana cara mengubah nilai property dengan akses private dari luar object?

        d. GETTER dan SETTER
       
Dalam OOP ada istilah getter dan setter yang berguna untuk mengubah data dari object yang memiliki akses private. Setter adalah method public yang berfungsi untuk mengeset nilai property yang private sedangkan getter berfungsi untuk mereturn nilai dari property yang memiliki akses private. Contohnya getter dan setter adalah seperti berikut:

function Kalkulator() {
    var angka1 = 0;
    var angka2 = 0;
    var hasil = 0;
   
    this.setAngka1 = function(a1) { // setter untuk angka1
        angka1 = a1;
    };
    this.setAngka2 = function(a2) { // setter untuk angka2
        angka2 = a2;
    };
    this.getHasil = function() { // getter untuk "hasil"
        return hasil;
    };
    this.kalikan = function() { // perkalian simpan ke "hasil"
        hasil = angka1 * angka2;
    }
}
var kalk = new Kalkulator;
kalk.kalikan();
alert( kalk.getHasil() ); // 0
kalk.setAngka1(3); // jadikan angka1 = 3
kalk.setAngka2(4); // jadikan angka2 = 4;
kalk.kalikan();
alert( kalk.getHasil() ); // 12;

Kita memiliki dua setter yaitu setAngka1 dan setAngka2 serta satu getter yaitu getHasil untuk mengubah atau mengakses nilai dari property dengan hak akses private. Selain tidak bisa diakses dari luar object, property dengan akses private juga tidak diwariskan pada object turunannya. Apa ini kok ada warisan segala?? Siapa yang meninggal?

        e. PEWARISAN/INHERITANCE
       
Salah satu konsep lain dari OOP adalah inheritance dimana property atau method suatu object bisa diwariskan pada object lain dengan tujuan untuk dikembangkan kemampuannya. Pada class Kalkulator diatas kita cuma mempunyai satu method "kalikan()" saja, nah daripada kita mengubah class tersebut lebih baik kalau property class tersebut kita turunkan pada class lain lalu kita kembangkan lagi class yang baru agar lebih baik. Mungkin kamu berpikir buat apa diturunkan ke class lain segala, diedit classnya aja kan sudah jadi dan lebih cepat? Ehm, iya kalau classnya seperti contoh diatas cuma memiliki beberapa property dan satu method, bagaimana kalau kamu diberi class yang memiliki ratusan property dan puluhan method yang kamu gak ngerti cara kerjanya?

Di Javascript, konsep inheritance diaplikasikan dengan menggunakan object prototype. Katanya prototype ini adalah template dari property yang dishare oleh semua instance dari object. Jadi semua object akan mewarisi nilai dari property dari prototype (semoga kata-kataku masuk akal :D). Kita langsung pada contoh saja:

// class induk/superclass
function Kalkulator() {
    var angka1 = 0; // private tidak diwariskan
    var    angka2 = 0; // ini juga private
    this.setAngka = function() {}; // ini public dan diwariskan
    this.getHasil = function() {}; // ini juga public
}
KalkulatorTambah.prototype = new Kalkulator; // turunkan class
KalkulatorTambah.prototype.constructor = KalkulatorTambah; // ubah constructor
// class anak/subclass
function KalkulatorTambah() {
    var angka1 = 1;
    var angka2 = 1;
    var hasil = 1;
    this.setAngka = function(a1, a2) { // override method induk
        angka1 = a1;
        angka2 = a2;
    };
    this.tambahkan = function() { // menambah method baru
        hasil = angka1 + angka2;
    };
    this.getHasil = function() { // override method induk
        return hasil;
    }
}
KalkulatorKali.prototype = new Kalkulator;
KalkulatorKali.prototype.constructor = KalkulatorKali;
// class anak lagi
function KalkulatorKali() {
    var angka1 = 2;
    var angka2 = 2;
    var hasil = 2;
    this.setAngka = function(a1, a2) {
        angka1 = a1;
        angka2 = a2;
    };
    this.kalikan = function() {
        hasil = angka1 * angka2;
    }
    this.getHasil = function() {
        return hasil;
    }
}

var kalk1 = new KalkulatorTambah;
var kalk2 = new KalkulatorKali;
kalk1.setAngka(2, 4);
kalk2.setAngka(2, 4);
kalk1.tambahkan();
kalk2.kalikan();
alert( kalk1.getHasil() ); // 6
alert( kalk2.getHasil() ); // 8

Yah, lumayan panjang juga untuk menunjukkan konsep inheritance ini :(. Pada contoh diatas kita buat dua anak turunan (subclass) dari class induk (superclass) Kalkulator yaitu KalkulatorTambah dan KalkulatorKali. Tiap turunan menambahkan method baru ataupun melakukan override (mengubah) method induknya. Semoga kamu bisa membayangkan apa yang terjadi pada class-class tersebut :). Dengan menuliskan "KalkulatorKali.prototype = new Kalkulator" itu berarti kita mewariskan semua property dengan akses public dari object "Kalkulator" ke object "KalkulatorKali". Agar constructor "KalkulatorKali" adalah dirinya sendiri (dan bukan induk) maka kita harus menuliskan "KalkulatorKali.prototype.constructor = KalkulatorKali" karena jika tidak maka object turunan akan tetap memanggil constructor induknya.
Jika kita memanggil sebuah property atau method maka Javascript pertamakali kali mencarinya di definisi classnya apakah didefinisikan secara eksplisit. Jika tidak ditemukan Javascript akan mencari ke prototype class tersebut dan jika tetap tidak ketemu akan dicari di class induknya. Begitu seterusnya hingga Javascript menemukan property yang kita panggil tersebut.

        f. POLYMORPHISM
       
Konsep terakhir dari OOP adalah polymorphism. Kamu lihat lagi contoh diatas dimana ada dua object yang memiliki method yang sama (setAngka dan getHasil). Nah, itu yang disebut polymorphism!. Sesederhana itukah? Jawabannya adalah iya.

Sekali lagi saya ingin mengatakan bahwa pembahasan ini cenderung teoritis artinya kamu gak perlu risau jika kodemu tidak seperti ini (punya inheritance, encapsulation, dsb). Tapi alangkah baiknya, karena tujuan OOP itu untuk mempermudah kerja programmer maka seharusnyalah kamu belajar untuk mengaplikasikan semua konsep diatas pada kode yang kamu buat. Jika kamu bekerja sendiri tanpa tim mungkin tidak masalah tapi jika bekerja dengan tim maka penggunaan OOP akan mempercepat kerjamu dan orang lain dalam timmu. Misalkan, kamu langsung saja memberi tahu kalau method yang public ini, ini dan ini, nah orang lain gak perlu baca keseluruhan kodemu atau edit sana edit sini, mereka cukup menggunakan class buatanmu yang sudah ada, atau jika perlu mereka bisa membuat turunan dari class yang kamu buat, selesai.


        g. CARA LAIN PEMBUATAN OBJECT
       
Pada contoh sebelumnya kita harus mendefinisikan dulu class untuk object yang akan kita buat, nah ada cara baru yang akan aku perkenalkan yaitu pembuatan object secara langsung seperti berikut:

var kalk = {
    "hasil" : 0,
    "kalikan" : function(a1, a2) {
        this.hasil = a1 * a2;
    },
    "getHasil": function() {
        return this.hasil;
    }
}
kalk.kalikan(2,3);
alert( kalk.getHasil() );

Tidak seperti contoh sebelumnya dimana kita harus membuat fungsi constructor lebih dahulu, sekarang kita bisa langsung membuat object secara instan. Objek yang kita inginkan sudah jadi, dan siap digunakan tanpa harus menulis fungsi constructor atau kata kunci "new" lagi. Seperti contoh diatas, untuk membuat object digunakan tanda kurung kurawal {} dan semua method atau properti ditulis dengan bentuk: { "namanya": "nilainya" } dan tiap properti dipisahkan dengan tanda koma (*perhatikan bahwa tanda koma tidak boleh ada setelah elemen terakhir). Object bentukan ini bisa langsung di assign ke variabel seperti contoh diatas langsung di assign ke variabel "kalk" ataupun di pass ke suatu fungsi sebagai parameter seperti berikut:

showResult({ "hasil": 0, "angka1": 2, "angka2": 4 });

Contoh diatas adalah contoh melakukan pass sebuah object kedalam fungsi. Yang perlu kamu catat adalah dengan membuat object seperti ini maka semua property atau method yang kamu deklarasikan akan memiliki hak akses public. Sebagian programmer mengawali nama property atau method dengan underscore (_) untuk menandakan bahwa dia tidak seharusnya diakses langsung dan memiliki hak akses private (contohnya: "_init()", "_width", dsb.)

        h. JSON (JavaScript Object Notation)
       
JSON mirip dengan penulisan object menggunakan kurang kurawal {} yang biasanya digunakan untuk pertukaran data (selain menggunakan XML). Karena JSON berupa string maka JSON dapat dipass ke URL atau metode request lain sehingga object yang sudah jadi tersebut siap digunakan tanpa harus diproses lagi oleh client ataupun oleh server. PHP memiliki dua fungsi yang berhubungan dengan JSON yaitu "json_encode" (melakukan encode object/array PHP ke JSON) dan "json_decode" (melakukan decode JSON ke dalam object/array PHP). Contoh penggunaan fungsi json_decode adalah seperti berikut:

<?php
$json = '{"nama": "amir"}';
$obj = json_decode($json);
print $obj->{'nama'}; // amir
?>

JSON bukanlah Javascript tapi subset dari Javascript sehingga spesifikasi JSON sedikit berbeda. Kode dibawah ini valid Javascript tapi tidak untuk JSON:

var data = { 'nama': "amir", umur: 27, "alamat": "indonesia" }

Alasan tidak valid JSON karena pada JSON nama properti dan nilainya harus diapit tanda double quoute (") dan tidak seperti kode diatas properti nama menggunakan single quote dan umur bahkan tidak menggunakan tanda quote sama sekali.

Karena JSON digunakan untuk pertukaran data maka kita tidak bisa mempass method melalui JSON. Nah bagaimana Javascript menghandle JSON? Jika Javascript menerima data dalam bentuk JSON maka sangat mudah mengubahnya menjadi object yaitu dengan menggunakan fungsi "eval()" atau bila tersedia bisa menggunakan method "window.JSON.parse()" untuk mengubah string JSON ke object yang sebenarnya.
       
        i. STATIC METHOD / PROPERTY
       
Secara singkat, static method atau property adalah method/property yang dimiliki oleh class dan bukan object sehingga untuk mengakses static method/property kita tidak perlu menggunakan kata kunci "new". Secara singkat cara pembuatan static method/property pada Javascript sama seperti menggunakan Prototype tapi sekarang kita hilangkan kata prototype seperti berikut:

function Kalkulator() {
    // definisi class
}
Kalkulator.kalikan = function(a1, a2) { // static method
    return a1 * a2;
}
// Tanpa new dan langsung nama class diikuti nama method kalikan
alert( Kalkulator.kalikan(2, 3) );

Static properti atau method biasanya digunakan jika kamu merasa bahwa ada method/property yang tidak tergantung pada property/method lain dari class tersebut sehingga akan lebih efektif bila kamu membuatnya menjadi static.
       
        -----------------
Saya rasa pembahasan tentang konsep OOP di Javascript sudah dicukupkan sampai sini saja dan semoga yang sedikit ini bisa bermanfaat. Terima kasih atas waktu dan perhatiannya dan sampai jumpa. Oh iya, pada bagian ketiga nanti saya akan membahas tentang DOM dan AJAX. See you!