martes, octubre 02, 2007

Yahoo! UI (yui) TabView como menu horizontal.

Ultimamente estoy usando la libreria de Yahoo! UI para todo lo que tenga que ver con Ajax, en los sitios web en los cuales solo se requiere html. Para los casos de ASP.Net sigo utilizando el Ajax Control Toolkit.

Me gusto mucho el menu que encontré en la página de Raphaël GOETTER

Este consiste de un menu horizontal expandible, muy rápido y muy sencillo. El problema es que tienes que batallar un poco con el posicionamiento de CSS, y me estaba atorando con algunos margenes y detalles.

Pero tomando esta idea y con algunas modificaiones pude obtener un menu que funciona de la misma forma, pero con la ventaja de no estar batallando con lo que mencionaba anteriormente.

Para lo anterior use el widget TabView de la libreria de YUI. Sólo tuve que hacer algunas modificaciones para en el archivo de estilo de yahoo, en particular /build/tabview/assets/skins/sam/tabview.css:

.yui-navset {
clear:both;
white-space:nowrap;
}
.yui-content {
background:silver;
}
a.yui-link:visited {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
text-decoration: none;
margin-right: 15px;
color: #EEEEEE;
}
a.yui-link:active {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
text-decoration: none;
margin-right: 15px;
color: #EEEEEE;
}
a.yui-link {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
text-decoration: none;
margin-right: 15px;
color: #EEEEEE;
}
a.yui-link:hover{
color:#FFFFFF;
text-decoration:underline;
}

Nota: la anterior modificacion se puede hacer en un archivo separado de css, o hasta el final del archivo tabview.css, para poder heredar el estilo que trae por omision.

Ahora bien, el problema que encontre es cuando se da click en algunos de los botones padres del menu, no se puede ir a otra pagina se tiene que poner dentro de la parte del submenu, por lo menos una liga:

Y aunque lo anterior, funcionaba bien, el cliente y yo mismo decidimos que no era lo mejor, la navegacion se volvia repitiva, pues escoges por ejemplo financiamiento y despues te aparece la pestaña con los enlace correspondientes, pero en este caso solo es un enlace, es decir para ver una pagina habia que clickear 2 veces. No, nada de "usability".

Asi que me puse a investigar un poco sobre la libreria de Yahoo, y resulta que se puede agregar eventos y propiedades al control tabview para este tipo de requerimientos.

Con mi viejo pero util libro de javascript 1.0 a un lado y la documentacion del API de Yahoo!, agregue el siguiente código:

(function() {
var tabView = new YAHOO.widget.TabView('demo');
var handleActiveTabChange = function(e,obj){
window.location=YAHOO.util.Dom.get(obj).firstChild.getAttribute("href").toString();
return false;
}
var handleNewWindowFromTab = function(e,obj){
window.open(YAHOO.util.Dom.get(obj).firstChild.getAttribute("href").toString());
return false;
}
YAHOO.util.Event.addListener("tab1", "click", handleActiveTabChange, "tab1");
YAHOO.util.Event.addListener("tab3", "click", handleNewWindowFromTab, "tab3");
YAHOO.util.Event.addListener("tab4", "click", handleActiveTabChange, "tab4");
YAHOO.util.Event.addListener("tab6", "click", handleActiveTabChange, "tab6");
YAHOO.util.Event.addListener("tab7", "click", handleActiveTabChange, "tab7");

})();

Ahora bien estos "listeners" buscan la pestaña tab1, tab3, tab4, etc., y al evento click se ejecuta la funcion handleActiveTabChange o en su caso handleNewwindowFromTab. Pero se tiene que modificar la estructura del ejemplo basico de TabView.

<ul class="yui-nav">
<li id="tab1"><a id="inicio" href="index.html"><em>Inicio</em></a></li>
<li><a href="#tab2"><em>Línea de modelos</em></a></li>
<li id="tab3"><a id="seminuevas" href=http://www.autos-usados.autoplaza.com.mx><em>Unidades seminuevas</em></a></li>
<li id="tab4"><a href="financiamiento.htm"><em>Financiamiento</em></a></li>
<li><a href="#tab5"><em>Acerca de Subaru</em></a></li>
<li id="tab6"><a id="contacto" href="contacto.htm"><em>Contacto</em></a></li>
<li id="tab7" class="selected"><a href="bolsa_trabajo.htm"><em>Bolsa de trabajo</em></a></li>
<li><a href="#tab8"><em>Mi Subaru</em></a></li>
</ul>

Agregue un ID a los elementos li que no tendrian un submenu con la ordenacion correspondiente y la siguiente etiqueta es la que contiene el link, esto es importante pues en la funcion handleActiveTabChange se esta obtiendo el atributo href de la etiqueta hija de li:


  • YAHOO.util.Dom.get(obj).firstChild.getAttribute("href")
Por otra parte encontre que tenia que colocar los divs correspondientes en el html, para que aquellos botones con submenus no se recorrieran:

<div id="notab1"></div>
<div id="tab2">
<a href="autos/forester.htm" class="yui-link">Forester</a>
<a href="autos/impreza.htm" class="yui-link">Impreza</a>
<a href="autos/imprezaWRX.htm" class="yui-link">Impreza WRX</a>
<a href="autos/legacy.htm" class="yui-link">Legacy</a>
<a href="autos/outback.htm" class="yui-link">Outback</a>
<a href="autos/tribeca.htm" class="yui-link">Tribeca</a>
</div>
<div id="notab3">
</div>

Ahora lo que mi menu funciona con links a nivel raiz, o a nivel submenus.

Listo!

4 comentarios:

Alfredo Carrillo dijo...

...el problema que encontre es cuando se da click en algunos de los botones padres del menu, no se puede ir a otra pagina se tiene que poner dentro de la parte del submenu...

No se si en la versión que entonces usaste no se podía, pero en la versión YUI-2.6.0 es realmente muy sencillo.

vgarcias dijo...

Gracias por tu cometario. Revisare ese codigo. El detalle es que deje a un lado esta libreria por la de JQuery. Pero dare una revision, y a lo mejor muestro las dos versiones.
Listo!

limonn dijo...

Hola se ve rebueno como quedo tu menu horizontal. Me gustaria si pones un link para bajarlo y usarlo, te felicito.

vgarcias dijo...

El ejemplo puede ser visto en http://www.subarugomsa.com.mx/