Memakai HTML5 Editing API


Hampir semua browser modern sudah mendukung atribut contenteditable. Apa fungsinya? Penggunaan contenteditable=true pada sebuah <div> menyebabkan isi dari <div> tersebut dapat di-edit oleh pengguna. Lalu apa bedanya dengan memakai <textarea>? Dengan menggunakan contenteditable, saya dapat men-format isi dari sebuah <div> dengan menggunakan execCommand() untuk membuat huruf tebal, mengubah jenis huruf, warna, menyisipkan gambar, membuat link, dan sebagainya. Function execCommand() adalah bagian dari Editing API. Selain berhubungan dengan format tulisan, Editing API juga menawarkan function yang berhubungan dengan selection seperti getSelection() yang akan mengembalikan sebuah objek Selection.

Sebagai latihan, saya dapat membuat halaman HTML seperti berikut ini:

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'/>
        <title>Event Tester</title>
        <style type="text/css">     
            #editor {
                float: left; border: 3px solid gray;
                padding: 15px; height: 400px;
                width: 400px; background-color: black;                             
                color: #eeee00; white-space: pre-wrap;
            }
            #outputHTML {               
                width: auto; margin-left: 450px;
                border: 3px solid gray; background-color: #eeeeee;
                height: 400px; padding: 15px; font: 15px monospace;
            }
        </style>
    </head>
    <body>
        <div id='editor' contenteditable="true">Silahkan menulis disini!</div>
        <div id='outputHTML'>Silahkan menulis disini!</div>
        <script type="text/javascript">
            var editor = document.getElementById('editor');
            var outputHTML = document.getElementById('outputHTML');
            editor.addEventListener('input', function(e) {                
                outputHTML.textContent = editor.innerHTML;                          
            }, false);
        </script>
    </body>
</html>

Bila saya menampilkan HTML di atas, saya akan memperoleh hasil seperti pada gambar berikut ini:

<div> yang dapat di-edit

<div> yang dapat di-edit

Saya dapat mengubah isi dari <div> yang ada dibagian kiri sama seperti ketika memakai <textarea>.

Untuk menunjukkan penggunaan HTML Editing API, saya perlu memanggil execCommand(). Function ini membutuhkan tiga nilai berupa aCommandName, aShowDefaultUI, dan aValueArgument. Nilai untuk aCommandName adalah sebuah string yang mewakili aksi yang akan dikerjakan pada teks terpilih seperti backColor, bold, copy, createLink, delete dan sebagainya. Beberapa dari aksi tersebut membutuhkan nilai parameter yang diberikan melalui aValueArgument. Pada Firefox, nilai aShowDefaultUI tidak dipakai sehingga saya membiarkannya bernilai false.

HTML yang telah saya ubah akan terlihat seperti pada contoh berikut ini:

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'/>
        <title>Event Tester</title>
        <style type="text/css">     
            #editor {
                float: left; border: 3px solid gray;
                padding: 15px; height: 300px;
                width: 400px; background-color: black;                             
                color: #eeee00; white-space: pre-wrap;
            }
            #editor::-moz-selection {
                color: black;
                background-color: #eeee00;
            }
            #outputHTML {               
                width: auto; margin-left: 450px;
                border: 3px solid gray; background-color: #eeeeee;
                height: 300px; padding: 15px; font: 15px monospace;
            }
            #commandPanel {
                margin: 10px;
            }
        </style>
    </head>
    <body>
        <div id='editor' contenteditable="true">Silahkan menulis disini!</div>
        <div id='outputHTML'>Silahkan menulis disini!</div>
        <div id='commandPanel'>
            Command:            
            <select id='command'>
                <option value="backColor">backColor(color)</option>
                <option value="bold">bold</option>
                <option value="contentReadOnly">contentReadOnly(boolean)</option>
                <option value="copy">copy</option>
                <option value="createLink">createLink(link)</option>
                <option value="cut">cut</option>
                <option value="decreaseFontSize">decreaseFontSize</option>
                <option value="delete">delete</option>
                <option value="fontName">fontName(font)</option>
                <option value="fontSize">fontSize(size)</option>
                <option value="foreColor">foreColor(color)</option>
                <option value="formatBlock">formatBlock(tag)</option>
                <option value="indent">indent</option>
                <option value="inserthorizontalrule">inserthorizontalrule</option>
                <option value="insertimage">insertimage(url)</option>
                <option value="insertorderedlist">insertorderedlist</option>
                <option value="insertparagraph">insertparagraph</option>
                <option value="insertunorderedlist">insertunorderedlist</option>
                <option value="italic">italic</option>
                <option value="justifycenter">justifycenter</option>
                <option value="justifyleft">justifyleft</option>
                <option value="outdent">outdent</option>
                <option value="paste">paste</option>
                <option value="removeformat">removeformat</option>
                <option value="selectall">selectall</option>
                <option value="underline">underline</option>
                <option value="unlink">unlink</option>
            </select>
            Value:
            <input id='txtValue' type='text' size='50'/>
            <input id='btnExecute' type='button' value='executeCommand()'/>
        </div>
        <script type="text/javascript">
            var editor = document.getElementById('editor');
            var outputHTML = document.getElementById('outputHTML');
            var selCommand = document.getElementById('command');
            var txtValue = document.getElementById('txtValue');           

            editor.addEventListener('input', function(e) {                
                outputHTML.textContent = editor.innerHTML;              
            }, false);
            document.getElementById('btnExecute').addEventListener('click', function(e) {               
                var optCommand = selCommand.options[selCommand.selectedIndex];
                var strCommand = optCommand.value;              
                document.execCommand(strCommand, false, txtValue.value);                
            }, false);          
        </script>
    </body>
</html>
Contoh hasil execCommand()

Contoh hasil execCommand()

Pada HTML di atas, saya dapat mencoba bereksperimen dengan command yang terdaftar. Pada kasus nyata, biasanya setiap eksekusi command diwakili oleh sebuah button pada toolbar atau sebuah shortcut. Saya tidak akan membuat sebuah editor lengkap seperti itu karena sudah ada banyak script rich text editor untuk HTML seperti TinyMCE dan CKEditor. Fasilitas inline editing dari CKEditor termasuk salah satu fitur yang memanfaatkan atribut contenteditable dari HTML5 (sesungguhnya fasilitas contenteditable sudah lama didukung browser modern sebelum HTML5, hanya saja kini menjadi lebih terstandarisasi).

Satu permasalahan yang cukup menganggu pada HTML di atas adalah teks yang terpilih di editor akan hilang dan tidak di-ingat bila saya memindahkan kursor ke textbox untuk mengisi nilai. Untuk memanipulasi teks yang sedang dipilih, Editing API menyediakan object Selection. Untuk memperoleh object Selection tersebut, saya dapat memanggil document.getSelection() atau window.getSelection(). Saya juga dapat memodifikasi teks yang terpilih dengan memanggil addRange() atau removeRange() dari Selection.

Sebagai contoh, saya dapat mengubah JavaScript di atas agar mengingat teks yang sebelumnya dipilih dengan mengubahnya menjadi seperti berikut ini:

var editor = document.getElementById('editor');
var outputHTML = document.getElementById('outputHTML');
var selCommand = document.getElementById('command');
var txtValue = document.getElementById('txtValue');           
var range;

editor.addEventListener('input', function(e) {                
    outputHTML.textContent = editor.innerHTML;              
}, false);

editor.addEventListener('mouseup', function(e) {
    // menyimpan teks yang terpilih
    var selection = document.getSelection();
    if (selection.rangeCount > 0) range = selection.getRangeAt(0);
}, false);

document.getElementById('btnExecute').addEventListener('click', function(e) {
    // set pilihan kembali ke seperti terakhir kali (yang tersimpan di range)
    var selection = document.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);

    // kerjakan execCommand()               
    var optCommand = selCommand.options[selCommand.selectedIndex];
    var strCommand = optCommand.value;              
    document.execCommand(strCommand, false, txtValue.value);                
}, false);  

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: