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:
- Elementul stilizat nu mai e un
spanci una(nchor). Astfel putem avea și „pătrățelul” de focus (se poate naviga doar cu tastatura); - Un singur bind pentru ambele elemente;
- 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);
- 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; }
- Am renunțat la
float:leftîn favoarea luidisplay:inline-block. Nu merge pe niște versiuni antice de Firefox, dar consider că e un sacrificiu rezonabil. [1] - Am combinat cele două imagini într-una singură. Un request mai puțin către server
- Cum nu se putea să meargă totul extrem de bine, IE7 face figuri. Prin urmare,
font-sizeșioverflow:visiblesunt cam musai; - 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 <label></label></li> <li> <input type="radio" checked="checked" name="myradio" /> Test fără <label> </li> <li><label> <input type="radio" name="myradio" /> Test cu <label></label></li> <li> <input type="radio" name="myradio" /> Test fără <label> </li> </ul> <h1>Chekbox</h1> <ul> <li><label> <input type="checkbox" name="check[]" /> Test cu <label></label></li> <li> <input checked="checked" type="checkbox" name="check[]" /> Test fără <label></li> <li><label> <input type="checkbox" name="check[]" /> Test cu <label></label></li> <li> <input type="checkbox" name="check[]" /> Test fără <label></li> </ul> </form>
DEMO!
Dacă fanii l-au cerut, îl dăm!


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', ''); }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'); } }); });Cum ramane cu smart-phones. A testat cineva pe telefoane?
@Horia : am testat demo-ul lui Ionut pe Android 2.2 (Galaxy S) si merge perfect.