Form styler jQuery: стилизуем checkbox, radio и select

Для разработки и интернет магазина потребовалось стилизовать элементы форм HTML такие как input[type="checkbox"], input[type="radio"] и select. По некоторым причинам многие существующие плагины мне не подошли так как потеряли свою актуальность и их код не адекватно работал с новыми версиями jQuery, а также конфликтовал с другими плагинами. Собственно, пришлось написать свою примитивную обертку для стилизации элементов форм.

Пример работы можно посмотреть здесь: https://xshiftx.github.io/forms-styler-jquery/styler/index.html.

Код выложен на github: https://github.com/xShiftx/forms-styler-jquery/blob/master/styler/index.html.

Элементы форм должны быть обернуты в label и соответствовать следующей разметке:

<form>
		<label>
			Опция - 2
			<input type="checkbox" name="" />
		</label>
		<label>
			Опция - 3
			<input type="checkbox" name="" />
		</label>
		<label>
			Опция - 4
			<input type="checkbox" name="" />
		</label>
 
		<ul>
			<li>
				<label>Радио - 1
					<input type="radio" name="" checked="" />
				</label>
			</li>
 
			<li>
				<label>Радио - 2
					<input type="radio" name="" />
				</label>
			</li>
 
			<li>
				<label>Радио - 3
					<input type="radio" name="" />
				</label>
			</li>
 
			<li>
				<label>Радио - 4
					<input type="radio" name="" />
				</label>
			</li>						
		</ul>
 
		<select>
			<option>Вариант - 1</option>
			<option selected>Вариант - 2</option>
			<option>Вариант - 3</option>
			<option>Вариант - 4</option>
		</select>
 
	</form>

Сам код для тех, кому может понадобиться быстрый доступ к исходнику выглядит так:

	$(function() {
		/* checkbox processor */
		function checkUncheck( state, label, check ) {
		    if(state) {
 
		        check.attr('checked', false);
		        label.removeClass('checkbox-checked');
		        label.addClass('checkbox-unchecked');
		    } 
		    else {
		        check.attr('checked', true);
		        label.addClass('checkbox-checked');
		        label.removeClass('checkbox-unchecked');
		    }
		}
        /* FORMS STYLER */
        var checkboxes = $('input[type="checkbox"], input[type="radio"]');
        $.each(checkboxes, function( i, c ) {
 
            var parent = $(c).closest('label');
            if( $(this).attr('type') === "checkbox" ) {
                parent.wrapInner('<div class="checkbox-style checkbox"></div>');
            } 
            else {
                parent.wrapInner('<div class="checkbox-style radiobox"></div>')
            }
            $('.checkbox-style', parent).append('<div class="checkbox-marker"></div>');
            if( $('input[type="checkbox"], input[type="radio"]', parent).attr('checked') === 'checked' ) {
                $(this).parents('.checkbox-style').find('.checkbox-marker').addClass('checkbox-checked');
            }
            //console.log( $('.checkbox-style', parent) );
            $('.checkbox-style', parent).not('.checkbox-style_is-init').addClass('checkbox-style_is-init').click(function(e) {
                e.preventDefault();
                var check = $('input[type="checkbox"], input[type="radio"]', this);
                var label = $('.checkbox-marker', this);
                var state = check.prop('checked');
                if( check.attr('type') === 'radio' ) {
                    var allRadios = $(this).parents('.filter-param, ul').find('input[type="radio"]');
                    var allLabels = $(this).parents('.filter-param, ul').find('.checkbox-marker');
 
                    $.each(allRadios, function(x, v) {
                        $(allRadios[x]).removeAttr('checked');
                        $(allLabels[x]).removeClass('checkbox-checked');
                    });
                }
               checkUncheck( state, label, check);
            });
        });
        /* SELECT STYLER PROCESSOR */
        var selects = $('select');
        $.each(selects, function(a, b) {
            var opts = "";
            $.each($('option', b), function(x, y) {
                var cls = '';
                if( $(y).prop('selected') ) {
                    cls = 'selected';
                }
                opts += '<div data-index="'+ x +'" class="styled-option '+ cls +'">'+ $(y).html() +'</div>';
            });
            $(b).wrap('<label class="styled-select"></label>');
            $(b).closest('label').prepend('<dfn>'+ opts +'</dfn>');
            $.each( $('div', $(b).closest('label') ), function(q,w) {
                if( $(w).attr('class').match('selected') ) {
                    $(w).wrap('<span class="target"></span>');
                    $('.target', $(this).closest('label') ).clone().prependTo( $(w).parents('label'));
                    $(w).unwrap();
                }
            });
        });
        $('.styled-select .target').click(function(e) {
            var list = $(this).parents('label').find('dfn');
            list.css('display', 'block');
            setTimeout(function(){
                list.css('display', 'none');
            }, 3500);
 
        });
        $('.styled-select .styled-option').click(function(){
            var label = $(this).parents('label');
            var tgt  = label.find('.target');
            var slc  = label.find('select');
            $( '.selected' ,label).removeClass('selected');
            tgt.html("");
            $(this).clone().appendTo( tgt );
            $(this).addClass('selected');
            var current = $(this).attr('data-index') - 0;
            $.each( $('option', slc), function(s,d) {
                $(d).attr('selected', false);
                if(current == s) {
                    $(d).attr('selected', true);
                }
            });
        })      
	});
В будущем планируется допилить такие элементы форм как type="file", number, date и так далее.

Добавить комментарий