Zoznam checkboxov alebo radiobuttonov. Chceš, aby sa ti pri zaškrtávaní jednotlivých inputov zvýrazňovali celé položky.
Ako na to? Veľmi jednoducho! Prototype ti ochotne pomôže.
HTML kód
Najprv jednoduchý HTML kód. Odrážkový zoznam. V každej odrážke checkbox s nejakým labelom. Ak je checkbox zaškrtnutý, celá odrážka má byť zvýraznená.
<ul id="zoznamCheckboxov"> <li><label> <input type="checkbox" name="testCheckbox" value="1" /> Prvy checkbox </label></li> <li><label> <input type="checkbox" name="testCheckbox" value="2" checked="checked" /> Druhy checkbox </label></li> <li><label> <input type="checkbox" name="testCheckbox" value="3" /> Treti checkbox </label></li> </ul>
CSS
CSS je v tomto prípade hrozne jednoduché. Jedna trieda highlighted, ktorá prefarbí element dajme tomu na modro.
.highlighted { background: blue; color: white; }
JavaScript
Čo chýba? To najpodstatnejšie. Skript, ktorý:
- nájde všetky inputy s daným názvom,
- bude sledovať či ich niekto nezaškrtáva,
- zaškrtnuté označí, nezaškrtnutým označenie zruší.
var ItemHighlighter = Class.create({
});
Trieda potrebuje vedieť jedinú vec – názov inputu, ktorý má ošetriť. ID je v tomto prípade nepoužiteľné, pretože checkboxy a radiobuttony sú skupinové a ID musí byť unikátne.
Všetko ostatné už sú len možnosti. Môžu sa konfigurovať, ale stačia na nich defaultné hodnoty:
- CSS selektor, podľa ktorého sa bude hľadať položka v ktorej leží input (defaultná hodnota bude li, pretože zoznam checkboxov je v odrážkovom zozname.
- Názov triedy ktorá zvýrazní položku. Tá už je zadefinovaná v CSS. Volá sa highlighted.
var ItemHighlighter = Class.create({
initialize : function ( elementName, options ) {
// defaultné nastavenia
this.options = {
listItemSelector : 'li', // obvykle sú položky v odrážkach
highlightClass : 'highlighted' // trieda zvýrazneného elementu
},
// ak užívateľ zadefinuje vlastné nastavenia, prepíšu sa nimi tie defaultné
Object.extend( this.options, options || { } );
}
});
Čo ďalej? Trieda bude mať dve pomocné metódy:
- markItem – overí či input je zaškrtnutý a podľa toho pridá alebo odoberie zvýrazňovaciu triedu položke v ktorej je umiestnený
- markAll – prejde všetky inputy v skupine a zavolá na nich metódu markItem()
var ItemHighlighter = Class.create({
markAll : function() {
// každý input sa skontroluje zvlášť
this.inputs.each( this.markItem.bindAsEventListener( this ) );
},
markItem : function ( elm ) {
// nájde sa položka v ktorej je umiestnený input
var item = elm.up( this.options.listItemSelector );
// podľa toho či je input zaškrtnutý, položke sa pridá alebo odoberie zvýrazňovacia trieda
if ( elm.checked ) {
item.addClassName( this.options.highlightClass );
} else {
item.removeClassName( this.options.highlightClass );
}
}
});
A teraz sa to celé spojí dohromady. Pri inicializácii sa zistí pomocu CSS selectoru ($$) zoznam všetkých inputov s daným menom. Na všetky sa zavesí onClick event, ktorý bude volať markAll(). A pri inicializácii sa ešte napevno zavolá markAll(), aby sa hneď označili prípadné defaultne zaškrtnuté políčka.
Kompletný JS nakoniec vyvzerá takto:
var ItemHighlighter = Class.create({
initialize : function ( elementName, options ) {
// defaultné nastavenia
this.options = {
listItemSelector : 'li', // obvykle sú položky v odrážkach
highlightClass : 'highlighted' // trieda zvýrazneného elementu
},
// ak užívateľ zadefinuje vlastné nastavenia, prepíšu sa nimi tie defaultné
Object.extend( this.options, options || { } );
// nájdu sa všetky inputy s daným "name"...
this.inputs = $$( 'input[name=' + elementName + ']' );
// ...a zavesí sa na nich onClick event
this.inputs.invoke( 'observe', 'click', this.markAll.bindAsEventListener( this ) );
// pri inicializácii sa nastaví úvodný stav
this.markAll();
},
markAll : function() {
// každý input sa skontroluje zvlášť
this.inputs.each( this.markItem.bindAsEventListener( this ) );
},
markItem : function ( elm ) {
// nájde sa položka v ktorej je umiestnený input
var item = elm.up( this.options.listItemSelector );
// podľa toho či je input zaškrtnutý, položke sa pridá alebo odoberie zvýrazňovacia trieda
if ( elm.checked ) {
item.addClassName( this.options.highlightClass );
} else {
item.removeClassName( this.options.highlightClass );
}
}
});
A samotná inicializácia sa zavolá pri načítaní dokumentu:
Event.observe( document, 'dom:loaded', function () {
new ItemHighlighter( 'testCheckbox' );
} );
Iné než defaultné nastavenia
Ak je treba, môže sa trieda zavolať s inými než defaultnými nastaveniami.
Vlastný názov zvýrazňovacej triedy:
new ItemHighlighter( 'testCheckbox', { highlightClass : 'mojaTrieda' } );
Položky nie sú v odrážkach ale v tabuľke:
new ItemHighlighter( 'tableCheckbox', { listItemSelector : 'tr' } );
Alebo kombinácia:
new ItemHighlighter( 'tableCheckbox', { listItemSelector : 'tr', highlightClass : 'mojaTrieda' } );
Prečo onClick a nie onChange?
Pretože onChange sa zavolá, keď sa zmení hodnota inputu. Čo u checkboxov a radiobuttonov nenastáva. U nich sa iba mení atribút checked.
Prístupnosť nie je ohrozená. Všetky browsery volajú onClick aj keď sa stav checkboxu či radiobuttonu zmení klávesnicou.