Tabs UJS con i data-behaviour

Ho scoperto l’UJS in concomitanza della sua introduzione massiccia su Rails: ne sono rimasto immediatamente affascinato. Un coupling ancora meno stretto tra contenuto e comportamenti dinamici della pagina, utilizzando come strumento di comunicazione gli attributi HTML5¬†data-*? Fantastico! ūüôā

Ho cercato da quel momento di impegnarmi a generare codice JS quanto pi√Ļ unobtrusive possibile; il vantaggio √® evidente dopo i primi tentativi: nel tempo, arrivi a comporre una comoda libreria di comportamenti riutilizzabili in altri contesti senza nessun codice JS custom da introdurre.

Esempio: una tabbed interface

Quante volte vi sarà capitato di dover impostare una vista a tab? Io sono arrivato a questa soluzione, che considero difficilmente battibile, sia per chiarezza che per brevità:

1 $ -> 
2 
3 $tab_scope_contents = {} 
4 
5 $("[data-behaviour=tab]").each -> 
6 $tab = $(this) 
7 $tab_content = $($tab.attr("href") || $tab.find("a").attr("href")).hide() 
8 scope = $tab.data("tab-scope")
 9 $related_tabs = $("[data-tab-scope=#{scope}]")
 10 $tab_scope_contents[scope] = ($tab_scope_contents[scope] || $()).add $tab_content 
11 
12 $tab.click -> 
13 $related_tabs.removeClass("selected-tab") 
14 $tab.addClass("selected-tab") 
15 $tab_scope_contents[scope].hide() 
16 $tab_content.show() 
17 false 
18 
19 $related_tabs.eq(0).click()

Come si utilizza? Semplice: supponiamo di avere un HTML del genere:

 1 <ul> 
2 <li><a href="#primo">Primo tab</a></li> 
3 <li><a href="#secondo">Secondo tab</a></li> 
4 <li><a href="#terzo">Terzo tab</a></li> 
5 </ul> 
6 
7 <div id="primo">Primo contenuto!</div> 
8 <div id="secondo">Secondo contenuto!</div> 
9 <div id="terzo">Terzo contenuto!</div>

E’ sufficiente aggiungere, per ogni tab handle, un attributo¬†data-behaviour="tab"¬†per specificare che vogliamo da quel link un comportamento di tipo “tab”, e un attributo¬†data-tab-scope="nome-dello-scope"¬†per specificare a quale gruppo di tab appartenga:

 1 <ul> 
2 <li><a href="#primo" data-behaviour="tab" data-tab-scope="tabset1">Primo tab</a></li> 
3 <li><a href="#secondo" data-behaviour="tab" data-tab-scope="tabset1">Secondo tab</a></li> 
4 <li><a href="#terzo" data-behaviour="tab" data-tab-scope="tabset1">Terzo tab</a></li> 
5 </ul>

Boom. Il gioco √® fatto. Ora, ovunque tu voglia tab, basta aggiungere due attributi all’HTML.

Cosa ne pensate?