Wednesday, May 30, 2012

CSS Komentar Blogspot · Tema Facebook

CSS Komentar Blogspot - Tema Facebook

Masuk ke halaman Editor HTML Template Anda lalu temukan kode ini:

]]></b:skin>

Salin kode CSS di bawah ini dan letakkan di atasnya:

/*!
 * CSS Komentar Blogspot - Tema Facebook
 * Selengkapnya: https://plus.google.com/108949996304093815163/posts
 */

.comments {
  font:normal normal 11px/14px "Lucida Grande",Tahoma,Verdana,Arial,Sans-Serif !important;
  color:rgb(51,51,51);
}

.comments .comments-content a {color:#3B5998 !important}

.comments h2,
.comments h3,
.comments h4 {
  font-family:inherit !important;
  font-size:16px;
}

.comments .comments-content .comment {
  margin:0;
  padding:10px;
  border-top:1px solid #e9e9e9;
  border-left:1px solid #ccc;
}

.comments .comment .comment-header,
.comments .comment .comment-actions,
.comments .comment .comment-actions a,
.comments .comment .comment-thread.inline-thread,
.comments .comment .continue {
  margin:0;
  padding:0;
  border:none;
  background:none;
}

.comments .comment .comment-header {margin-bottom:4px}
.comments .comment .comment-header .datetime a {color:#808080 !important}
.comments .comment .comment-actions a {padding-right:5px}

.comments .thread-toggle .thread-arrow {
  width:7px;
  height:7px;
  padding-right:4px;
}

.comments .comment .avatar-image-container,
.comments .comment .avatar-image-container img {
  float:none;
  display:block;
  width:50px;
  height:50px;
  max-width:none;
  max-height:none;
  border:none;
  padding:0;
  margin:0;
  outline:none;
}

.comments .comment .comment-block {margin:0 0 0 60px !important}
.comments .comment .comment-thread.inline-thread {margin:7px 0 0 22px}
.comments .comment .comment-thread.inline-thread ol {margin:7px 0 10px !important}

.comments .comment .comment-thread.inline-thread .comment {
  background-color:#EDEFF4;
  padding:5px 5px 0;
  margin:1px 0 0;
  border:none;
  border-bottom:1px solid #D2D9E7;
}

.comments .comment .comment-thread.inline-thread .comment .avatar-image-container,
.comments .comment .comment-thread.inline-thread .comment .avatar-image-container img {
  width:32px;
  height:32px;
}

.comments .comment .comment-thread.inline-thread .comment .comment-block {margin:0 0 0 40px !important}
.comments .comment .comment-content {text-align:left}

.comments .comments-content .icon.blog-author {
  width:16px;
  height:16px;
  display:inline-block;
  vertical-align:top;
  background:transparent url('/favicon.ico') no-repeat 50% 50%;
  -webkit-background-size:100% 100%;
  -moz-background-size:100% 100%;
  background-size:100% 100%;
}

.comments .comment .comment-thread.inline-thread .comment:last-child {border-left:2px solid #A8B2CE !important}

Klik Simpan Template dan lihat hasilnya:

Lihat Demo

Labels: , , ,

jQuery Custom Select Box

Pembaharuan: Posting ini sudah usang. Cek versi plugin-nya di sini

jQuery Custom Select Box

jQuery

// Iterate over each select element
$('select').each(function() {

    // Cache the number of options
    var $this = $(this),
        numberOfOptions = $(this).children('option').length;

    // Hides the select element
    $this.addClass('s-hidden');

    // Wrap the select element in a div
    $this.wrap('<div class="select"></div>');

    // Insert a styled div to sit over the top of the hidden select element
    $this.after('<div class="styledSelect"></div>');

    // Cache the styled div
    var $styledSelect = $this.next('div.styledSelect');

    // Show the first select option in the styled div
    $styledSelect.text($this.children('option').eq(0).text());

    // Insert an unordered list after the styled div and also cache the list
    var $list = $('<ul />', {
        'class': 'options'
    }).insertAfter($styledSelect);

    // Insert a list item into the unordered list for each select option
    for (var i = 0; i < numberOfOptions; i++) {
        $('<li />', {
            text: $this.children('option').eq(i).text(),
            rel: $this.children('option').eq(i).val()
        }).appendTo($list);
    }

    // Cache the list items
    var $listItems = $list.children('li');

    // Show the unordered list when the styled div is clicked (also hides it if the div is clicked again)
    $styledSelect.click(function(e) {
        e.stopPropagation();
        $('div.styledSelect.active').each(function() {
            $(this).removeClass('active').next('ul.options').hide();
        });
        $(this).toggleClass('active').next('ul.options').toggle();
    });

    // Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item
    // Updates the select element to have the value of the equivalent option
    $listItems.click(function(e) {
        e.stopPropagation();
        $styledSelect.text($(this).text()).removeClass('active');
        $this.val($(this).attr('rel'));
        $list.hide();
        /* alert($this.val()); Uncomment this line for demonstration! */
    });

    // Hides the unordered list when clicking outside of it
    $(document).click(function() {
        $styledSelect.removeClass('active');
        $list.hide();
    });

});

CSS

.s-hidden {
  visibility:hidden;
  padding-right:10px;
}

.select {
  cursor:pointer;
  display:inline-block;
  position:relative;
  font:normal 11px/22px Arial,Sans-Serif;
  color:black;
  border:1px solid #ccc;
}

.styledSelect {
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  background-color:white;
  padding:0 10px;
  font-weight:bold;
}

.styledSelect:after {
  content:"";
  width:0;
  height:0;
  border:5px solid transparent;
  border-color:black transparent transparent transparent;
  position:absolute;
  top:9px;
  right:6px;
}

.styledSelect:active,
.styledSelect.active {
  background-color:#eee;
}

.options {
  display:none;
  position:absolute;
  top:100%;
  right:0;
  left:0;
  z-index:999;
  margin:0 0;
  padding:0 0;
  list-style:none;
  border:1px solid #ccc;
  background-color:white;
  -webkit-box-shadow:0 1px 2px rgba(0,0,0,0.2);
  -moz-box-shadow:0 1px 2px rgba(0,0,0,0.2);
  box-shadow:0 1px 2px rgba(0,0,0,0.2);
}

.options li {
  padding:0 6px;
  margin:0 0;
  padding:0 10px;
}

.options li:hover {
  background-color:#39f;
  color:white;
}

Lihat Demo


Via: CSS-Tricks Forum + Sedikit Perbaikan untuk Fungsionalitas

Labels: , ,

Sekilas Tentang `b:else`

<b:else/>

Dalam blogspot kita tahu bahwa kondisi dinyatakan dengan <b:if>. Tapi biasanya kita juga akan menemui <b:else/>. Apa itu? Mereka berdua pada dasarnya masih memiliki tugas yang sama yaitu untuk menciptakan kondisi seperti halnya peraturan if dalam JavaScript. Jika kondisi terpenuhi, lakukan A. Jika tidak, lakukan B. Berikut ini adalah salah satu contoh peraturan if pada JavaScript dengan perintah: Jika A, tulskan A!

if(A) {
   document.write('A');
}

Dalam tag kondisional blogspot, kita bisa menuliskannya seperti ini:

<b:if cond='A'>
    A
</b:if>

<b:else/>

<b:else/> digunakan untuk menyatakan perintah cadangan jika tugas yang diberikan tidak terpenuhi. Sama seperti halnya else dalam JavaScript: Jika A, tuliskan A. Jika bukan A, tuliskan B!

if(A) {
   document.write('A');
} else {
   document.write('B');
}

Dalam tag kondisional blogspot, kita bisa menuliskannya seperti ini:

<b:if cond='A'>
    A
<b:else/>
    B
</b:if>

Satu contoh nyata ada dalam beberapa penerapan tag kondisional halaman. Katakanlah, saat kita sedang berada pada halaman item, kita ingin menampilkan posting. Sedangkan saat kita sedang tidak berada pada halaman item, kita ingin menampilkan sidebar. Pada umumnya, kita akan menuliskan kondisinya seperti ini:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
    <article class='post hentry'> ... </article>
</b:if>
<b:if cond='data:blog.pageType != &quot;item&quot;'>
    <aside class='sidebar'> ... </aside>
</b:if>

Dengan <b:else/> kita bisa meringkasnya menjadi seperti ini:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
    <article class='post hentry'> ... </article>
<b:else/>
    <aside class='sidebar'> ... </aside>
</b:if>

Labels: ,

Sunday, May 27, 2012

Style Switcher Blog dengan Cookies

Style Switcher Blog
Style Switcher Blog

Style Switcher adalah aplikasi/aksesoris kecil yang biasa ada dalam sebuah situs untuk mengizinkan pengunjung mengganti tampilan dari luar sesuka hati. Dengan ini diharapkan pengunjung tidak akan bosan dengan artikel yang dia baca karena dia bisa memutuskan desain situs yang sedang dia kunjungi melalui Style Switcher. Versi asli yang lebih besar sebenarnya cenderung mengambil konsep penggantian file CSS secara keseluruhan:

Style Switcher pada Yahoo! Mail
Style Switcher pada Yahoo! Mail

Di sini Saya hanya akan mengambil beberapa perubahan kecil saja seperti warna latar, warna huruf, jenis huruf dan ukuran huruf. Versi ini agak berbeda dengan yang biasa Anda temui, karena versi ini sudah Saya lengkapi dengan JavaScript Cookies. Kelebihannya adalah, saat pengunjung blog Anda mengubah tampilan template Anda dari luar, meskipun dia sudah berpindah-pindah halaman, perubahan yang dia lakukan akan tetap bertahan:

Lihat Sampel

Untuk membuatnya, pertama-tama masuklah ke halaman editor HTML template Anda:

Mengedit HTML Template
Mengedit HTML Template

Temukan kode ini:

</body>

Salin script di bawah ini dan letakkan di atasnya:

<script src='http://dte-project.googlecode.com/svn/trunk/cookie.js'></script>
<script>
/**
 * Style Switcher with JavaScript Cookie by Taufik Nurrohman
 * URL: https://plus.google.com/108949996304093815163/posts
 */

//<![CDATA[
// =========================================================================
// == Your personal function
// =========================================================================
var expiredStyle = 7000,
    dbs = document.body.style;

// background switcher
function bgSwitch(v) {
    dbs.background = v;
    createCookie('bgstyle', v, expiredStyle);
}

// font switcher
function fontSwitch(v) {
    dbs.fontFamily = v;
    createCookie('fontstyle', v, expiredStyle);
}

// font sizer
function changeFontSize(v) {
    dbs.fontSize = v + 'px';
    createCookie('fontsize', v, expiredStyle);
}

// color switcher
function fontColor(v) {
    dbs.color = v;
    createCookie('fontcolor', v, expiredStyle);
}

// =========================================================================
// == If cookies successfully created and successfully read... do something!
// =========================================================================
if (readCookie('bgstyle')) {
    dbs.background = readCookie('bgstyle');
}
if (readCookie('fontstyle')) {
    dbs.fontFamily = readCookie('fontstyle');
}
if (readCookie('fontsize')) {
    dbs.fontSize = readCookie('fontsize') + 'px';
    document.getElementById('fontSizer').value = readCookie('fontsize');
}
if (readCookie('fontcolor')) {
    dbs.color = readCookie('fontcolor');
    document.getElementById('fontColorer').value = readCookie('fontcolor');
}

// =========================================================================
// == Reset button
// =========================================================================
function resetStyle() {
    eraseCookie('bgstyle');
    eraseCookie('fontstyle');
    eraseCookie('fontsize');
    eraseCookie('fontcolor');
    window.location.reload(1);
}
//]]>
</script>

Klik Simpan Template. Sekarang masuk ke halaman Tata Letak:

Masuk ke Halaman Tata Letak
Masuk ke halaman Tata Letak

Tambahkan sebuah elemen halaman HTML/JavaScript, kemudian salin kode ini dan letakkan di dalam formulirnya:

<style>
#styleSwitcher {
  border:none;
  margin:0 0;
  padding:0 0;
  width:98%;
  text-align:left;
  font:normal 11px Tahoma,Arial,Sans-Serif;
  border-collapse:collapse;
}

#styleSwitcher th,
#styleSwitcher td {
  vertical-align:middle;
  border:none !important;
  padding:2px 10px;
}

#styleSwitcher th.title {
  background-color:#ccc;
  padding:5px 10px;
  margin:0 0 10px;
  text-transform:uppercase;
  font-size:12px;
  font-family:Arial,Sans-Serif;
}

#styleSwitcher select,
#styleSwitcher input[type="text"] {
  width:130px;
  border:2px solid #bbb;
  background-color:#333;
  padding:2px;
  font:bold 11px Tahoma,Verdana,Arial,Sans-Serif;
  color:#999;
  display:block;
  margin:0 0 0;
  height:24px;
}

#styleSwitcher select option {
  color:white;
  padding:5px 10px;
  cursor:pointer;
}

#styleSwitcher button {
  font:normal 11px Tahoma,Arial,Sans-Serif;
  padding:3px 5px;
  cursor:pointer;
}

#styleSwitcher #bgColorer {
  overflow:hidden;
  margin:10px 0 10px;
}

#styleSwitcher #bgColorer span {
  display:block;
  float:left;
  width:20px;
  height:20px;
  border:1px solid black;
  margin:0 5px 0 0;
  cursor:pointer;
}

#styleSwitcher input[type="text"] {
  width:118px !important;
  padding:4px !important;
  height:auto !important;
}
</style>
<table id="styleSwitcher">
    <tr><th class="title" colspan="2">Ganti Tampilan Sesuka Hati</th></tr>
    <tr>
        <td colspan="2">
            <div id="bgColorer">
                <span style="background-color:#523690;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#248bcb;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#fed100;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#c91212;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#3a9838;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#36404a;" onclick="bgSwitch(this.style.backgroundColor);"></span>
                <span style="background-color:#ffffff;" onclick="bgSwitch(this.style.backgroundColor);"></span>
            </div>
        </td>
    </tr>
    <tr><th>Tipe Font</th>
        <td>
            <select onchange="fontSwitch(this.value);">
                <option selected="true">--</option>
                <option value="'Book Antiqua',Serif">Book Antiqua</option>
                <option value="'Times New Roman',Serif">Times New Roman</option>
                <option value="Georgia,Serif">Georgia</option>
                <option value="Arial,Sans-Serif">Arial</option>
                <option value="Tahoma,Verdana,Arial,Sans-Serif">Tahoma</option>
                <option value="'Trebuchet MS',Arial,Sans-Serif">Trebuchet</option>
                <option value="Verdana,Arial,Sans-Serif">Verdana</option>
                <option value="'Century Gothic',Tahoma,Verdana,Arial,Sans-Serif">Century Gothic</option>
                <option value="'Comic Sans MS',Serif">Comic Sans</option>
            </select>
        </td>
    </tr>
    <tr><th>Warna Font</th>
        <td><input type="text" id="fontColorer" value="#000000" onkeyup="fontColor(this.value);"/></td>
    </tr>
    <tr><th>Ukuran Huruf</th>
        <td><input type="text" id="fontSizer" value="12" maxlength="3" onkeyup="changeFontSize(this.value);"/></td>
    </tr>
    <tr><th>Reset?</th>
        <td><button onclick="resetStyle();">Reset Semua Tampilan</button></td>
    </tr>
</table>

Klik Simpan dan lihat hasilnya.

Kode yang Saya beri tanda adalah masa kadaluarsa kuki. Saya membuat masa kadaluarsa selama 7000 hari untuk membuat tampilannya bertahan selama mungkin. Tapi jika Anda ingin menentukan sendiri masa kadaluarsa perubahan tema yang pengunjung Anda lakukan, (misalnya tampilan yang telah berubah akan kembali menjadi seperti semula dalam waktu 3 hari), cukup ganti nilainya dari 7000 menjadi 3 (untuk 3 hari).

Catatan: Aksesoris ini cocok diterapkan pada tema yang sederhana, cenderung berkotak-kotak dan tidak memiliki detail elemen yang rumit. Tidak cocok untuk . Pertanyaan mengenai pengembangan dan penambahan fitur bisa dilanjutkan di bawah, tapi pastikan Anda sudah membaca cara kerja JavaScript Cookies sebelum berdiskusi » (pelajari di sini)

Labels: , , , ,

Saturday, May 26, 2012

Navigasi CSS3 Sohtanaka

Navigasi CSS3 Sohtanaka
Navigasi Sohtanaka, versi CSS3

Eksperimen sederhana untuk menciptakan navigasi dengan efek hover menggulung dari Sohtanaka yang dulu pernah Saya tuliskan di artikel ini. Kali ini Saya hanya akan menggunakan CSS3 Transisi untuk menganimasikan efek menggulung tiap item menu:

HTML

<nav id='rolling-nav'>
    <ul>
        <li><a href='#' data-clone='Home'>Home</a></li>
        <li><a href='#' data-clone='About'>About</a></li>
        <li><a href='#' data-clone='Portfolio'>Portfolio</a></li>
        <li><a href='#' data-clone='Comments'>Comments</a></li>
        <li><a href='#' data-clone='Contact'>Contact</a></li>
    </ul>
</nav>

CSS

#rolling-nav {
  font:normal 12px 'Trebuchet MS',Arial,Sans-Serif;
  color:white;
  text-transform:uppercase;
}

#rolling-nav ul {
  height:50px;
  margin:0px 0px;
  padding:0px 0px;
  overflow:hidden;
}

#rolling-nav li {
  float:left;
  display:inline;
  list-style:none;
  margin:0px 0px;
  padding:0px 0px;
}

#rolling-nav a,
#rolling-nav a:before {
  display:block;
  margin:0px 0px;
  padding:0px 30px;
  line-height:50px;
  color:white;
  text-decoration:none;
  background-color:#900;
  background-image:-webkit-linear-gradient(top, #900 0%, #6A0808 50%, #620303 50%, #6A0808 100%);
  background-image:-moz-linear-gradient(top, #900 0%, #6A0808 50%, #620303 50%, #6A0808 100%);
  background-image:-ms-linear-gradient(top, #900 0%, #6A0808 50%, #620303 50%, #6A0808 100%);
  background-image:-o-linear-gradient(top, #900 0%, #6A0808 50%, #620303 50%, #6A0808 100%);
  background-image:linear-gradient(top, #900 0%, #6A0808 50%, #620303 50%, #6A0808 100%);
  -webkit-box-shadow:inset 0px 1px 0px rgba(255,255,255,0.1);
  -moz-box-shadow:inset 0px 1px 0px rgba(255,255,255,0.1);
  box-shadow:inset 0px 1px 0px rgba(255,255,255,0.1);
  position:relative;
  /* CSS Transisi */
  -webkit-transition:all 0.3s ease-in-out;
  -moz-transition:all 0.3s ease-in-out;
  -ms-transition:all 0.3s ease-in-out;
  -o-transition:all 0.3s ease-in-out;
  transition:all 0.3s ease-in-out;
}

#rolling-nav a:before {
  content:attr(data-clone); /* Memuat data atribut */
  position:absolute;
  top:100%;
  left:0px;
  display:block;
  background-color:white;
  background-image:-webkit-linear-gradient(top, #ddd, white);
  background-image:-moz-linear-gradient(top, #ddd, white);
  background-image:-ms-linear-gradient(top, #ddd, white);
  background-image:-o-linear-gradient(top, #ddd, white);
  background-image:linear-gradient(top, #ddd, white);
  border-top:2px solid rgba(0,0,0,0.2);
  color:#333;
}

#rolling-nav a:hover {
  margin-top:-50px;
  margin-bottom:1px;
}

Lihat Demo

Atribut data-clone digunakan untuk menyimpan nilai kloning yang dituliskan secara manual menggantikan fungsi .clone() dalam jQuery. Efek animasi dibuat dengan cara menganimasikan properti margin dengan CSS transisi.

Labels: ,

Squirrel & Peanut · CSS Pagination

Squirrel & Peanut - CSS pagination

Desain elemen halaman berupa navigasi angka yang terispirasi dari tokoh kartun Flying Squirrel. Bentuk setiap item navigasi menggambarkan bahwa mereka adalah kacang-kacang pohon yang sangat disukai oleh tupai terbang ini. Memang tidak mirip, tapi cukup mewakili:

HTML

<div id="blog-pager">
    <a class="prev" href="#">«</a>
    <a class="num" href="#">1</a>
    <a class="num active" href="#">2</a>
    <a class="num" href="#">3</a>
    <a class="num" href="#">4</a>
    <a class="next" href="#">»</a>
</div>

CSS

#blog-pager {
  text-align:center;
  line-height:36px;
}

#blog-pager a {
  font:bold 16px Georgia,Serif;
  color:#711F05;
  text-decoration:none;
  margin:0px auto 10px;
  background-color:white;
  padding:10px 15px;
  -webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.2);
  -moz-box-shadow:0px 1px 2px rgba(0,0,0,0.2);
  box-shadow:0px 1px 2px rgba(0,0,0,0.2);
  -webkit-border-radius:40% 0% 40% 40%;
  -moz-border-radius:40% 0% 40% 40%;
  border-radius:40% 0% 40% 40%;
  position:relative;
  -webkit-transition:all 0.26s ease-in-out;
  -moz-transition:all 0.26s ease-in-out;
  -ms-transition:all 0.26s ease-in-out;
  -o-transition:all 0.26s ease-in-out;
  transition:all 0.26s ease-in-out;
}

#blog-pager a:before,
#blog-pager a.active:after {
  content:"";
  width:0px;
  height:0px;
  border:10px solid transparent;
  border-color:#B62B00 #B62B00 transparent transparent;
  position:absolute;
  top:0px;
  right:0px;
}

#blog-pager a.active:before,
#blog-pager a.active:after {
  border-width:6px;
  top:4px;
  right:4px;
}

#blog-pager a.active:after {
  top:auto;
  right:auto;
  bottom:4px;
  left:4px;
  border-color:transparent transparent #B62B00 #B62B00;
}

#blog-pager a:hover,
#blog-pager a.active {
  color:white;
  background-color:#711F05;
}

#blog-pager a.active {
  -webkit-border-radius:40% 0% 40% 0%;
  -moz-border-radius:40% 0% 40% 0%;
  border-radius:40% 0% 40% 0%;
}

#blog-pager a:active {
  background-color:#333;
}

Lihat Demo

Labels: , , ,

Friday, May 25, 2012

Konfigurasi JavaScript Cookie

Cookie sebenarnya hanyalah memori peramban yang tercipta untuk menyimpan data kecil berupa teks. Sekedar untuk memberikan indikasi apakah sesuatu harus diingat atau tidak. Memori ini digunakan untuk membuat peramban mengingat sesuatu saat mengunjungi situs yang pernah dia kunjungi. Satu contoh yang paling umum ada pada semua halaman login situs. Dalam halaman login tersebut biasanya terdapat pilihan Ingat saya? atau Remember me? atau Keep me logged in? seperti ini:

Formulir Login Facebook
Formulir Login Facebook

Saat Anda mengecek kotak centang tersebut sebelum melakukan login, maka setelah Anda melakukan login, dan kemudian Anda menutup peramban kemudian membukanya lagi, Anda tidak perlu melakukan login untuk yang ke dua kalinya karena peramban yang sedang Anda gunakan telah menyimpan data login Anda. Begitulah fungsi kuki secara umum (Sebenarnya Saya masih tidak begitu yakin apakah cara kerja ‘ingat Saya?’ pada aplikasi login informasi menggunakan sesuatu sesederhana kuki atau tidak. Mohon dikoreksi).

Saya berikan sebuah demo sederhana terlebih dahulu. Bukan demo formulir login akun (kuki login tidak dibuat begitu saja dengan JavaScript. Itu bisa mengancam keamanan akun), tapi konsep kotak dialog yang hanya akan tampil sekali saja:

Lihat Demo

Dasar Kerja

  1. Dasar kerjanya adalah, saat sebuah halaman terbuka maka kotak dialog akan tampil.
  2. Saat Anda menutup kotak dialog tersebut, di balik itu sebenarnya Anda juga telah menciptakan kuki untuk mengingat sesi penutupan kotak dialog.
  3. Setelah kuki kotak dialog tersimpan, maka saat peramban memuat ulang halaman tersebut dia akan secara otomatis membaca kuki terkait yang telah tersimpan kemudian memutuskan untuk melakukan sesuatu terhadap data yang berhasil dibaca tersebut.

JavaScript Cookie

Berikut ini adalah fungsi JavaScript Cookie yang Saya dapatkan dari QuirksMode:

function createCookie(name, value, days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
    } else {
        var expires = "";
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name, "", -1);
}

Unduh/Pakai URL Ini

Hanya ada tiga fungsi yaitu createCookie(name, value, days), readCookie(name) dan eraseCookie(name).

createCookie(name, value, days)

createCookie digunakan untuk mencipatkan kuki bersamaan saat sebuah perintah dikerjakan (dalam demo kotak dialog, kuki dibuat saat tombol [×] diklik):

$('a.close').click(function() {
    $('#dialog').fadeOut();
    createCookie("hideDialog", "hide", 7000); // Membuat kuki...
});

hideDialog adalah nama kuki, hide adalah nilai kuki dan 7000 adalah masa kadaluarsa. Dalam fungsi di atas, kuki akan kadaluarsa setelah 7000 hari.

Nilai kuki sebenarnya bisa diabaikan dengan menuliskan nilai berupa null, jika yang kita inginkan hanya mengingat sesi yang terjadi. Tapi jika kuki yang akan kita tampilkan/tugaskan lebih spesifik (nama orang misalnya) maka nilai kuki akan bermanfaat. Sebagai contoh, jika peramban Anda telah menyimpan kuki yang diciptakan dari ini:

createCookie("Nama", "Taufik Nurrohman", 30);

Maka Anda bisa menampilkan nilai kuki tersebut dengan menuliskan ini:

if(readCookie("Nama")) {
    alert(readCookie("Nama"));
}

Kode di atas akan menampilkan kotak pesan peringatan bertuliskan Taufik Nurrohman.

readCookie(name)

Anda sudah mengeklik tombol penutup kotak dialog. Kuki hideDialog sudah tersimpan. Tugas selanjutnya hanyalah menciptakan kondisi untuk memerintahkan peramban melakukan sesuatu saat kuki hideDialog terbaca. Ini bisa dilakukan dengan menuliskan fungsi readCookie dalam kondisi:

if(readCookie("hideDialog")) {
    $('#dialog').remove(); // Hilangkan kotak dialog saat kuki 'hideDialog' terbaca
}

Kode di atas Saya rasa cukup jelas. Saat kuki hideDialog terbaca maka kotak dialog akan dihilangkan. Itulah sebabnya kenapa kotak dialog hanya tampil sekali saja.

eraseCookie(name)

eraseCookie tidak memiliki keistimewaan apapun. Ini hanyalah fungsi sederhana untuk menghapus kuki melalui dokumen HTML:

<button onclick='eraseCookie("hideDialog");'>Hapus Kuki</button>

Tombol di atas akan menghapus kuki penutupan kotak dialog saat diklik. Hal ini tidak jauh berbeda seperti halnya saat kita menghapus kuki secara manual melalui histori peramban:

Menghapus kuki melalui histori peramban
Menghapus kuki melalui histori peramban

Kode Lengkap

jQuery

$(function() {

    // Tampilkan kotak dialog saat halaman telah termuat
    $(window).load(function() {
        $('#dialog').animate({top:($(window).height()/2)-20}, 400, "swing");
    });

    // Saat tombol tutup diklik, sembunyikan kotak dialog dengan efek .fedeOut()
    // dan buat kuki dengan nama "hideDialog" dengan waktu kadaluarsa 7000 hari
    $('a.close').click(function() {
        $(this).parent().fadeOut('fast');
        createCookie("hideDialog", "hide", 7000);
        return false;
    });

    // Digunakan saat kuki sudah tercipta
    // Saat kuki "hideDialog" terbaca, singkirkan kotak dialog
    if(readCookie("hideDialog")) {
        $('#dialog').remove();
    }

});

HTML

<div id='dialog'>
    Lorem ipsum dolor sit amet.
    <a class='close' href='#'>&#215;</a>
</div>

CSS

#dialog {
  background-color:#ffa500;
  border:5px solid #222;
  box-shadow:0px 1px 3px black;
  position:absolute;
  top:-100px;
  left:50%;
  z-index:999;
  width:260px;
  height:140px;
  margin:-70px 0px 0px -150px;
  padding:15px;
  color:white;
}

a.close {
  color:white;
  font:bold 16px Arial,Sans-Serif;
  text-decoration:none;
  position:absolute;
  top:10px;
  right:14px;
}

Labels: , ,

Thursday, May 24, 2012

JavaScript Auto Expand Textarea

Versi Dasar

function expandTextarea(id) {
    document.getElementById(id).addEventListener('keyup', function() {
        this.style.overflow = 'hidden';
        this.style.height = 0;
        this.style.height = this.scrollHeight + 'px';
    }, false);
}

Penggunaan

expandTextarea('id-textarea');

Lihat Demo

Dalam Bentuk Plugin jQuery (Dengan Sedikit Perubahan)

/**
 * TextAreaExpander plugin for jQuery
 * v1.0
 * Expands or contracts a textarea height depending on the
 * quatity of content entered by the user in the box.
 *
 * By Craig Buckler, Optimalworks.net
 * With some modification by Taufik
 * As featured on SitePoint.com:
 * http://www.sitepoint.com/blogs/2009/07/29/build-auto-expanding-textarea-1/
 *
 * Please use as you wish at your own risk.
 */

/**
 * Usage:
 *
 * From JavaScript, use:
 *     $(<node>).TextAreaExpander(<minHeight>, <maxHeight>);
 *     where:
 *       <node> is the DOM node selector, e.g. "textarea"
 *       <minHeight> is the minimum textarea height in pixels (optional)
 *       <maxHeight> is the maximum textarea height in pixels (optional)
 *
 * Alternatively, in you HTML:
 *     Assign a class of "expand" to any <textarea> tag.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand"></textarea>
 *
 *     Or assign a class of "expandMIN-MAX" to set the <textarea> minimum and maximum height.
 *     e.g. <textarea name="textarea1" rows="3" cols="40" class="expand50-200"></textarea>
 *     The textarea will use an appropriate height between 50 and 200 pixels.
 */

(function($) {
    // jQuery plugin definition
    $.fn.TextAreaExpander = function(minHeight, maxHeight) {
        var hCheck = !($.browser.msie || $.browser.opera);
        // resize a textarea
        function ResizeTextarea(e) {
            // event or initialize element?
            e = e.target || e;
            // find content length and box width
            var vlen = e.value.length,
                ewidth = e.offsetWidth;
            if (vlen != e.valLength || ewidth != e.boxWidth) {
                if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0px";
                var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));
                e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
                e.style.height = h + "px";
                e.valLength = vlen;
                e.boxWidth = ewidth;
            }
            return true;
        };

        // initialize
        this.each(function() {
            // is a textarea?
            if (this.nodeName.toLowerCase() != "textarea") return;
            // set height restrictions
            var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
            this.expandMin = minHeight || (p ? parseInt('0' + p[1], 10) : 0);
            this.expandMax = maxHeight || (p ? parseInt('0' + p[2], 10) : 99999);
            // initial resize
            ResizeTextarea(this);
            // zero vertical padding and add events
            if (!this.Initialized) {
                this.Initialized = true;
                $(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
            }
        });
        return this;
    };
})(jQuery);

Penggunaan

Dasar

Seleksi sebuah <textarea> kemudian terapkan fungsi .TextAreaExpander(min-height, max-height):

$('textarea').TextAreaExpander(200, 700);

Tinggi Minimal & Maksimal dalam Kelas

Berikan kelas expandMinHeight-MaxHeight pada <textarea>:

<textarea class="expand50-200"></textarea>
$('textarea[class*=expand]').TextAreaExpander();

Lihat Demo


Referensi: Snipplr - Dynamically Expand a Textarea Based On the Amount of Text, TextAreaExpander Demonstration

Labels: ,

Wednesday, May 23, 2012

Efek Thread Comment Bertingkat Hanya dengan CSS

Blogger thread commenting system
Cara sederhana untuk menciptakan efek komentar bertingkat dengan CSS pseudo-class :nth-child(N)

Anda pernah tertarik untuk memasang fitur/sistem thread comment bertingkat dengan hack komentar Blogger dari beberapa blog yang Saya temukan? Jika Anda sekedar tertarik dengan efek bertingkatnya saja, sebenarnya efek itu bisa diciptakan hanya dengan CSS3. Blogger memiliki tingkatan komentar balasan satu tingkat, namun setidaknya mereka memiliki induk komentar yang bisa kita jadikan sebagai batas akhir perhentian efek.

Cukup salin kode ini dan letakkan di atas kode ]]></b:skin> atau </style>:

/*!
 * Efek thread-comment bertingkat hanya dengan CSS
 * Level tingkatan dibuat dengan cara menentukan `margin-left` dengan nilai yang berbeda
 */

.comments .thread-toggle {margin-bottom:10px}
.comments .comment-thread.inline-thread .comment .comment-block {margin-left:52px}

.comments .comment-thread.inline-thread .comment {
  margin:0 0 5px 30%; /* Level 6+ */
  background-color:#222;
  border:1px solid #333;
  padding:10px 15px;
  color:#ccc;
}

.comment .comment-thread.inline-thread .comment:nth-child(6) {margin-left:25%} /* Level 6 */
.comment .comment-thread.inline-thread .comment:nth-child(5) {margin-left:20%} /* Level 5 */
.comment .comment-thread.inline-thread .comment:nth-child(4) {margin-left:15%} /* Level 4 */
.comment .comment-thread.inline-thread .comment:nth-child(3) {margin-left:10%} /* Level 3 */
.comment .comment-thread.inline-thread .comment:nth-child(2) {margin-left:5%}  /* Level 2 */
.comment .comment-thread.inline-thread .comment:nth-child(1) {margin-left:0%}  /* Level 1 */

Klik Simpan Template. Warna latar, huruf dan border bisa dimodifikasi sesuka hati.

Lihat Demo

Labels: , , ,

YouTube Lazy Loader

YouTube

Ide ini sebenarnya Saya ambil dari sebuah artikel - Lazy Load YouTube Videos. Tapi Saya pikir kodenya terlalu panjang. Dan prosedurnya juga terlalu rumit. Berikut ini adalah versi paling sederhana dari jQuery YouTube Lazy Loader:

jQuery

$(function() {
    $('a.youtube-link').each(function() {
        var yt_url   = this.href,
            yt_id    = yt_url.split('?v=')[1],
            yt_title = $(this).text();
        $(this).replaceWith('<div class="youtube-box" style="background-image:url(http://img.youtube.com/vi/' + yt_id + '/0.jpg);"><span class="youtube-title">' + yt_title + '</span><span class="youtube-bar"><span class="yt-bar-left"></span><span class="yt-bar-right"></span></span><span class="youtube-play"></span></div>');
        $('div.youtube-box').click(function() {
            $(this).replaceWith('<iframe class="youtube-frame" src="//www.youtube.com/embed/' + yt_id + '?autoplay=1"></iframe>');
        });
    });
});

CSS

.youtube-box,
.youtube-frame {
  display:block;
  width:420px; /* Lebar video */
  height:315px; /* Tinggi video */
  background-color:black;
  background-size:100%;
  position:relative;
  border:none;
  margin:0px auto 15px;
}

.youtube-box span {
  display:block;
  position:absolute;
  top:0px;
  right:0px;
  bottom:0px;
  left:0px;
}

.youtube-box .youtube-title {
  background-color:rgba(0,0,0,0.4);
  font:bold 15px Verdana,Arial,Sans-Serif;
  color:white;
  text-shadow:0px 1px 2px black;
  bottom:auto;
  line-height:30px;
  height:30px;
  overflow:hidden;
  padding:0px 15px;
}

.youtube-box .youtube-bar {
  background:black url('http://4.bp.blogspot.com/-7keKvgPlMUA/T7vJpi3X_YI/AAAAAAAACtw/4OUd7uHadDk/s1600/yt-bar-center.png') repeat-x top;
  height:35px;
  top:auto;
}

.youtube-box .youtube-bar .yt-bar-left {
  background:transparent url('http://4.bp.blogspot.com/-WL_y2cwe57k/T7xHS3C8tTI/AAAAAAAACug/xIqhenfa-4o/s1600/yt-bar-left.png') no-repeat top left;
  z-index:4;
  cursor:pointer;
}

.youtube-box .youtube-bar .yt-bar-right {
  background:transparent url('http://1.bp.blogspot.com/-DCNevn4jQx0/T7vJt3X3pjI/AAAAAAAACuA/uIKxoT3685M/s1600/yt-bar-right.png') no-repeat top right;
}

.youtube-box .youtube-play {
  cursor:pointer;
  width:83px;
  height:56px;
  top:50%;
  left:50%;
  margin:-28px 0px 0px -42px;
  background:transparent url('http://1.bp.blogspot.com/-JVqaIffy7Ws/T7vK4-ya81I/AAAAAAAACuI/UCL8Y7G4DqE/s1600/yt-play.png') no-repeat top left;
}

.youtube-box .youtube-play:hover {
  background-position:bottom left;
}

HTML

Cukup tulis beberapa tautan dengan format seperti ini maka jQuery akan mengubah mereka semua menjadi video (dalam versi palsu pada saat pertama, dan akan berubah menjadi video asli setelah diklik):

<a class="youtube-link" href="URL-Halaman-YouTube">Judul Video</a>

Lihat Demo

Cara kerjanya sangat sederhana. jQuery akan mencari semua tautan yang memiliki kelas youtube-link. Setelah elemen ditemukan, maka jQuery akan mencari atribut href darinya untuk mengambil ID video:

var yt_url = this.href,
    yt_id = yt_url.split('?v=')[1]; // Mendapatkan ID video dari URL

Kemudian juga mengambil teks dari tautan tersebut sebagai judul video palsu yang akan kita buat nanti:

var yt_title = $(this).text();

Setelah ID dan teks didapatkan, maka dia akan menggunakannya untuk membangun elemen-elemen yang tampak sebagai video dengan latar belakang gambar dan judul yang diambil dari data tadi:

$(this).replaceWith('<div class="youtube-box" style="background-image:url(http://img.youtube.com/vi/' + yt_id + '/0.jpg);"><span class="youtube-title">' + yt_title + '</span><span class="youtube-bar"><span class="yt-bar-left"></span><span class="yt-bar-right"></span></span><span class="youtube-play"></span></div>');

Video tidak akan dipanggil sampai sejauh ini, hingga saat seorang pengunjung (penonton) mengeklik video palsu yang kita buat, maka video palsu tersebut akan berubah menjadi elemen <iframe> yang akan memuat video asli:

$('div.youtube-box').click(function() {
    $(this).replaceWith('<iframe class="youtube-frame" src="//www.youtube.com/embed/' + yt_id + '?autoplay=1"></iframe>');
});

Labels: ,

Tuesday, May 22, 2012

CSS Spoiler

HTML

<input type="checkbox" class="trigger"/> Buka/Tutup Spoiler
<div class="spoiler">
Konten di sini...
</div>

CSS

input.trigger {
  display:inline-block;
  margin:0;
  padding:0;
}

.spoiler {
  background-color:white;
  padding:15px 30px;
  margin:10px 0 0;
  display:none;
}

input.trigger:checked + .spoiler,
input.trigger:checked + br + .spoiler {
  display:block;
}

Lihat Demo

Dengan CSS3 Transisi

input.trigger {
  display:inline-block;
  margin:0;
  padding:0;
}

.spoiler {
  overflow:hidden;
  background-color:white;
  margin:10px 0 0;
  padding:0 30px;
  height:0;
  visibility:hidden;
  -webkit-transition:all 1s ease-in-out;
  -moz-transition:all 1s ease-in-out;
  -ms-transition:all 1s ease-in-out;
  -o-transition:all 1s ease-in-out;
  transition:all 1s ease-in-out;
}

input.trigger:checked + .spoiler,
input.trigger:checked + br + .spoiler {
  padding:15px 30px;
  visibility:visible;
  height:300px;
  overflow:auto;
}

Lihat Demo

Labels: ,

Paket JavaScript Fitur Manipulasi Komentar Blogger

Manipulasi komentar Blogger
Manipulasi komentar Blogger

Rilis paket JavaScript manipulasi komentar Blogger! Setelah beberapa kali menemukan masalah pada kode JavaScript manipulasi komentar yang biasa digunakan (Saya rasa ada banyak dimana-mana dalam berbagai versi), kali ini Saya akan memperkenalkan versi yang lebih aman dan lebih lengkap. Berikut ini adalah beberapa fitur yang ada:

  • Menyisipkan gambar pada komentar Blogger.
  • Menyisipkan video YouTube ke dalam komentar Blogger.
  • Menyisipkan tag <code>
  • Menyisipkan tag <pre>
  • Menyisipkan <blockquote>
  • Mengubah teks emotikon secara otomatis.
  • Dua metode penyisipan kode untuk manipulasi komentar Blogger.
  • Aman. Kode braket kotak yang keliru saat diimplementasikan tidak akan diparse menjadi tag HTML.
  • CSS Fallback. Artinya bahwa jika JavaScript tidak bekerja, beberapa elemen penting masih bisa bekerja sebagaimana saat menggunakan JavaScript (Progressive Enhancement).
  • Pengaturan ukuran dan posisi dilakukan melalui CSS.

Lihat Sampel Manipulasi

Ada beberapa hal yang menjadi perhatian Saya di sini:

Perhatian Pertama: Rusaknya DOM (?)

Rusaknya elemen-elemen HTML karena terkadang JavaScript memanipulasi karakter dengan perintah yang salah yang berasal dari faktor manusia. Hal ini biasanya terjadi ketika penulis melakukan kesalahan saat menerapkan kode. Salah satu contoh umum adalah saat menyisipkan gambar dengan manipulasi braket kotak seperti ini:

[img]gambar-pemandangan.jpg[/img]

Kode di atas adalah kode yang dituliskan secara benar, sehingga kita bisa membuat manipulasi dengan regex untuk mengubahnya menjadi tag <img> seperti ini:

var a = something.innerHTML;
    a = a.replace(/\[img\]/ig, "<img src='");
    a = a.replace(/\[\/img\]/ig, "' alt='' />");
another.innerHTML = a;

Sehingga JavaScript akan mengubah kode di atas menjadi seperti ini:

<img src='gambar-pemandangan.jpg' alt='' />

Tapi terkadang kita juga bisa saja mengalami kesalahan ketik seperti ini:

[img]gambar-pemandangan.jpg[img]

Hal ini sangat berbahaya, karena sekali saja Anda melakukan kesalahan terhadap peraturan JavaScript yang Anda buat sendiri, meskipun hanya satu kode tapi itu bisa merusak dokumen HTML secara global!

<img src='gambar-pemandangan.jpg<img src='

Masalah system of blog pada diskusi hilangnya beberapa item komentar karena JavaScript - Permalink

Oleh karena itu, dibandingkan mengubah setiap karakter unik secara terpisah, akan lebih baik jika Anda menggabungkannya dalam satu kelompok, antara braket pembuka dan braket penutup:

var a = something.innerHTML;
    a = a.replace(/\[img\](.[^\]]*)\[\/img\]/ig, "<img src='$1' alt='' />");
another.innerHTML = a;

Cara di atas jauh lebih aman, karena JavaScript hanya akan memanipulasi karakter [img] yang memiliki penutupnya yaitu [/img]. Jika karakter akhirnya bukan [/img], maka JavaScript akan mengabaikannya. Itu adalah konsep yang Saya pegang di sini.

Penggunaan Tag HTML Asli

Ini penting, dan Saya memang lebih memfokuskan karya ini pada penerapan tag HTML murni, bukan braket kotak atau karakter-karakter paksaan lainnya. Blogger sudah memiliki fasilitas pengecekan validasi tag HTML pada formulir komentar mereka. Singkatnya, tag HTML bisa menjadi sesuatu yang sangat aman karena Blogger secara normal akan memastikan bahwa kode yang Anda tuliskan benar:

var a = something.innerHTML;
    // Mengubah tag <i> menjadi <code>
    a = a.replace(/<i rel="code">(.[^>]*)<\/i>/g, "<code>$1<\/code>");
another.innerHTML = a;

Progressive Enhancement

Saya menggunakan dua tag HTML utama yaitu <i> dan <b> dengan atribut rel yang berbeda-beda. Apa yang Saya lakukan di sini adalah Saya akan memastikan bahwa jika JavaScript tidak bekerja, maka tampilan tag HTML manipulator akan tetap sama dengan tag HTML yang akan menjadi penggantinya. Sebagai contoh, Saya akan menyamakan tampilan tag <pre> dengan <i rel="pre"> sebagai cadangan:

pre,
i[rel="pre"] {
  display:block;
  font:normal normal 12px/normal Monaco,"Courier New",Courier,Monospace;
  word-wrap:normal;
  white-space:pre;
  background-color:black;
  color:white;
  padding:.5em 1em;
  overflow:auto;
}

Dengan begitu Saya bisa memastikan bahwa jika tag <i rel="pre"> berhasil dimanipulasi menjadi tag <pre>, maka tampilan pada peramban akan tampak seperti apa adanya tag <pre>. Namun jika gagal dimanipulasi, tampilan tag <i rel="pre"> akan tetap tampak sebagai sesuatu yang memiliki wujud sama dengan tag <pre> - Selengkapnya bisa dibaca di CSS Fallback untuk Manipulasi Bagian Komentar

Mengatur Tampilan Melalui CSS

Semua pengaturan seperti lebar elemen, posisi dan warna dilakukan melalui CSS.


Cara Memasang Fitur Ini

Pertama-tama masuklah ke halaman editor HTML blog Anda. Klik Edit HTML dan klik Lanjutkan:

Edit HTML Blogger
Mengedit HTML

Temukan kode ini:

</head>

Salin kode CSS ini dan letakkan di atasnya:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<style>
/* Add More Features to the Blogger Comments by Taufik Nurrohman @http://www.dte.web.id */
img.emo {
  display:inline-block;
  vertical-align:middle;
}

#comment-holder .cm-youtube {
  display:block;
  border:none;
  background-color:#333;
  width:370px;
  height:218px;
  margin:0 auto 30px;
}

#comment-holder .cm-image {
  display:block;
  margin:0 auto 15px;
  outline:none;
  border:1px solid #ccc;
  background-color:white;
  -webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);
  -moz-box-shadow:0 1px 3px rgba(0,0,0,.2);
  box-shadow:0 1px 3px rgba(0,0,0,.2);
  padding:5px;
  max-width:96%;
  height:auto;
  width:auto\9;
}

#comment-holder code,
#comment-holder i[rel="code"],
#comment-holder pre,
#comment-holder i[rel="pre"] {
  font:normal normal 12px/normal Monaco,"Courier New",Courier,Monospace;
  color:blue;
}

#comment-holder pre,
#comment-holder i[rel="pre"] {
  display:block;
  background-color:#333;
  color:white;
  padding:.5em 1em;
  word-wrap:normal;
  white-space:pre;
  overflow:auto;
}

#comment-holder blockquote,
#comment-holder b[rel="quote"] {
  margin:0 2%;
  background-color:#eee;
  padding:1em 1.2em;
  border-left:4px solid #7498AD;
  display:block;
  font-weight:bold;
  font-style:italic;
}

#comment-holder i[rel="image"],
#comment-holder i[rel="youtube"] {
  display:block;
  overflow:hidden;
  border:2px solid black;
  position:relative;
  width:170px;
  height:100px;
  margin:0 auto 30px;
}

#comment-holder i[rel="image"]:before,
#comment-holder i[rel="youtube"]:before {
  content:"Please enable your JavaScript to see this image!";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  background-color:red;
  color:white;
  font-weight:bold;
  text-align:center;
  padding:15px 0;
}

#comment-holder i[rel="youtube"]:before {content:"Please enable your JavaScript to watch this video!"}
</style>
</b:if>

Setelah itu temukan kode ini:

</body>

Salin kode ini dan letakkan di atasnya:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<script>
//<![CDATA[
// Add More Features to the Blogger Comments
// Fix some bugs that I got from some similar code out here :)
// Date: 21 May 2012
// Time: 22:50 WIB
// Author: Taufik Nurrohman
// URL: https://plus.google.com/108949996304093815163/about
function repText(id) {
    var a = document.getElementById(id);
    if (!a) return;
    var b = a.innerHTML, c = "//cdn.rawgit.com/tovic/dte-project/0ef9de902cf286a77272f9b3c6f8168c17ab61c6/emoticon/";
    // Images
    b = b.replace(/<i rel="image">(.*?)<\/i>/ig, "<img class='cm-image' src='$1' alt='loading...' \/>");
    b = b.replace(/\[img\](.*?)\[\/img\]/ig, "<img class='cm-image' src='$1' alt='loading...' \/>");
    // YouTube video
    b = b.replace(/<i rel="youtube">https?:\/\/www\.youtube\.com\/embed\/(.*?)<\/i>/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$1'><\/iframe>");
    b = b.replace(/<i rel="youtube">(https?:\/\/youtu\.be\/|https?:\/\/www\.youtube\.com\/watch\?v\=)(.*?)<\/i>/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$2'><\/iframe>");
    b = b.replace(/\[youtube\]https?:\/\/www\.youtube\.com\/embed\/(.*?)\[\/youtube\]/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$1'><\/iframe>");
    b = b.replace(/\[youtube\](https?:\/\/youtu\.be\/|https?:\/\/www\.youtube\.com\/watch\?v\=)(.*?)\[\/youtube\]/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$2'><\/iframe>");
    // Code & text block
    b = b.replace(/<i rel="code">(.*?)<\/i>/ig, "<code>$1<\/code>");
    b = b.replace(/<i rel="pre">(.*?)<\/i>/ig, "<pre>$1<\/pre>");
    b = b.replace(/<b rel="quote">(.*?)<\/b>/ig, "<blockquote>$1<\/blockquote>");
    b = b.replace(/\[code\](.*?)\[\/code\]/ig, "<code>$1<\/code>");
    b = b.replace(/\[pre\](.*?)\[\/pre\]/ig, "<pre>$1<\/pre>");
    b = b.replace(/\[blockquote\](.*?)\[\/blockquote\]/ig, "<blockquote>$1<\/blockquote>");
    // Finishing YouTube and Reduce filesize from images that uploaded by Blogger
    b = b.replace(/&feature=[\w-]*/ig, "");
    b = b.replace(/\/s(640|1600)/g, "/s400");
    // Emoticons
    b = b.replace(/\s:\)+/g, " <img class='emo' alt=':)' src='" + c + "01.gif'\/>");
    b = b.replace(/\s;\)+/g, " <img class='emo' alt=';)' src='" + c + "02.gif'\/>");
    b = b.replace(/\s:\(/g, " <img class='emo' alt=':(' src='" + c + "03.gif'\/>");
    b = b.replace(/\s=\(/g, " <img class='emo' alt='=(' src='" + c + "04.gif'\/>");
    b = b.replace(/\s@@,/g, " <img class='emo' alt='@@,' src='" + c + "05.gif'\/>");
    b = b.replace(/\s:s/ig, " <img class='emo' alt=':s' src='" + c + "07.gif'\/>");
    b = b.replace(/\s:(\\|\/)/g, " <img class='emo' alt=':\\' src='" + c + "08.gif'\/>");
    b = b.replace(/\s:D/g, " <img class='emo' alt=':D' src='" + c + "09.gif'\/>");
    b = b.replace(/\s=D/g, " <img class='emo' alt='=D' src='" + c + "10.gif'\/>");
    b = b.replace(/\s\^:D/g, " <img class='emo' alt='^:D' src='" + c + "11.gif'\/>");
    b = b.replace(/\s\^_?\^/g, " <img class='emo' alt='^_^' src='" + c + "12.gif'\/>");
    b = b.replace(/\s:'\(/g, " <img class='emo' alt=':&#39;(' src='" + c + "13.gif'\/>");
    b = b.replace(/\sT_T/ig, " <img class='emo' alt='T_T' src='" + c + "15.gif'\/>");
    b = b.replace(/\sB\)/g, " <img class='emo' alt='B)' src='" + c + "16.gif'\/>");
    b = b.replace(/\s:Q/ig, " <img class='emo' alt=':Q' src='" + c + "17.gif'\/>");
    b = b.replace(/\s7:\(/g, " <img class='emo' alt='7:(' src='" + c + "19.gif'\/>");
    b = b.replace(/\s:p/ig, " <img class='emo' alt=':p' src='" + c + "20.gif'\/>");
    b = b.replace(/\s:Oz+/ig, " <img class='emo' alt=':Ozzz' src='" + c + "21.gif'\/>");
    b = b.replace(/\s7:O/ig, " <img class='emo' alt='7:O' src='" + c + "22.gif'\/>");
    b = b.replace(/\s\\o\//ig, " <img class='emo' alt='\\o/' src='" + c + "23.gif'\/>");
    b = b.replace(/\s\\m\//ig, " <img class='emo' alt='\\m/' src='" + c + "24.gif'\/>");
    b = b.replace(/\s(<3|:\*)/ig, " <img class='emo' alt=':*' src='" + c + "25.gif'\/>");
    b = b.replace(/\s0:\)+/ig, " <img class='emo' alt='0:)' src='" + c + "26.gif'\/>");
    b = b.replace(/\s\^o\^/ig, " <img class='emo' alt='^o^' src='" + c + "27.gif'\/>");
    b = b.replace(/\s:-a/ig, " <img class='emo' alt=':-a' src='" + c + "28.gif'\/>");
    b = b.replace(/\s\*fck\*/ig, " <img class='emo' alt='*fck*' src='" + c + "29.gif'\/>");
    b = b.replace(/\sxV/ig, " <img class='emo' alt='xV' src='" + c + "30.gif'\/>");
    b = b.replace(/\sx\@/g, " <img class='emo' alt='x@' src='" + c + "31.gif'\/>");
    b = b.replace(/\s\X\@/g, " <img class='emo' alt='X@' src='" + c + "32.gif'\/>");
    b = b.replace(/\s:-d/ig, " <img class='emo' alt=':-d' src='" + c + "33.gif'\/>");
    b = b.replace(/\s:-bd/ig, " <img class='emo' alt=':-bd' src='" + c + "34.gif'\/>");
    b = b.replace(/\s\~x\(+/ig, " <img class='emo' alt='~x(' src='" + c + "35.gif'\/>");
    b = b.replace(/\s:W/g, " <img class='emo' alt=':W' src='" + c + "37.gif'\/>");
    b = b.replace(/\s''J/ig, " <img class='emo' alt='&#39;&#39;J' src='" + c + "47.gif'\/>");
    a.innerHTML = b;
} repText('comment-holder');
//]]>
</script>
</b:if>

Klik Simpan Template.

Pembaharuan: Mengganti pola /<tag>(.[^>]*)<\/tag>/ig dan /\[bracket\](.[^\]]*)\[\/bracket\]/ig menjadi /<tag>(.*?)<\/tag>/ig dan /\[bracket\](.*?)\[\/bracket\]/ig untuk meloloskan tag <br> di dalam tag manipulasi.

Penerapan Kode-Kode Manipulasi

Saya memberikan dua pilihan, yaitu menggunakan tag HTML dengan target manipulasi yang diambil berdasarkan atribut rel dan menggunakan kata-kata kunci yang dimasukkan ke dalam braket kotak sebagai penggambaran tag HTML. Saya merekomendasikan Anda untuk menggunakan tag HTML karena mereka masih bisa bekerja tanpa JavaScript (ini juga merupakan standar manipulasi komponen komentar di blog Saya):

Perintah Format
Memasukkan gambar <i rel="image">URL Gambar</i>
[img]URL Gambar[/img]
Memasukkan video YouTube <i rel="youtube">URL YouTube</i>
[youtube]URL YouTube[/youtube]
Memasukkan tag <code> <i rel="code">Kode Anda</i>
[code]Kode Anda[/code]
Memasukkan tag <pre> <i rel="pre">Kode Anda</i>
[pre]Kode Anda[/pre]
Memasukkan kuota <b rel="quote">Kata-kata Anda</b>
[blockquote]Kata-kata Anda[/blockquote]
Memasukkan emotikon Beberapa kode yang bisa digunakan: :) :( =( :s ^_^ :D =D ^:D @@, ;) :-bd :-d :'( :'( T_T :\ :p B) :Q :Ozz 7:( \o/ \m/ <3 0:) ^o^ :-a 7:O *fck* xV x@ X@ ~x( ''J :W

Labels: , , ,

Monday, May 21, 2012

Klasifikasi Typeface/Jenis Huruf

Berikut ini adalah beberapa keterangan singkat mengenai klasifikasi fon yang Saya temukan dari luar. Beberapa mungkin masih akan Saya edit suatu saat nanti jika Saya telah menemukan referensi yang lebih meyakinkan. Tapi pada intinya beginilah hasil paling meyakinkan untuk saat ini.

Calligraphic

Calligraphic

Huruf yang terkait dengan seni kaligrafi dan fon yang dikembangkan dari produksi mereka dapat diklasifikasikan sebagai kaligrafi. Huruf kaligrafi dapat, walaupun tidak harus, diklasifikasikan sebagai Chancery, Etruscan atau Uncial. Huruf Chancery memiliki huruf sempit sedikit miring dan sangat berpengaruh dalam pengembangan serif italik. Wajah Etruscan tidak memiliki huruf kecil dan didasarkan pada bentuk awal dari kaligrafi Romawi dimana kuas diadakan di sudut curam. Gaya Celtic, huruf Uncial diciptakan dari cara memegang kuas pada sudut hampir horizontal. Hanya ada satu case dalam desain Uncial, meskipun mereka menjadi dasar untuk pengembangan roman lowercase.

Subkelas:

Old English

Old English

Sebuah gaya naskah kaligrafi dibuat dengan broad-nibbed pen menggunakan stroke vertikal, melengkung dan miring. Juga disebut sebagai Fraktur atau Blackletter. Populer dari abad pertengahan melalui Renaissance (dan sampai abad ke-20 terutama di Jerman). Ketika ahli-ahli Taurat menggunakan metode penulisan dan harus angkat pena untuk setiap segmen huruf. Dari sinilah istilah “Fraktur” berasal; itu berasal dari kata latin untuk rusak. Gaya sering dikaitkan dengan beberapa negara tertentu atau wilayah.

Subkelas:

Serif

Serif

Kategori Serif didefinisikan oleh tambahan goresan horizontal pada setiap huruf (sering disebut sebagai feet). Ada berbagai macam fon Serif yang dibagi menjadi tiga subkategori: old style, modern dan transitional. Ada kategori tambahan dari fon SerifSerif Slab— yang kini telah berevolusi dalam kategori tersendiri.

Serif Gaya Lama diidentifikasi oleh bentuk miring, bulat. Setiap goresan huruf memiliki berat yang sama, membuat setiap huruf tampak seragam.

Serif Modern, memiliki kontras goresan huruf tipis dan tebal. Berat huruf jauh lebih berat dari tipografi gaya lama. Goresan lebih tebal secara vertikal daripada horizontal.

Serif Transisi menggabungkan atribut dari gaya lama dan tipografi modern. Setiap huruf berisi goresan horizontal tajam dari setiap huruf tetapi juga memiliki berbagai lebar goresan. Tipografi transisi yang umum digunakan dalam berbagai aplikasi, terutama sebagai jenis huruf standar (Times New Roman) dalam aplikasi perangkat lunak umum seperti Microsoft Word dan Adobe Photoshop.

Subkelas:

Sans Serif

Sans Serif

Adalah jenis huruf tanpa serif. Mereka dapat ditemukan dalam sejarah sejak abad ke-5, meskipun kembalinya kebangkitan klasik Renaissance Italia untuk tipografi gaya lama serif membuat mereka hampir usang sampai abad ke-20. Ada banyak pengembangan mereka huruf Sans-Serif di Jerman sebagai pemberontakan terhadap tulisan hiasan gaya Blackletter populer yang menghasilkan tipografi Sans-Serif berdasarkan pada kemurnian bentuk-bentuk geometris. Sama seperti tipografi Serif, ada klasifikasi yang berbeda untuk Sans-Serif.

Subkelas:

Script

Script

Fon dalam kategori jenis Script mudah diidentifikasi karena mereka dirancang untuk meniru tulisan tangan. Setiap huruf terhubung satu sama lain. Dalam varian Cursive —yang juga biasa diklasifikasikan sebagai Script— huruf memiliki ekor panjang tapi tidak benar-benar menyentuh.

Subkelas:

Novelty

Novelty

Adalah fon dengan tampilan hiasan yang tidak lazim, atau yang menyimulasikan bentuk nontipografikal. Semua yang eksentrik, tipografi tak biasa dikelompokkan ke dalam satu kategori: Novelty. Ada beberapa nama lain untuk jenis tipografi ini: Decorative, Grunge, Artistic, Ornamental. Tetapi mereka semua mengacu pada klasifikasi yang sama. Fon-fon ini diidentifikasi karena kurangnya karakteristik lainnya.

Subkelas:


Referensi

Labels: ,

Blogger JSON · Top Commentators

<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<title>Top Commentators</title>
<style>
.top-commenter-line {
  margin:3px 0px;
}
.top-commenter-avatar {
  display:inline-block;
  vertical-align:middle;
}
</style>
</head>
<body>

<script>
// Top Commentators gadget with avatars, by MS-potilas 2012.
// Gets a list of top commentators from all comments, or specified number of days in the past.
// See http://yabtb.blogspot.com/2012/05/top-commenters-gadget-with-avatars.html

// CONFIG:
var homepage           = 'http://latitudu.blogspot.com',  // Homepage
    maxTopCommenters   = 17,  // How much?
    minComments        = 1,  // How many comments must top commentator have at least
    numDays            = 0,  // From how many days (ex. 30), or 0 from "all the time"
    excludeMe          = true,  // true: exclude my own comments
    excludeUsers       = ["Anonymous", "Another Name"],  // Exclude these usernames
    maxUserNameLength  = 42,  // 0: don't cut, >4: cut usernames
    txtTopLine         = '<b>[#].</b> [image] [user] ([count])',  // List number
    txtNoTopCommenters = 'No top commentators at this time.',
    txtAnonymous       = '',  // Empty, or Anonymous user name localized if you want to localize
    sizeAvatar         = 16,  // Avatar size
    cropAvatar         = true,
    urlNoAvatar        = 'http://lh4.googleusercontent.com/-069mnq7DV_g/TvgRrBI_JaI/AAAAAAAAAic/Iot55vywnYw/s' + sizeAvatar + '/avatar_blue_m_96.png',  // http://www.blogger.com/img/avatar_blue_m_96.png resizeable
    urlAnoAvatar       = 'http://www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&s=' + sizeAvatar,
    urlMyProfile       = '',  // Set if you have no profile gadget on page
    urlMyAvatar        = '';  // Can be empty (then it is fetched) or url to image
// END CONFIG
// for old IEs & IE modes:
if (!Array.indexOf) {
    Array.prototype.indexOf = function(obj) {
        for (var i = 0; i < this.length; i++) if (this[i] == obj) return i;
        return -1;
    };
}

function replaceTopCmtVars(text, item, position) {
    if (!item || !item.author) return text;
    var author = item.author;

    var authorUri = "";
    if (author.uri && author.uri.$t !== "") authorUri = author.uri.$t;

    var avaimg = urlAnoAvatar;
    var bloggerprofile = "//www.blogger.com/profile/";
    if (author.gd$image && author.gd$image.src && authorUri.substr(0, bloggerprofile.length) == bloggerprofile) {
        avaimg = author.gd$image.src;
    } else {
        var parseurl = document.createElement('a');
        if (authorUri !== "") {
            parseurl.href = authorUri;
            avaimg = 'http://www.google.com/s2/favicons?domain=' + parseurl.hostname;
        }
    }
    if (urlMyProfile !== "" && authorUri == urlMyProfile && urlMyAvatar !== "") avaimg = urlMyAvatar;
    if (avaimg == "//img2.blogblog.com/img/b16-rounded.gif" && urlNoAvatar !== "") avaimg = urlNoAvatar;
    var newsize = "s" + sizeAvatar;
    avaimg = avaimg.replace(/\/s\d\d+-c\//, "/" + newsize + "-c/");
    if (cropAvatar) newsize += "-c";
    avaimg = avaimg.replace(/\/s\d\d+(-c){0,1}\//, "/" + newsize + "/");

    var authorName = author.name.$t;
    if (authorName == 'Anonymous' && txtAnonymous !== "" && avaimg == urlAnoAvatar) authorName = txtAnonymous;
    var imgcode = '<img class="top-commenter-avatar" height="' + sizeAvatar + '" width="' + sizeAvatar + '" title="' + authorName + '" src="' + avaimg + '" />';
    if (authorUri !== "") imgcode = '<a href="' + authorUri + '">' + imgcode + '</a>';

    if (maxUserNameLength > 3 && authorName.length > maxUserNameLength) authorName = authorName.substr(0, maxUserNameLength - 3) + "...";
    var authorcode = authorName;
    if (authorUri !== "") authorcode = '<a class="profile-name-link" href="' + authorUri + '">' + authorcode + '</a>';

    text = text.replace('[user]', authorcode);
    text = text.replace('[image]', imgcode);
    text = text.replace('[#]', position);
    text = text.replace('[count]', item.count);
    return text;
}

var topcommenters = {};
var ndxbase = 1;

function showTopCommenters(json) {
    var one_day = 1000 * 60 * 60 * 24;
    var today = new Date();

    if (urlMyProfile === "") {
        var elements = document.getElementsByTagName("*");
        var expr = /(^| )profile-link( |$)/;
        for (var i = 0; i < elements.length; i++) {
            if (expr.test(elements[i].className)) urlMyProfile = elements[i].href;
            break;
        }
    }

    for (var j = 0; j < json.feed.entry.length; j++) {
        var entry = json.feed.entry[j];
        if (numDays > 0) {
            var datePart = entry.published.$t.match(/\d+/g); // Assume ISO 8601
            var cmtDate = new Date(datePart[0], datePart[1] - 1, datePart[2], datePart[3], datePart[4], datePart[5]);

            // Calculate difference btw the two dates, and convert to days
            var days = Math.ceil((today.getTime() - cmtDate.getTime()) / (one_day));
            if (days > numDays) break;
        }
        var authorUri = "";
        if (entry.author[0].uri && entry.author[0].uri.$t !== "") authorUri = entry.author[0].uri.$t;

        if (excludeMe && authorUri !== "" && authorUri == urlMyProfile) continue;
        var authorName = entry.author[0].name.$t;
        if (excludeUsers.indexOf(authorName) != -1) continue;

        var hash = entry.author[0].name.$t + "-" + authorUri;
        if (topcommenters[hash]) topcommenters[hash].count++;
        else {
            var commenter = {};
            commenter.author = entry.author[0];
            commenter.count = 1;
            topcommenters[hash] = commenter;
        }
    }
    if (json.feed.entry.length == 200) {
        ndxbase += 200;
        document.write('<scr' + 'ipt src="' + homepage + '/feeds/comments/default?redirect=false&max-results=200&start-index=' + ndxbase + '&alt=json-in-script&callback=showTopCommenters"></' + 'script>');
        return;
    }

    // Convert object to array of tuples
    var tuplear = [];
    for (var key in topcommenters) tuplear.push([key, topcommenters[key]]);

    tuplear.sort(function(a, b) {
        if (b[1].count - a[1].count) return b[1].count - a[1].count;
        return (a[1].author.name.$t.toLowerCase() < b[1].author.name.$t.toLowerCase()) ? -1 : 1;
    });

    // List top commenters:
    var realcount = 0;
    for (var k = 0; k < maxTopCommenters && k < tuplear.length; k++) {
        var item = tuplear[k][1];
        if (item.count < minComments) break;
        document.write('<di' + 'v class="top-commenter-line">');
        document.write(replaceTopCmtVars(txtTopLine, item, realcount + 1));
        document.write('</d' + 'iv>');
        realcount++;
    }
    if (!realcount) document.write(txtNoTopCommenters);
}
document.write('<scr' + 'ipt src="' + homepage + '/feeds/comments/default?redirect=false&max-results=200&alt=json-in-script&callback=showTopCommenters"></' + 'script>');
</script>

</body>
</html>

Labels: , , , ,

Sunday, May 20, 2012

Cek Apakah Textarea Mengandung Karakter Ganti Baris atau Tidak

Ini adalah masalah yang Saya alami. Mengenai konverter HTML khusus di blog Saya. Sepertinya pengunjung masih belum begitu mengerti bahwa <i rel="code"> dan <i rel="pre"> itu berbeda. Jadi saat mereka mem-paste kode yang seharusnya berada segaris dengan kalimat malah menghasilkan tampilan yang terpotong dengan kalimat:

Contoh Kasus - Kesalahan Konversi
Contoh kasus terbaru: Seharusnya kode <p> yang dituliskan tidak masuk di dalam elemen <pre> melainkan masuk di dalam elemen <code> - Permalink

Dengan beberapa baris kode ini Saya telah berhasil mengatasi masalahnya:

function check() {
    var input = document.getElementById('txt').value;
    if (input.lastIndexOf('\n') != -1) {
        // Mengandung karakter ganti baris
    } else {
        // Tidak mengandung karakter ganti baris
    }
}

Lihat Demo

Intinya adalah, kode ini akan mengecek apakah di dalam textarea mengandung karakter \n (ganti baris) atau tidak. Jika ya, lakukan perintah A. Jika tidak, lakukan perintah B. Dan setelah alat diperbaiki, hasil komentarpun membaik.

HOREEE!!!
HOREEE!!! - Permalink

Kode dimentahkan dari sebuah ide jQuery di sini

Labels: , , , ,