Formulare custom: checkbox & radio v.2

După ce m-a muștruluit bine Ionuț, mi-am făcut puțin timp să revizuiesc scriptul:

$('form input:radio').wrap('<a class="fakeRadio"/>');
$('form input:checkbox').wrap('<a class="fakeCheckbox"/>');
$('form input:checked').parent().addClass('checked');

$('form').delegate('input:radio, input:checkbox', 'change', function(){
	var t=$(this);
	if(this.type==='radio'){t.closest('form').find('input[name="'+this.name+'"]').parent().removeClass('checked');}
	if(this.checked===true) { t.parent().addClass('checked') }else { t.parent().removeClass('checked');}
}).delegate('a.fakeRadio, a.fakeCheckbox', 'focus blur', function(e){
	if(e.type==='focusin'){$(this).addClass('focus')}else {$(this).removeClass('focus')}
});

Ce s-a schimbat?

Păi.. Multe:

  1. Elementul stilizat nu mai e un span ci un a(nchor). Astfel putem avea și „pătrățelul” de focus (se poate naviga doar cu tastatura);
  2. Un singur bind pentru ambele elemente;
  3. Cod mai puțin și un pic mai optimizat (am folosit jQuery unde a fost cu adevărat necesar, folosindu-mă de metode javascript built in);
  4. CSS-ul și HTML-ul (nu mai este necesară folosirea tag-ului label).

CSS-ul

.fakeRadio,
.fakeCheckbox {
	display:inline-block;
	background:url(checkbox.png) no-repeat left top;
	width:16px;
	height:16px;
	cursor:default;
	overflow:hidden;
}
*:first-child+html .fakeRadio,
*:first-child+html .fakeCheckbox {font-size:1em;overflow:visible}

.fakeCheckbox.checked {background-position:right top;}

.fakeRadio {background-position:left bottom;}
.fakeRadio.checked {background-position:right bottom;}

.fakeRadio.focus,
.fakeCheckbox.focus {outline:1px dotted #444;}

.fakeRadio input,
.fakeCheckbox input { opacity: 0; filter:alpha(opacity=0); margin:0;padding:0; }
  1. Am renunțat la float:left în favoarea lui display:inline-block. Nu merge pe niște versiuni antice de Firefox, dar consider că e un sacrificiu rezonabil. [1]
  2. Am combinat cele două imagini într-una singură. Un request mai puțin către server :P
  3. Cum nu se putea să meargă totul extrem de bine, IE7 face figuri. Prin urmare, font-size și overflow:visible sunt cam musai;
  4. Opacity e mai „sexy” decât scoaterea din decor.”

HTML-ul

În principiu, poți avea un radio sau un checkbox oriunde (într-un formular, desigur):

<form action="index_submit" method="get">
	<h1>Radio buttons</h1>
	<ul>
		<li><label> <input type="radio" name="myradio" /> Test cu &lt;label&gt;</label></li>
		<li> <input type="radio" checked="checked" name="myradio" /> Test fără &lt;label&gt; </li>
		<li><label> <input type="radio" name="myradio" /> Test cu &lt;label&gt;</label></li>
		<li> <input type="radio" name="myradio" /> Test fără &lt;label&gt; </li>
	</ul>
	
	<h1>Chekbox</h1>
	<ul>
		<li><label> <input type="checkbox" name="check&#91;&#93;" />  Test cu &lt;label&gt;</label></li>
		<li> <input checked="checked" type="checkbox" name="check&#91;&#93;" />  Test fără &lt;label&gt;</li>
		<li><label> <input type="checkbox" name="check&#91;&#93;" />  Test cu &lt;label&gt;</label></li>
		<li> <input type="checkbox" name="check&#91;&#93;" />  Test fără &lt;label&gt;</li>
	</ul>
</form>

DEMO!

Dacă fanii l-au cerut, îl dăm!

4 Comentarii to “Formulare custom: checkbox & radio v.2”

  1. Ionuț Botizan

    Eh, altă viață! :) Bravo!
    Există totuși două probleme în Chrome & Safari:
    1) input-urile radio nu se modifică când folosești tastatura; focusul se mută, dar bănuiesc că nu este declanșat evenimentul “change” (sau “e.type” nu are valoarea “focusin” în WebKit) și nu se schimbă clasa
    2) când folosești mouse-ul, nu se face focus pe input-ul pe care ai dat click.

    Îmi place că începi să prinzi și tu metodele și proprietățile native din JavaScript. O mică optimizare mai puteai face însă:

    if (e.type === 'focusin') {
        this.className += ' focus';
    } else {
        this.className = this.className.replace(' focus', '');
    }
    
  2. Ionuț Botizan

    Uite, că tot n-aveam ce face:

    jQuery(document).ready(function($){
    	$('form input:radio').wrap('<a class="fakeRadio"/>');
    	$('form input:checkbox').wrap('<a class="fakeCheckbox"/>');
    	$('form input:checked').parent().addClass('checked');
    	$('form').delegate('input:radio, input:checkbox', 'change focus', function(e){
    		var t=$(this);
    		$('a.fakeRadio+.focus, a.fakeCheckbox+.focus').not(t.parent()).removeClass('focus');
    		this.focus();
    		if(this.type==='radio'){
    			t.closest('form').find('input[name="' + this.name + '"]').parent().removeClass('checked');
    		}
    		if (this.checked===true) { 
    			t.parent().addClass('checked focus');
    		} else {
    			t.parent().removeClass('checked');
    		}
    	}).delegate('a.fakeRadio, a.fakeCheckbox', 'focus blur', function(e){
    		if (e.type === 'focusin') {
    			$(this).addClass('focus');
    		} else {
    			$(this).removeClass('focus');
    		}
    	});
    });
    
  3. Pilat Horia-Stefan

    Cum ramane cu smart-phones. A testat cineva pe telefoane?

  4. @Horia : am testat demo-ul lui Ionut pe Android 2.2 (Galaxy S) si merge perfect.

Show trackbacks

Ți-a plăcut articolul? Lasă un comentariu!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter