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'INTERFACCIA</h3> <p>L'interfaccia a tab puo' essere "comandata" 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> $('#Container').triggerTab(2); </td> <td>Attiva la seconda tab dell'interfaccia a tab contenuta in <code><div id="container"></code>.</td> </tr> <tr> <td> <span style="float: right"><input type="button" value="Test" name="P2" onclick="$('#Container').triggerTab();"></span> $('#Container').triggerTab(); </td> <td>Attiva la prima tab dell'interfaccia a tab contenuta in <code><div id="container"></code></td> </tr> <tr> <td><span style="float: right"><input type="button" value="Test" name="P3" onclick="$('#Container').triggerTab('Sezione2');"></span> $('#Container').triggerTab('Sezione-2'); </td> <td>Attiva la tab associata all'id '<code>fragment-2</code>'</td> </tr> <tr> <td> <span style="float: right"><input type="button" value="Test" name="P4" onclick="$('#Container').disableTab(3);"></span> $('#Container').disableTab(3); </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> $('#Container').enableTab(3); </td> <td>Abilita la terza tab</td> </tr> </table> <p style="margin-top: 0; margin-bottom: 0"> </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> </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.
© Copyright 2024 Paperzz