Своё оформление checkbox-элементов форм — проще, чем кажется

11 августа 2010 г.

Оказывается, это не так уж и сложно. И для этого не нужно использовать горы хаков, чтобы обеспечить кросс-браузерность.
Анализ существующих средств показал, что чаще всего используется дополнительный тэг, который «заворачивается» вокруг элемента формы и затем с ним производятся манипуляции.

У меня же задача стояла следующая.
Есть элемент формы, выглядящий следующим образом:

 <div class="form-item>
<label class="option" for="brands-acer">
<input name="brand_filter[brands][acer]" id="brands-acer" value="acer" type="checkbox" /> Acer (6)
</label>
</div>


Необходимо, чтобы он выглядел как-то так (скриншот уже готовой страницы):Оформление checkbox элементов
Готовые решения прикручиваться не хотели, да и качеством не впечатлили, поэтому (да-да) было решено написать своё. В результате получился совсем небольшой плагин для jQuery (что меня удивило) и пара строчек CSS-кода. Работа проверена в IE 6+, FF 3.6.6, Opera 10.5+, Chrome 5.

Код плагина представлен ниже с подробными комментариями:

(function($) {
$.fn.checkboxStyle = function(o) {
o = $.extend({
height: 14  // высота фонового изображения
}, o || {});

return this.each(function() {
var checkbox = $(this); // наш input

// добавляем span вокруг input'а
$(checkbox).wrap('/&amp;gt;');
// если скрыть чекбокс выставив display: none, то при клике на связанный label
// значение checked меняться не будет, поэтому просто убираем его с глаз долой за пределы страницы
// причем значение top здесь не указанно специально - иначе при клике на label страница
// будет скролиться вверх
$(checkbox).css("position", "absolute").css("left", "-999px");

// IE вызывает событие change, только после того как фокус перейдёт на другой элемент
// поэтому здесь вызываем его насильно при клике по label'у
$(checkbox).parents('label').css("cursor", "pointer").bind('click', function() {
$(this).find("input:checkbox").change();
return true;
});

// обработка самого события change: изменение положения фонового изображения
$(checkbox).change(function() {
var checked = $(this).attr("checked");
if (checked) {
$(this).parent('.cb-styled').css("background-position", "0px -"+o.height+"px");
} else {
$(this).parent('.cb-styled').css("background-position", "0px 0px");
}
});

// напоследок вызываем наше событие при загрузке страницы для
// инициализации режимов наших красивых чекбоксов
$(checkbox).change();
});
};
})(jQuery);

В CSS были вынесены только стили, относящиеся к добавляемому span’у:

.cb-styled { float: left; width: 14px; height: 14px; margin: 2px 3px 2px 2px; }
.cb-styled { background: url(../images/checkbox.gif) no-repeat 0px 0px; }

Само изображение чекбокса выполнено спрайтами:
Оформление checkbox элементов
Вызов плагина осуществляется следующим образом:

$("#category-block-form input:checkbox").checkboxStyle();

Если размер чекбокса отличается от моего примера, его можно указать при вызове, например:

$("#category-block-form input:checkbox").checkboxStyle({height: 18});

В данном примере не реализована обработка наведения мыши (mouserover) на чекбокс и нажатия (mousedown). Но, думаю, обработка двух дополнительных событий теперь не составит сложности (я же их не сделал, потому что в дизайне они не были отрисованы).

Что мне нравится в данном подходе: если обратили внимание, здесь не производится манипуляций со свойством checked у input‘ов. Плагин только отражает изменение значения данного свойства. Меньше звеньев в цепи — меньше погрешность (вероятность ошибки).

Теги:
рубрика Сайтостроение