Pannelli a Tab - Seconda scheda (second)

Realizzare un pannello a tab
Utilizzare delle tab all’interno delle pagine web consente spesso una migliore organizzazione e
ridistribuzione dei contenuti.
In rete è facilissimo trovare script in Javascript che consentono di realizzare dei menu a schede ma
non tutti sanno che è possibile realizzare lo stesso effetto utilizzando semplicemente i fogli di stile.
Vedremo in questa lezione proprio come realizzare un menu a tab utilizzando solo i CSS.
Struttura HTML
Il codice HTML che utilizzeremo è davvero molto semplice. Abbiamo bisogno di una lista puntata
per le varie voci delle schede e di un div per ogni scheda che vogliamo includere. Un semplice
esempio con tre schede ha la seguente struttura:
<pre><ul id="tabs">
<li><a href="#tab1">Tab 1</a></li>
<li><a href="#tab2">Tab 2</a></li>
<li><a href="#tab3">Tab 3</a></li>
</ul>
<div id="container">
<div class="content">
<a name="tab1" id="tab1"></a>
<h2>Tab 1</h2>
<p>Lorem ipsum dolor sit amet consectetuer ...</p>
</div>
<div class="content">
<a name="tab2" id="tab2"></a>
<h2>Tab 2</h2>
<p>Convallis elit tortor ut ante libero Aenean
Maecenas ...</p>
</div>
<div class="content">
<a name="tab3" id="tab3"></a>
<h2>Tab 3</h2>
<p>Urna justo quam nunc urna sem facilisis nibh Curabitur
tellus quis...</p>
</div>
</div></pre>
Come possiamo notare dal codice, all’interno dei vari list-item della lista non ordinata abbiamo
inserito dei link con delle àncore. Queste àncore si trovano all’interno di ogni div con classe
content, ognuna corrispondente ad una voce della lista.
Codice CSS
Ora che abbiamo realizzato la struttura HTML della pagina, possiamo innanzitutto assegnare lo stile
alla lista non ordinata e ai vari div contenitori.
#tabs { font-family: Verdana, sans-serif; font-size: 14px; }
#tabs li {
list-style: none;
float: left;
width: 150px;
height: 35px;
margin: 0 5px;
}
#tabs li a {
background-color: #dedede;
color: #222;
font-weight: bold;
text-decoration: none;
width: 150px;
height: 35px;
display: block;
float: left;
line-height: 35px;
text-align: center;
}
#tabs li a:hover,
#tabs li a:active { background-color: #ededed; }
div.content {
color: #222;
font-family: Verdana;
font-size: 12px;
background-color: #efefef;
padding: 25px;
width: 600px;
height: 350px;
line-height: 22px;
}
#container { clear: both; }
Anche il codice CSS che abbiamo appena visto è semplicissimo. Per lo più ci siamo occupati di
dare dello stile grafico e delle dimensioni fisse agli elementi della lista non ordinata e dei vari div
relativi alle schede.
A questo punto dobbiamo rendere visibile il div#container per la dimensione di uno solo dei
div, in maniera da nascondere gli altri due non in primo piano. Per fare ciò è sufficiente impostare
una larghezza uguale a quella della singola scheda e la proprietà overflow settata su hidden.
L’ultima riga del codice CSS precedente, quindi, diviene:
#container {
clear: both;
height: 400px; /* 350px + 25px (padding sx) + 25px (padding
dx) */
overflow: hidden; }
Tab semplici e accessibili con jQuery
Come molti di voi sanno, jQuery è una libreria Javascript nata per semplificare l’accesso agli
oggetti del DOM dal lato del client e per realizzare delle chiamate Ajax. Tra i suoi punti di forza
annovera la possibilità di estendere le funzioni di base con dei plugin esterni.
L’obiettivo di questo tutorial è di creare un’interfaccia a tab con l’uso di JavaScript, di modelli
CSS e di chiamate Ajax, in maniera semplice, impiegando una sola riga di codice Javascript nelle
pagine HTML e sfruttando le potenzialità di jQuery. Per più complesse necessità segnalo che si può
contare anche su un ottimo plugin come jQuery.tabs.js
Premessa
I menu a “schede”, o a “linguette”, in inglese tab, consentono di “nascondere” parti di testo di una
pagina HTML, consentendo di snellire la quantità di informazioni presentate: in un “box dei
contenuti” (di solito un container creato con la sintassi <div></div>) si vedrà un contenuto
diverso a seconda della linguetta attiva. Inoltre, vi sarà una sola linguetta attiva per volta, linguetta
che avrà un aspetto diverso dalle altre per identificare il suo stato.
Figura 1 – Esempio di pannello con tab
L’interfaccia a tab richiede dunque che, dopo che l’utente ha cliccato su una linguetta, uno script
lato client – collegato all’evento onclick - esegua le seguenti attività:
1. modificare l’aspetto della linguetta attualmente attiva, rendendola come non attiva;
2. modificare l’aspetto della linguetta cliccata, mostrandola come attiva;
3. sostituire nel “box dei contenuti” il contenuto corrente con il contenuto associato alla
linguetta attiva (oppure, a seconda della logica seguita viene nascosto il “box dei contenuti”
attuale e mostrato il box associato alla linguetta attivata).
Normalmente i contenuti delle varie parti sono inseriti all’interno della stessa pagina web in cui è
presente la tab; con jQuery, si possono richiamare contenuti di file esterni in modalità Ajax.
Relativamente alla parte CSS, un articolo che descrive queste tecniche è Un menu a tabs con i CSS
di Alessandro Fulciniti, o il più sofisticato Menu con tab grafiche dello stesso autore. Una raccolta
di interfacce “tab-based” la troviamo nell’articolo 14 Tab-Based Interface Techniques.
Esempi problematici di interfacce a tab
Mentre stavo scrivendo questo tutorial mi sono imbattuto in due diverse realizzazioni di interfacce
a tab:
• Creating a Tabbed Interface with CSS and jQuery di Rob Maurizi (demo)
• Tabmenu for free di Koller Jürgen, che ne fa un uso esteso sul suo sito, in maniera davvero
efficace ed espressiva (demo)
Si tratta di implementazioni apparentemente semplici. Tuttavia, andando ad esaminarle in dettaglio,
ci accorgiamo che queste due interfacce intervengono direttamente sul codice HTML e non possono
essere facilmente estese, se non in maniera problematica. Si tratta cioè di soluzioni intrusive, che
mescolano assieme senza separarli HTML, CSS e Javascript (sulla questione potete approfondire il
concetto con il corso “Unobtrusive Javascript” di Christian Heilmann -tradotto anche in italiano- ed
anche esaminando le tecniche descritte nell'articolo “Il problema di window.onload” di Peter
Michaux).
Vediamo, dapprima, come Koller Jürgen realizza il suo pannello a tab, che tralasciando gli altri
dettagli, è definito da una lista come segue:
<div class=”menu”>
<ul>
<li><a href=”#” onmouseover=”blendon(‘tabcontent1′); blendoff(‘tabcontent2′);
blendoff(‘tabcontent3′);blendoff(‘tabcontent4′); swichtabs(’1′);” onclick=”return false;” title=”"
class=”tabactive” id=”tablink1″>Tab 1 </a></li>
<li><a href=”#” onmouseover=”blendon(‘tabcontent2′); blendoff(‘tabcontent1′);
blendoff(‘tabcontent3′);blendoff(‘tabcontent4′); swichtabs(’2′);” onclick=”return false;” title=”"
id=”tablink2″>Tab 2 </a></li>
<li><a href=”#” onmouseover=”blendon(‘tabcontent3′); blendoff(‘tabcontent1′);
blendoff(‘tabcontent2′); blendoff(‘tabcontent4′); swichtabs(’3′);” onclick=”return false;” title=”"
id=”tablink3″>Tab 3 </a></li>
&<li><a href=”#” onmouseover=”blendon(‘tabcontent4′); blendoff(‘tabcontent1′);
blendoff(‘tabcontent2′);blendoff(‘tabcontent3′); swichtabs(’4′);” onclick=”return false;” title=”"
id=”tablink4″>Tab 4 </a></li>
</ul>
</div>
Le funzioni blendon e blendoff vanno ad attivare o disattivare le linguette, mentre la
funzione swichtabs aggiorna il contenuto del box dei contenuti. Rimando alla demo per i
dettagli. Come si vede, se dobbiamo scrivere 3 tab o 7 tab dobbiamo riscrivere completamente tutto
il codice, e la cosa può diventare pesante.
Invece, lo script di Rob Maurizi, interviene con un codice Javascript che fa uso di jQuery per
attivare la linguetta ed il contenuto:
$(document).ready(function() {
$(“#program_details dd”).hide();
$(“#program_details dt”).click(function() {
var tgt = $(this).attr(“target”);
$(“#program_details dd:visible”).hide();
$ (“#program_details dt.tab_here”).removeClass(“tab_here”);
$(“#”+tgt).show();
$(this).addClass(“tab_here”);
});
});
Anche in questo caso, esaminando la parte HTML, vediamo che si tratta di un’implementazione
ancora meno generalizzabile. Ne riportiamo un frammento:
<div id=”program_detail_tabs”>
<dl id=”program_details”>
<dt target=”pg_overview” id=”tab_overview”>Overview</dt>
<dd style=”display: none;” id=”pg_overview”>This is how you could create …..</dd>
<dt class=”tab_here” target=”pg_works” id=”tab_works”>How it Works</dt>
<dd style=”display: block;” id=”pg_works”>Starting out with a basic …..</dd>
………….
</dl>
</div>
Come si vede dobbiamo dare un id diverso a ciascuna tab, e poi abbiamo molti box dei contenuti
(gli elementi <dd> della lista), ciascuno a sua volta con id differente.
La mia soluzione
Utilizzando appieno le potenzialità di jQuery ho realizzato un’interfaccia a tab molto più generale
(esempio). L’esempio mostra anche una modalità di implementazione di una funzione codeview,
cioè di visualizzazione di codice CSS, JS, HTML richiamabile dall’interfaccia tab-based.
Vediamo subito l’esempio nella sua struttura HTML:
<div id=”tab-menu”>
<ul>
<li><a href=”#Commento”>Commento</a></li>
<li><a href=”tabshort.css”>Mostra tabshort.css</a></li>
<li><a href=”jquery.tabshort.js”>Mostra jquery.tabshort.js</a></li>
<li><a href=”tabshort-demo.html”>Mostra tabshort-demo.html</a></li>
</ul>
<div id=”tab-contenuto”></div>
</div>
<div class=”contenutoNascosto” id=”Commento”>
Questo tab non ha un contenuto Ajax attivo, <br /> gli altri tab aprono un file esterno….<br /> Il
blocco div deve essere esterno al div del tab
</div>
L’interfaccia a tab è contenuta all’interno di <div id="tab-menu"></div>. Volendo
possiamo avere più menu a tab nella stessa pagina: basta usare un id diverso. All'interno del
container <div id="tab-menu"></div> troviamo una lista, più il box dei contenuti <div
id="tab-contenuto">.
Nella lista <ul> avremo tanti elementi <li> ciascuno contenente un link. Il testo è quello che sarà
mostrato sulla linguetta, l'url invece può essere:
• # o vuoto, ed in questo caso viene mostrato solo un messaggio di errore nel box dei contenuti
• #miaetichetta, ed in questo caso nel box dei contenuti sarà richiamato un contenuto interno
alla stessa pagina associato ad una div avente l'id miaetichetta
• url, ed in questo caso nel box dei contenuti sarà richiamato un contenuto esterno tramite una
chiamata Ajax; ricordo che jquery – per motivi di sicurezza – consente di richiamare via
Ajax solo pagine esterne contenute nello stesso dominio e nella stessa cartella della pagina
che effettua la chiamata; nell'esempio realizzato il codice javascript riconosce l'estensione
del file esterno e attiva dei comportamenti diversi secondo che si tratti di estensioni .css, .txt,
.js, htm, html, asp, php, consentendo di realizzare una comoda funzionalità codeview.
All’esterno di <div id="tab-menu"> avremo tanti div come <div
class="contenutoNascosto" id="Commento">. Si tratta di contenuti che normalmente
sono nascosti, fino a quando cliccheremo sulla linguetta associata. Nell’esempio, il primo elemento
della lista ha un link con l’url #Commento al quale corrisponde come contenuto quello del div con
l’id Commento.
Lo script che fa funzionare l’interfaccia tab-based è indipendente dalle scelte di stile. Normalmente,
infatti, si pone lo stile in un file CSS esterno. Nel nostro esempio ciascuna regola di stile è legata
direttamente a <div class="contenutoNascosto">:
#tab-menu{ border-bottom: 1px solid gray; /width: 90%; margin-bottom: 1em; }
#tab-menu ul{ padding: 3px 0; margin-left: 0; margin-top: 1px; margin-bottom: 0;
font: bold 12px Verdana; list-style-type: none; text-align: left; }
……….
Se abbiamo più interfacce tab-based sulla stessa pagina è forse più conveniente riferirsi ad una
classe nel foglio stile come, ad esempio:
.tab-menu-class{….}
.tab-menu-class ul{…..}
……….
classe che però va assegnata al div che definisce l’interfaccia:
<div id=”tab-menu” class=”tab-menu-class”>
<ul> ….. </ul>
<div id=”tab-contenuto”></div>
</div>
…..
Vediamo ora come è organizzato lo script che opera dietro la pagina e che è contenuto nel file
jquery.tabshort.js. Nella sezione <head> della nostra pagina HTML richiameremo questo script e
la libreria jQuery come segue:
<script type=”text/javascript” src=”../js/jquery.pack.js”></script>
<script type=”text/javascript” src=”jquery.tabshort.js”></script>
Le funzioni presenti in jquery.tabshort.js sono le seguenti:
- GestioneClickSuTab()
- AttivaTab()
- MostraContenuto()
Cosa fanno le varie funzioni è evidente da quanto abbiamo detto in premessa. Inoltre, in
jquery.tabshort.js abbiamo alcune funzioni accessorie e la funzione che viene eseguita per
inizializzare la tab – InizializzaTab – quando la pagina è interamente caricata (esempio):
$(document).ready(function() {
InizializzaTab (‘tab-menu’);
InizializzaTab (‘tab-menu2′);
});
Lo script può essere semplificato se non interessa realizzare la funzione codeview, in particolare la
funzione MostraContenuto, oppure può essere esteso, ad esempio per aggiungere effetti di
animazione. Ma in questo caso conviene usare direttamente il plugin jQuery.tabs.js, di cui
parleremo in un prossimo articolo.
Tutti gli esempi, completi delle librerie usate, sono disponibili per il download.
Due tecniche per menu a tab centrati
Negli esempi di questo articolo verrano illustrate due tecniche fondamentalmente diverse per
raggiungere un risultato simile. Partiamo dal presupposto di voler realizzare un menu a tab e
centrato orizzontalmente nella finestra del browser, attraverso una struttura XHTML classica
realizzatata con una lista non ordinata (<ul>), assicurandone la resa cross-browser senza utilizzare
hack CSS, regole non standard (display:inline-block è un esempio), o peggio, Javascript.
Voglio ricordare in proposito alcune risorse meritevoli di menzione: l’articolo di Alessandro
Fulciniti tab grafiche centrate, e due versioni delle Sliding Doors, Centered Sliding Doors Menus da
Explodingboy, e 100% clickable Sliding doors – centered da CSSPlay, che propongono degli
esempi di menu centrati con tab ad angoli arrotondati che però utilizzano degli hack per ottenere la
compatibilità con le diverse e capricciose versioni di Internet Explorer.
Primo esempio
Nella creazione di una barra di navigazione centrata l’approccio più ovvio (e quindi anche forse più
diffuso) prevede di centrare degli elementi, come nel caso delle voci di un menu, di dimensioni non
note a priori, attraverso le regole CSS display:inline (applicata su di essi) e textalign:center (applicata al loro contenitore). Vediamo subito la struttura HTML base
necessaria:
<div id="navigation">
<ul>
<li><a href="#" title="home">Home</a></li>
<li><a href="#" title="profilo">Profilo</a></li>
<li><a href="#" title="notizie">Notizie</a></li>
<li><a href="#" title="porfolio">Portfolio</a></li>
<li><a href="#" title="prodotti">Prodotti</a></li>
<li><a href="#" title="blog">Blog</a></li>
<li class="last"><a href="#" title="contatti">Contatti</a></li>
</ul>
</div>
Come abbiamo già detto, per affiancare le voci del menu utilizzeremo su di esse la dichiarazione
display:inline, evitando accortamente l’utilizzo dei float, cosa che ci consente una agevole
e robusta centratura applicando la dichiarazione text-align:center direttamente
sull’elemento <ul>.
Diversamente, utilizzando proprio la proprietà “float:left” per affiancare le voci della lista,
l’unico modo per centrare il menu è assegnare una larghezza definita e la proprietà margin:0
auto all’elenco non ordinato. Una soluzione comunque imperfetta: pensiamo a quali disastri
potrebbe provocare un eventuale ingrandimento del testo da parte dell’utente. Inoltre l’applicazione
di un tale metodo non si dimostra nemmeno flessibile, di fronte alla necessità di incrementare il
numero delle tab saremo ad esempio per forza di cose costretti a variare anche la width dell’elenco.
Torniamo piuttosto sui nostri argomenti cominciando ad analizzare più in dettaglio gli stili CSS e il
parziale risultato nella pagina di prova:
body {
margin:0; padding:0;
background:#FFFFFF; color:#000;
font-family:Arial, Helvetica, sans-serif;
font-size:85%;
}
#navigation {
}
background:#7FAACA url(bg-nav.jpg) repeat-x;
border-bottom:1px solid #999999;
#navigation ul, #navigation ul li {
list-style:none;
margin:0; padding:0;
}
#navigation ul {
text-align:center;
padding:0.5em 0;
}
#navigation ul li {
display:inline;
margin-right:0.5em;
}
#navigation ul li.last {
margin-right:0;
}
#navigation li a {
padding:0.5em 1em;
background:#FFFF00;
}
Possiamo dire di essere a metà dell’opera, avendo già ottenuto la centratura del menu di
navigazione: da osservare che le varie tab sono distanziate tra di loro del valore attribuito alla
proprietà margin-right. L’ultima voce della lista non ordinata dispone di una classe last proprio
per azzerare tale margine non più necessario. Non essendo possibile attribuire una height specifica
agli elementi inline, l’unico modo di intervenire sulle dimensioni delle ancore per dar loro la
consistenza del pulsante di una tab ci è dato dalla proprietà padding. Per un corretto contenimento
verticale del menu è necessario applicare gli stessi valori di padding-top e padding-bottom
direttamente anche sull’elemento genitore <ul>. nell’esempio appena visto viene assegnato un
colore di sfondo giallo sui collegamenti solo a scopo dimostrativo, che verrà rimosso negli stili
succesivi. Non rimane che creare le tab vere e proprie personalizzando l’aspetto grafico dei link.
Controlliamo le regole CSS che è necessario aggiungere prima di vedere l’esempio completo in
opera:
#navigation {
/* stili precedenti */
padding-top:2em;
}
#navigation ul li a {
background:#FFFFFF url(bg-tab.jpg) repeat-x;
color:#0033FF;
border-color:#999999;
border-style:solid;
border-width:1px 1px 0 1px;
text-decoration:none;
padding:0.5em 1em;
}
#navigation ul li a:hover {
color:#003366;
background:#FFFFFF;
}
#navigation ul li a.active,
#navigation ul li a.active:hover {
color:#FFFFFF;
background:#BCBCBC;
}
Da osservare l’inserimento di un padding-top alla barra di navigazione, per distanziare le tab
dal suo margine superiore: è stata anche aggiunta una classe active per evidenziare la tab
selezionata. Due le immagini di background utilizzate: una per la barra di navigazione e una per le
tab. Naturalmente è possibile modificare a piacimento gli stili applicati agli stati dei link in base alle
proprie preferenze.
Secondo esempio
Il secondo esempio dell’articolo prevede un approccio veramente originale, rendendo flottanti gli
elementi della lista e centrando poi la barra di navigazione attraverso un intelligente uso della
proprietà position. L’articolo originale di questa tecnica è Beautiful Horizontally Centered
Menus/Tabs/List. No CSS hacks. Full cross-browser di Matthew James Taylor. Per cominciare
possiamo utilizzare la stessa struttura HTML dell’esempio della tecnica precedente.
La realizzazione di questo menu parte dal principio che un elemento flottante con width non
assegnata assume una larghezza pari al suo contenuto: il trucco per ottenere la centratura è
posizionare relativamente degli elementi flottanti l’uno all’interno dell’altro. Incominciamo nel
costruire un semplice barra di navigazione allineata a sinistra. Ho predisposto un esempio e per
meglio evidenziare gli elementi, ho utlizzato le seguenti regole CSS:
#navigation {
float:left;
width:50%;
background:#fff;
border:4px solid #006699;
margin:15px 0;
}
#navigation ul, #navigation ul li {
list-style:none;
margin:0;
padding:0;
}
#navigation ul {
clear:left;
float:left;
margin:10px;
border:4px solid #CC0000;
}
#navigation ul li {
display:block;
float:left;
margin:10px;
border:4px solid #009900;
}
#navigation ul li a {
display:block;
margin:5px;
padding:10px;
border:4px solid #FFCC00;
text-decoration:none;
}
Il div#navigation, con bordo blu, è flottante a sinistra, con una larghezza del 100%.
• La lista non ordinata (ul), con bordo rosso, è contenuta nel div#navigation ed è anch’essa
flottante a sinistra, senza una width specificata. Questo significa che si dimensiona in base
alla larghezza del suo contenuto, che è data a sua volta dalla somma delle larghezze di tutte
le tab.
• Tutti gli elementi della lista (li), con bordo verde, sono contenuti nell’ul e sono anch’essi
flottanti a sinistra e affiancati orizzantalmente. Ogni li assume la larghezza del link in esso
contenuto.
• All’interno di ogni link (a), con bordo giallo, è inserito il testo descrittivo delle varie voci
del menu: home, profilo, porfolio, etc.
Il passo successivo è quello cruciale, cioè centrare l’elemento ul nel div#navigation: per fare questo
assegnamo ad entrambi gli elementi la regola position:relative, e spostiamo a destra la lista
non ordinata del 50% (left:50%). Vediamo l’esempio parziale. In questo modo l’elemento ul
viene spostato verso destra della metà della larghezza del div#navigation. Non rimane che spostare
la posizione di tutte le voci del menu verso sinistra del 50% (che rappresenta la metà della larghezza
del loro elemento genitore ul), assegnando ad ogni elemento li le regole position:relative e
right:50%. Ecco l’ulteriore esempio e le regole CSS aggiornate:
#navigation {
position:relative;
float:left;
width:100%;
background:#fff;
border:4px solid #006699;
border-width:4px 0;
margin:15px 0;
}
#navigation ul, #navigation ul li {
list-style:none;
margin:0;
padding:0;
}
#navigation ul {
position:relative;
left:50%;
clear:left;
float:left;
margin:10px 0;
border:4px solid #CC0000;
}
#navigation ul li {
position:relative;
right:50%;
display:block;
float:left;
margin:10px;
border:4px solid #009900;
}
#navigation ul li a {
display:block;
margin:5px;
padding:10px;
border:4px solid #FFCC00;
text-decoration:none;
}
Abbiamo praticamente quasi finito il lavoro “sporco”. E’ necessario fare però una annotazione:
dall’esempio precedente possiamo notare la inattesa comparsa della scrollbar orizontale nella
pagina, dovuta al fatto che l’elemento ul è posizionato in modo da eccedere la larghezza del
viewport, cioè della parte visibile della finestra del browser. Bisogna quindi sempre applicare la
regola overflow:hidden al div contenitore del menu (in questo caso al div#navigation).
Una volta rimossi i bordi colorati e i margini degli elementi inseriti solo a scopo di debug, possiamo
concentrarci sui dettagli più puramente estetici, per conferire un aspetto più gradevole al menu.
Poichè l’elemento ul non è allineato con gli elementi che contiene, non è possibile aggiungere stili
di presentazione ad esso; si può però intervenire a piacimento sugli elementi li ed a. Non avendo
molta fantasia, ho pensato di riutilizzare parte degli stili dell’esempio della prima tecnica illustrata,
sicchè il risultato finale è molto simile. Di seguito il CSS completo del menu:
#navigation {
position:relative;
float:left;
width:100%;
background:#7FAACA url(bg-nav.jpg) repeat-x;
border-bottom:1px solid #999999;
padding-top:2em;
}
#navigation ul, #navigation ul li {
list-style:none;
margin:0;
padding:0;
}
#navigation ul {
position:relative;
left:50%;
clear:left;
float:left;
margin:0;
}
#navigation ul li {
position:relative;
right:50%;
display:block;
float:left;
}
#navigation ul li a {
display:block;
margin:0 0.25em;
padding:0.5em 1em;
color:#0033FF;
border-width:1px 1px 0 1px;
border-color:#999999;
border-style:solid;
background:#FFFFFF url(bg-tab.jpg) repeat-x;
text-decoration:none;
}
#navigation ul li a:hover {
color:#003366;
background:#FFFFFF;
}
#navigation ul li a.active,
#navigation ul li a.active:hover {
color:#FFFFFF;
background:#BCBCBC;
}
Anche in questo caso è possibile evidenziare la tab selezionata assegnandole una classe active
creata ad hoc. Inoltre, sempre tramite l’aggiunta di classi apposite stavolta applicate sugli elementi
li, si può differenziare l’aspetto della prima e dell’ultima voce del menu. Visitando la pagina degli
esempi avanzati nel blog dell’autore sono disponibili diverse implementazioni grafiche di questa
tecnica; alcune barre di navigazione sono anche più accattivanti delle “semplici tab”.
Conclusioni
Attraverso le tecniche precedentemente illustrate, riusciamo ad ottenere un menu sempre centrato
orizzontalmente nella pagina, senza utilizzare hack CSS, dalla resa pressochè perfetta su tutti i
browser più diffusi (Firefox, Opera, Safari, Internet Explorer 6, 7 ed 8), con un codice XHTML
valido e semantico. Avendo utilizzato delle unità di misura in em o in unità percentuali, il menu
supera brillantemente la prova del ridimensionamento del testo, salvaguardando da un lato
l’integrità del layout della pagina e dall’altro l’accessibilità, una problematica da cui ormai non
possiamo più prescindere. Prerogativa essenziale di entrambe le versioni è la semplicità del codice e
dello stesso utilizzo.
Naturalmente, esiste anche il rovescio della medaglia. Un menu a tab grafiche con angoli
arrotondati può risultare più attraente; alcune volte in ragione dei risultati estetici può essere
necessario sacrificare l’uso di un hack, non sarà certo la fine del mondo. Inoltre, talvolta potrebbe
risultare poco agevole l’eventuale integrazione con sub-menu a tendina in Javascript: in questi casi
è meglio evitare i posizionamenti relativi o in linea e preferire comunque per una soluzione con i
float e non centrata.
Il codice CSS e gli esempi dell’articolo sono disponibili per il download.
Un’interfaccia a tab con il plugin jQuery.tabs
Abbiamo visto nell'articolo Tab semplici e accessibili con JQuery come costruire una interfaccia a
tab seguendo una procedura passo per passo. Lo script da me proposto, pur essendo semplice da
utilizzare ed efficace, non è così sofisticato e articolato come il plugin jquery.tabs.js - descritto sul
sito Stilbüro e creato da Klaus Hartl.
Rimando all'articolo Tab semplici e accessibili con JQuery, così come anche gli altri articoli
richiamati nello stesso per la necessarie conoscenze propedeutiche sull'interfaccia a tab. Inoltre, per
un'introduzione di carattere generale segnalo l'articolo (in inglese) Tabbed document interface,
presente in Wikipedia.
Per comprendere come utilizzare al meglio questo plugin di jQuery, affronteremo i seguenti
argomenti:
• la struttura degli oggetti del DOM da utilizzare, che in genere è abbastanza rigida
• le regole e i metodi CSS necessari o opzionali
• la sintassi del plugin stesso, i suoi parametri e le opzioni;
Cosa ci serve ?
Per prima cosa suggerirei di vedere cosa fa il plugin stesso andando alla pagina demo del suo
autore. Nella stessa pagina troviamo il link al package della demo stessa, cioè un file zippato
contenente sia la stessa demo sia tutti i file necessari, inclusa l'ultima versione del plugin.
Ma cerchiamo di andare per gradi. Nella package troviamo:
• una pagina html – index.html - in cui sarà visualizzata l'interfaccia a tab
• un foglio stile – jquery.tabs.css – in cui troviamo le regole CSS che ci occorrono per
la sola interfaccia a tab; in esso sono inserite le classi .tabs-nav necessarie per creare
l'interfaccia a tab a partire da una semplice lista; in genere possiamo personalizzare a piacere
queste classi, usando la grafica che vogliamo, inclusi alcuni elementi grafici definiti in file
immagine (nella demo è tab.png). Il foglio stile jquery.tabs-ie.css, definisce
delle classi applicate solo per IE, e occorre solo per il particolare stile grafico scelto
dall'autore.
• la libreria jquery.js; nel package è presente la versione compressa jquery1.1.2.pack.js;
• il plugin jquery.tabs.js, o le sue versioni ridotta – jquery.tabs.min.js – o
critptata e compressa – jquery.tabs.pack.js.
• il plugin jquery.history_remote.pack.js, realizzato dallo stesso autore e
descritto in questa pagina; questo plugin è utile per compensare il fatto che i click
sull'interfaccia a tab non vengono memorizzati nella cronologia del browser; questo plugin
non è indispensabile per fa funzionare l'interfaccia a tab, tuttavia se viene caricato
jquery.tabs.js lo riconosce e lo usa automaticamente.
Vediamo ora le istruzioni passo-passo per costruire la nostra interfaccia.
PASSO 1 – IMPOSTIAMO LE LINGUETTE E I CONTENUTI
Immaginiamo di volere visualizzare solo contenuti statici (non richiamati in remoto via Ajax):
quando clicchiamo su una linguetta visualizzeremo un contenuto che si trova nella stessa pagina e
non posto su pagine remote.
All'interno del body della pagina il plugin jquery.tabs.js richiede che si utilizzi una
struttura come questa:
<div id=”Container”>
<ul>
<li><a href=”#Sezione-1″>Tab 1</a></li>
<li><a href=”#Sezione-2″>Tab 2</a></li>
<li><a href=”#Sezione-3″>Tab 3</a></li>
</ul>
<div id=”Sezione-1″> Testo da visualizzare cliccando su Tab1 </div>
<div id=”Sezione-2″> Testo da visualizzare cliccando su Tab2 </div>
<div id=”Sezione-3″> Testo da visualizzare in cliccando su Tab3 </div>
</div>
Abbiamo un elemento <div> con id=Container, al cui interno troviamo un elenco non
ordinato <ul>, seguita da alcune sezioni <div>. Gli elementi della lista sono link che puntano
direttamente ad una di queste sezioni <div> (ovvero, più precisamente, l' dell'attributo href del
link rimanda direttamente all'attributo id della sezione). Le sezioni <div> contengono il testo
da visualizzare.
Gli id delle sezioni <div> possono essere tutti rinominati a proprio piacere. Se volessimo
visualizzare delle icone sulle linguette, i relativi tag <img> queste vanno posti dentro i tag <a>.
PASSO 2 – SCEGLIAMO L'ASPETTO DELLA PAGINA
Fin qui non abbiamo realizzato altro che un elenco e delle aree div. Per mostrare ciascun elemento
della lista come tab dobbiamo realizzare ed applicare un modello CSS, che potremo mettere nella
stessa pagina – in un tag <style> nella sezione <head> o, meglio, in un file esterno.
La cosa più facile è quella di scegliere da esempi già pronti, come quelli presenti alle seguenti
pagine:
• Top 71 CSS Menus Navigation Tabs
• Dynamic Drive's CSS Library: Horizontal CSS Menus
• SmashingMagazine.com: 14 Tab-Based Interface Techniques
Per esemplificare le operazioni non ho utilizzato il foglio stile presente nella demo originale di
jquery.tabs.js, ma ho adattato un esempio, esattamente basic-css-tabs-menu su Dynamic
Drive's.
Per adattare un qualunque menu-tab alle nostre esigenze dobbiamo considerare che:
1. normalmente jquery.tabs.js opera sulle classi e non sugli identificatori, pertanto se
troviamo nel foglio stile dei metodi come questi:
#tabmenu{…}
#tabmenu ul{…}
……
dobbiamo trasformarli in
.tabmenu{…}
.tabmenu ul{…}
……
2. Il nome delle classi che jquery.tabs.js usa per default è tabs-nav, mentre per la
linguetta attiva sarà necessario definire un metodo .tabs-nav li.tabs-selected a.
Pertanto, nel foglio stile scelto come esempio si dovrà sostituire il nome di classe basictab con
tabs-nav ed inotre il nome di classe selected con tabs-selected
3. Si dovrà poi aggingere una classe per nascondere i contenuti non desiderati:
.tabs-hide { display: none;}
4. Devo far notare che molti modelli di interfacce a tab, reperibili agli indirizzi indicati, necessitano
una loro struttura html-css troppo diversa da quella vista al “Passo 1″, e pertanto adattarli alle nostre
esegenze può essere molto complicato.
L'esempio 1 esemplifica i passaggi effettuati.
Se non vogliamo modificare nulla del foglio stile che abbiamo scelto per l'interfaccia a tab,
possiamo richiamare jquery.tabs.js con i parametri opzionali navClass –
selectedClass – disabledClass - containerClass. Tali parametri indicheranno al
plugin di usare i nomi delle classi specificate al posto dei nomi di default. L'esempio 2 esemplifica
questa seconda tecnica.
PASSO 3 – ATTIVIAMO L'INTERFACCIA A TAB
Includiamo nel modo consueto all'interno della sezione <head> i due principali componenti
Javascript che ci necessitano: la libreria jQuery e il plugin jquery.tabs.js:
<script type=”text/javascript” src=”jquery.js”></script>
<script type=”text/javascript” src=”jquery.pack.js”></script>
Ovviamente scriveremo:
<script src=”js/jquery.js” type=”text/javascript”></script>
<script src=”js/jquery.tabs.js” type=”text/javascript”></script>
se i due script sono stati messi nella sottocartella js/ della pagina HTML. è possibile anche
collegare le versioni packed cioè compresse delle due librerie Javascript.
Subito dopo, per mostrare e inizializzare l'interfaccia tab, aggiungeremo una sola riga di codice
javascript:
<script type=”text/javascript”>
$(document).ready(function(){ $('#Container').tabs(); });
</script>
Analizziamo il codice. Al verificarsi dell'evento ready, cioè quando tutti gli elementi del DOM
sono stati inizializzati, ma prima di essere visualizzati, viene eseguita una funzione contenente
un’unica istruzione e cioè: $('#Container').tabs(). La funzione tabs() agisce
sull'oggetto $('#Container'), che è l'oggetto del DOM associato al div con
id="Container", che ricordiamo è il div che contiene tutta l'interfaccia a tab.
Per comprendere come opera la funzione tabs() del plugin, esaminiamo le trasformazioni agli
oggetti DOM che abbiamo ricavato per l'esempio 1 usando l'estensione Firebug di Firefox. Di
seguito mostriamo come è stata trasformata la pagina nel browser subito dopo che la pagina è stata
caricata e il codice jQuery è stato eseguito:
<div id=”Container”>
<ul class=”tabs-nav”>
<li class=”tabs-selected”><a href=”#Istruzioni”>Modificazioni al foglio stile</a></li>
<li class=”"><a href=”#tabs-dd-htm“>Mostra tabs-dd.htm</a></li>
<li class=”"><a href=”#tabs-dd-css“>Mostra tabs-dd.css</a></li> …
</ul>
<div id=”Istruzioni” class=”tabs-container” style=”display: block;”>… </div>
<div id=”tabs-dd-htm” class=”tabs-container tabs-hide”> …. </div> …..
</div>
In colore rosso sono evidenziate le modificazioni apportate dinamicamente al DOM dalla funzione
tabs(): sono state attribuite delle classi all'elenco e ai suoi elementi. Al primo elemento
dell'elenco è stato attribuita la classe “tabs-selected”. Al div da visualizzare è attribuita la classe
"tabs-container" e lo stile "display: block;", mentre ai div associati alle linguette
non attive, e quindi da nascondere, le classi "tabs-container tabs-hide".
PASSO 4 – USIAMO LE OPZIONI E I COMANDI AVANZATI
Le opzioni avanzate non le troviamo descritte all'interno del sito http://stilbuero.de/jquery/tabs/, ma
direttamente all'interno del codice dello stesso plugin.
Vediamo, anzitutto degli esempi dei comando di creazione delle interfacce tab-based:
Codice da inserire
$('#container').tabs();
$('#container').tabs(2);
Descrizione
Crea l'interfaccia tab con l'id container, con la linguetta di default (la
prima) nello stato attivo
Crea l'interfaccia tab con l'id container con la seconda linguetta nello
stato attivo
$
Crea l'interfaccia tab con l'id container e usa l'effetto di animazione
('#container').tabs({fxSlide
slide quando viene mostrato il contenuto associato alle linguette
: true});
$('#container').tabs({
Crea l'interfaccia tab con l'id container con i parametri listaparametri
listaparametri });
I parametri sono delle coppie chiave: valore separate da virgole e che consentono di fornire
al plugin delle impostazioni opzionali:
Chiave : valore Descrizione
La chiave disabled consente di creare una interfaccia tab con le linguette
disabilitate indicate nell'Array. Ad esempio, il comando:
$('#Container').tabs({disabled: [3, 4]});
Crea l'interfaccia tab con l'id Container e disabilita le linguette 3 e 4.
disabled : Array Si intende che gli elementi dell'array sono numeri che possono partire da uno fino
al numero di linguette presenti.
Il valore di default è null (cioè nessuna linguetta è disabilitata)
Una linguetta può essere anche disabilitata anche attribuendole la classe “tabsdisabled”,
remote :
La chiave remote, di tipo booleano specifica se il contenuto delle linguette,
boolean
associato all'attributo href dei link delle linguette, è locale o remoto, e quindi
richiamato con Ajax.
Il plugin non consente di avere situazioni miste, ma solo linguette o tutte locali o
tutte remote. Se si vuole gestire una situazione mista bisogna usare il parametro
remote: false, e poi impostare il parametro onClick per gestire i link remoti.
fxFade :
Parametri che consentono di specificare il modo in cui avvengono le animazioni
Boolean,
durante la visualizzazione del contenuto associato a ciascuna linguetta. Per i
fxSlide :
Boolean
fxSpeed :
String|Number
fxShow : Object
fxHide : Object
fxShowSpeed :
String|Number
fxHideSpeed :
String|Number
dettagli delle chiave e dei valori dei parametri rimandiamo al testo del plugin.
Si tratta comunque degli stessi valori che jQuery usa per gestire le animazioni e
che sono descritti alla pagina:
http://docs.jquery.com/Effects
La chiave fxAutoHeight indica al plugin che l'altezza del contenitore tab deve
fxAutoHeight :
essere costante per tutti i contenuti delle linguette e corrispondente all'altezza del
Boolean
contenuto della linguetta più alto. Il valore di default è false.
E' una funzione che può essere invocata subito dopo che una linguetta è stata
cliccata. La funzione passa 3 argomenti: il primo è la linguetta cliccata, il secondo
Function
l'elemento div del DOM che contiene la linguetta cliccata, il terzo è la linguetta
onClick
che prima era attiva. Se la funzione ritorna false l'evento di click viene cancellato.
Questo può essere utile ad esempio per una validazione di una form o quando
bisogna gestire il caricamento di dati remoti
Function
Simile alla funzione onClick, ma viene attivata subito dopo che quando una
onHide
linguetta viene nascosta.
Function
Simile alla funzione onClick, ma viene attivata subito dopo che la completa
onShow
attivazione della linguetta.
PASSO 5 – COMANDARE L'INTERFACCIA
L'interfaccia a tab può essere “comandata” attraverso del codice javascript, ad esempio cliccando su
un bottone di una form. Potete verificare il funzionamento attraverso questa demo.
PASSO 6 – Migliorare l'usabilità con il plugin jquery.history_remote.js
Se utilizziamo un'interfaccia a tab per mostrare i contenuti del nostro sito, il browser non gestisce la
cronologia delle tab, e perciò diminuisce l'accessibilità e l'usabilità del sito. Il plugin
jquery.history_remote.js invece consente di aggiungere un bookmark all'URL attuale del
browser, e così consente di usare i bottoni “avanti” e “indietro” del browser.
Non c'è altro da fare che aggiungere nella sezione <head> della nostra pagina l'istruzione per
richiamare il plugin:
<script type=”text/javascript” src=”js/jquery.history_remote.pack.js”></script>
Il plugin jquery.tabs.js riconosce automaticamente la presenza del
jquery.history_remote.js durante l'inizializzazione della tab e non bisogna fare altro.
Per ora è tutto. Tutti i file relativi agli esempi sono come al solito disponibili per il download. In un
prossimo appuntamento andremo ad analizzare l’uso di jQuery e del plugin per richiamare contenuti
remoti tramite richieste Ajax.
File “comandi.html”
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Interfaccia a Tab con jquery.tabs.js: Esempio 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="tabs.css" type="text/css" rel="stylesheet" />
<script src="./js/jquery.pack.js" type="text/javascript"></script>
<script src="./js/jquery.history_remote.pack.js" type="text/javascript"></script>
<script src="./js/jquery.tabs.js" type="text/javascript"></script>
<script type="text/javascript">
function AttivaDemo(){
$('#Comandi tr td input').toggle();
if ($("#AttivaDemo").val().search("Attiva") >= 0)
$("#AttivaDemo").attr("value", "Nascondi bottoni demo")
else
$("#AttivaDemo").attr("value", "Attiva bottoni demo");
}
$(document).ready(function() {
$('#Container').tabs();
$('#Comandi tr td input').hide();
});
</script>
</head>
<body>
<h3>PASSO 5 - COMANDARE L&#39;INTERFACCIA</h3>
<p>L&#39;interfaccia a tab puo' essere &quot;comandata&quot; attraverso del codice javascript, ad esempio
cliccando su un bottone di una form:</p>
<input type="button" id="AttivaDemo" value="Attiva bottoni demo" onclick="AttivaDemo();" />
<table style="width: 100%; font-size:10pt" cellspacing="0" cellpadding="2" border="1" id="Comandi">
<tr>
<td><b>Codice da inserire</b></td>
<td><b>Descrizione</b></td>
</tr>
<tr>
<td>
<button name="P1" onclick="$('#Container').triggerTab(2);" style="float: right">Test</button>
$(&#39;#Container&#39;).triggerTab(2);
</td>
<td>Attiva la seconda tab dell&#39;interfaccia a tab contenuta in <code>&lt;div
id=&quot;container&quot;&gt;</code>.</td>
</tr>
<tr>
<td>
<span style="float: right"><input type="button" value="Test" name="P2" onclick="$('#Container').triggerTab();"></span>
$(&#39;#Container&#39;).triggerTab();&nbsp;&nbsp;
</td>
<td>Attiva la prima tab dell&#39;interfaccia a tab contenuta in <code>&lt;div id=&quot;container&quot;&gt;</code></td>
</tr>
<tr>
<td><span style="float: right"><input type="button" value="Test" name="P3" onclick="$('#Container').triggerTab('Sezione2');"></span>
$(&#39;#Container&#39;).triggerTab(&#39;Sezione-2&#39;);&nbsp;
</td>
<td>Attiva la tab associata all&#39;id &#39;<code>fragment-2</code>&#39;</td>
</tr>
<tr>
<td>
<span style="float: right"><input type="button" value="Test" name="P4" onclick="$('#Container').disableTab(3);"></span>
$(&#39;#Container&#39;).disableTab(3);&nbsp;
</td>
<td>Disabilita la terza tab</td>
</tr>
<tr>
<td>
<span style="float: right"><input type="button" value="Test" name="P5" onclick="$('#Container').enableTab(3);"></span>
$(&#39;#Container&#39;).enableTab(3);&nbsp;
</td>
<td>Abilita la terza tab</td>
</tr>
</table>
<p style="margin-top: 0; margin-bottom: 0">&nbsp;</p>
<div id="Container">
<p><b>INTERFACCIA TAB DIMOSTRATIVA</b></p>
<ul>
<li><a href="#Sezione-1">Tab 1</a></li>
<li><a href="#Sezione-2">Tab 2</a></li>
<li><a href="#Sezione-3">Tab 3</a></li>
</ul>
<div id="Sezione-1">Testo associato a Tab1</div>
<div id="Sezione-2">Testo associato a Tab2</div>
<div id="Sezione-3">Testo associato a Tab3</div>
</div>
<p>&nbsp;</p>
</body>
</html>
File “tabs.css”
/*
Credits: Dynamic Drive CSS Library
URL: http://www.dynamicdrive.com/style/
http://www.dynamicdrive.com/style/csslibrary/item/css-tabs-menu/
*/
.tabs-nav {
padding: 3px 0;
margin-left: 0;
font: bold 12px Verdana;
border-bottom: 1px solid gray;
list-style-type: none;
text-align: left; /*set to left, center, or right to align the menu as desired*/
}
.tabs-nav li {
display: inline;
margin: 0;
}
.tabs-nav li a {
text-decoration: none;
padding: 3px 7px;
margin-right: 3px;
border: 1px solid gray;
border-bottom: none;
background-color: #f6ffd5;
color: #2d2b2b;
}
.tabs-nav li a:visited {
color: #2d2b2b;
}
.tabs-nav li a:hover {
background-color: #F6FFD5;
color: black;
}
.tabs-nav li a:active {
color: black;
}
.tabs-nav li.tabs-selected a {
/*selected tab effect*/
position: relative;
top: 1px;
padding-top: 4px;
background-color: #FFFFFF;
color: black;
}
.tabs-nav li.tabs-disabled a {
color:#ccc;
}
.tabs-hide {
/* Use class for showing/hiding tab content, so that visibility can be better controlled in
different media types... */
display: none;
}
#Container {
border: thin inset #808080;
padding: 8pt;
background-color: #FFFFFF;
width: 80%;
display: block;
margin-left: 5%;
margin-right: 5%;
}
Schermata del risultato finale, si noti che i Tab sono prodotti dal file CSS.
Tabs: opzioni
L’utilizzo delle schede (tab) per gestire blocchi di contenuto molto corposi o di diversa natura
è ormai divenuta una soluzione comune nel campo dell’interface design, tanto da essere spesso
preso come metro di valutazione dell’aggiornamento di un software.
Se prendiamo ad esempio il campo dei web browser, una delle pecche maggiormente messe in
evidenza del vecchio IE6 era la mancanza della navigazione a tab ormai comune in Firefox ed
Opera. Peraltro questa soluzione progettuale è diventata così pervasiva da aver invaso anche
l’interfaccia di prodotti desktop come Office.
Per quanto riguarda il web, l’uso di tab è indicato nei casi in cui ci sia necessità di suddividere un
contenuto in blocchi ben distinti, dando così più rilievo alle singole parti via via visualizzate
dall’utente.
È invece buona norma evitare le tab (e altre strutture come gli accordion) nel caso in cui il
contenuto sia sostanzialmente omogeneo o comunque presenti rimandi interni, in modo da evitare
che l’utente debba saltare continuamente da una scheda all’altra.
Nella sua configurazione di default, il widget tab è richiamato con il seguente codice:
$('#tabs').tabs();
e crea una struttura di navigazione a schede a partire da una struttura HTML come la seguente
(esempio live):
<div id="tabs">
<ul>
<li><a href="#fragment-1"><span>Uno</span></a></li>
<li><a href="#fragment-2"><span>Due</span></a></li>
<li><a href="#fragment-3"><span>Tre</span></a></li>
</ul>
<div id="fragment-1">
<p>Testo 1</p>
<pre><code>$('#tabs').tabs();</code></pre>
</div>
<div id="fragment-2">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit...
</div>
<div id="fragment-3">
Lorem ipsum dolor sit amet, consectetuer adipiscing
elit...
</div>
</div>
Sebbene questa struttura possa essere realizzata con una semantica più corretta, essa rimane
comunque leggibile e navigabile anche quando CSS e JavaScript sono disabilitati, garantendo anche
un elevato grado di accessibilità.
Come vedremo più avanti il widget non si limita ad applicare una serie di interazioni ed effetti
grafici al contenuto preesistente, ma permette anche di caricare dinamicamente il contenuto delle
schede, di aggiungere e cancellare schede on demand.
Opzioni
Come per altri widget complessi, è possibile adeguare in profondità l’aspetto e le funzionalità delle
tab secondo le proprie necessità progettuali. Ecco le principali:
• ajaxOptions: (oggetto)
un oggetto JavaScript contenente le opzioni per la gestione del caricamento di contenuti
nelle tab via AJAX (vedere $.ajax per le proprietà disponibili).
• cache: (booleano – false)
se impostato su true il contenuto delle schede caricato con AJAX sarà salvato nella cache.
Per evitare che anche le richieste AJAX siano salvate nella cache del brower dovrete
aggiungere l’opzione cache : false in ajaxOptions.
• collapsible: (booleano – false)
permette di rendere collassabili tutte le schede, lasciando visibili solo le etichette.
• cookie: (oggetto – null)
salva l’ultima scheda selezionata in un cookie, per essere riutilizzata come scheda di default
quando l’utente ritorna sulla pagina. Richiede l’utilizzo del plugin cookie. L’oggetto passato
come valore dell’opzione dev’essere formattato secondo quanto previsto dal plugin cookie,
ad esempio: { expires: 7, path: '/', domain: 'jquery.com',
secure: true }.
• event: (stringa – 'click')
l’evento che permette di visualizzare il contenuto di una scheda. In alcuni casi potrebbe
essere preferibile associare l’apertura di una scheda all’evento mouseover, tuttavia
bisogna tener conto dei problemi legati al movimento involontario del mouse da parte
dell’utente.
• panelTemplate / tabTemplate: (stringa)
indicano un modello al quale applicare il contenuto di tab caricate in remoto (AJAX)
rispettivamente per la scheda (default '<div></div>') e l’etichetta (default '<li><a
href="#{href}"><span>#{label}</span></a></li>').
• selected: (intero : 0)
indica l’indice (a partire da 0) della scheda di default al momento dell’inizializzazione del
widget. Per non impostare alcuna tab passate il valore -1. Se richiamata dal metodo
'option', questa opzione restituirà l’indice della scheda attiva corrente sotto forma
di intero.
L’elenco completo delle opzioni disponibili è in questo documento.
Tabs: eventi e metodi
Eventi
Proprio per la complessità del widget, gli sviluppatori ci hanno messo a disposizione una nutrita
serie di eventi con i quali interagire per controllare al meglio l’integrazione di tab con gli altri
elementi dell’interfaccia e l’insieme dell’esperienza di navigazione:
• select: è lanciato quando viene selezionata una scheda, più precisamente quando è invocato
l’evento dell’opzione event (di default click).
• load: lanciato quando il contenuto di una scheda caricato da remoto viene caricato
completamente.
• show: lanciato quando una scheda viene mostrata e diventa attiva.
• add / remove: lanciato quando viene aggiunta una nuova scheda
• enable / disable: lanciato quando una tab viene ablitata o disabilitata.
Tutte le funzioni di callback associate agli eventi accettano come argomenti l’evento JavaScript
nativo ed un oggetto ui con le seguenti proprietà:
• tab: etichetta della scheda selezionata
• panel: elemento che contiene la scheda corrente
• index: un intero indicante l’indice della scheda selezionata (partendo da 0)
Metodi
Attraverso i metodi specifici per tab è possibile interagire via script con le schede gestite dal widget
nonché gestirne il comportamento relativamente alle opzioni di caricamento e aggiunta dinamica di
contenuti via AJAX:
• add: attraverso questo metodo è possibile aggiungere una scheda al widget sia associandovi
un contenuto già presente nel documento, sia caricandolo da remoto. Al momento non è
ancora supportata la possibilità di caricare contenuti da siti esterni (AJAX cross domain).
Il metodo necessità di due argomenti: il primo di tipo stringa dev’essere un’ancora legata ad
un contenuto presente nel documento oppure un URL da cui caricare in modo asincrono un
frammento di HTML. Il secondo argomento obbligatorio è una stringa da utilizzare come
testo della nuova etichetta. Opzionalmente è possibile passare un indice di tipo numerico per
posizionare la nuova scheda in una posizione precisa del widget, che altrimenti sarà inserito
in fondo (esempio).
•
•
•
•
•
•
•
//Carica una nuova scheda da un elemento con attributo
//name="nuovascheda"
$('#tabs').tabs('add','#nuovascheda','Nuova Scheda');
//Carica una nuova scheda da un URL del sito
$('#tabs').tabs('add','carica.php','Nuova Scheda');
remove: rimuove dal widget una tab specifica in base al numero di indice passato come
argomento (partendo da 0).
//Cancella la prima scheda
$('#tabs').tabs('remove',0);
select: rende attiva la scheda indicata come ulteriore argomento:
//Rendi attiva la terza scheda
$('#tabs').tabs('remove',2);
load: ricarica il contenuto di una specifica scheda caricato dinamicamente. Può essere utile
nel caso il contenuto sia soggetto ad aggiornamenti costanti (per esempio un lettore di feed
RSS)
url: cambia l’URL associato ad una scheda dinamica. Necessita di altri due argomenti
indicanti rispettivamente la posizione della scheda nel widget (a partire da 0) ed il nuovo
indirizzo da cui caricare i contenuti.
length: restituisce il numero di tab caricate nel widget.
abort: cancella tutte le richieste AJAX ancora in sospeso per tab caricate dinamicamente.
rotate: attiva una rotazione automatica fra le schede del widget. Accetta come ulteriori
argomenti un intero indicante i millisecondi fra la visualizzazione di una scheda e la
successiva, nonché un valore booleano opzionale per stabilire se la rotazione debba essere
continua o fermarsi quando l’ultima scheda è divenuta attiva.
Questo metodo è molto utile quando il widget viene usato come teaser dei contenuti di un
sito.
Usi particolari e note di utilizzo
Proprio per la complessità del widget e la possibilità offerta di aggiungere, rimuovere e caricare
schede dinamicamente, vi sono alcuni accorgimenti utili da seguire per garantire la migliore
fruibilità dei contenuti ed una migliore consistenza nelle funzionalità del widget.
Anzitutto potrebbe essere necessario mantenere la navigazione dei link presenti in una scheda
all’interno di quest’ultima, piuttosto che aprirli in una nuova finestra o nella finestra corrente. In
tal caso si può ricorrere allo script seguente in fase di inizializzazione del widget:
$('#tabs').tabs({
load: function(event, ui) {
$('a', ui.panel).click(function() {
$(ui.panel).load(this.href);
return false;
});
}
});
In secondo luogo è importante sottolineare che ogni componente che richieda un calcolo sulle sue
dimensioni durante l’inizializzazione non funzionerà se caricato in una scheda nascosta, poiché la
scheda stessa è nascosta via CSS con display: none. Un accorgimento utile può essere quello
di sovrascrivere il CSS nativo di jQuery UI con il seguente:
.ui-tabs .ui-tabs-hide {
position: absolute;
left: -10000px;
}
In modo da nascondere le tab inattive semplicemente spostandole al di fuori del viewport. In realtà
questa soluzione non è sempre efficace in quanto molto legata allo specifico contesto del layout
dell’applicazione.