viernes, 30 de julio de 2010

Programación acordeón con JQuery

En mi ultimo proyecto desarrollado, para el hotel lagunamar en la isla de margarita; se presento una página interna donde se requería un acordeón para mostrar información. 




Aunque existen varios Plugins  para realizar acordeones como http://docs.jquery.com/UI/Accordion, el código lo desarrolle por mi cuenta ya que es bastante sencillo y un buen proceso de aprendizaje.

Primero veamos el Html completo para un acordeón de 3 tabs:

<div id="acordeon">    

   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">     

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     Et lorem tristique amet integer tristique et integer et, vel amet, porta urna montes sit ut! Ultrices?

           </div> 

   </div>


   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">     

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     pellentesque, purus, amet elementum pid ultrices phasellus! Ultrices amet nu

           </div> 

   </div>   

   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">      

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     Velit enim habitasse duis turpis turpis massa sit cursus e

           </div> 

   </div>

</div>

Simplificando tenemos el código de cada Tab:

<div class="headerTabApagado headerTab">

     <div class="verdana14 bold labelApagado labelHeader">

             Titulo del tab

     </div>

     <div class="flechaTab flechaTabAbajo">

     </div>

</div>

<div class="contAcordion verdana12 darkgray">      

   Contenido del Tab

</div>

Donde tenemos el código del Titulo, área que esta siempre visible:


<div class="headerTabApagado headerTab">

    <div class="verdana14 bold labelApagado labelHeader">

          Título del tab</div>

   <div class="flechaTab flechaTabAbajo">

   </div>

</div>




El contenedor del tab posee dos clases CSS, headerTab que define el estilo general de los tabs:


  .headerTab

  {

      width: 658px;

      height: 42px;

      margin-left: 34px;

      position: relative;

      margin-top: 10px;

      cursor: pointer;

      float: left;

  }
y la clase headerTabApagado, que define el estilo de los tabs que se encuentran cerrados:


  .headerTabApagado

  {

      background-image: url(../Img/FondoGrisAcordeon.png);

      border: 2px solid #8d8d8d;

  }
Dentro de este div tenemos dos contenedores, uno que define el título con las clases CSS labelHeader y labelApagado, que definen los estilos de los títulos en general y de los tabs cerrados respectivamente:







  .labelHeader

  {

      position: absolute;

      top: 12px;

      left: 12px;

  }
   
  .labelApagado

  {

      color: #333333;

  }
Luego tenemos un div con la flecha de la derecha, igualmente con dos clases que representan el estilo general de las flechas, y el especifico de las flechas de los tabs cerrados, flechaTab y flechaTabApagado:





  .flechaTab

  {

      width: 28px;

      height: 28px;

      position: absolute;

      left: 612px;

      top: 7px;

  }   

  .flechaTabAbajo

  {

      background-image: url(../Img/flecha1.png);

  }

Finalmente tenemos el contenido de los Tabs:


  <div class="contAcordion">

      Contenido

  </div>

Ahora la parte mas interesante, el código JavaScript para realizar el efecto:


  $(function () {

              $('.headerTabApagado').click(prender);

          });

   

          function apagar() {

           $(this).removeClass('headerTabPrendido').addClass('headerTabApagado');

           $(this).next('.contAcordion').slideUp();

           $(this).children('.labelHeader').removeClass('labelPrendido').addClass('labelApagado');


           $(this).children('.flechaTabArriba').removeClass('flechaTabArriba').addClass('flechaTabAbajo');

           $(this).unbind('click');

           $(this).click(prender);

       }

       function prender() {

           apagarByNombre($('.headerTabPrendido'));

           $(this).removeClass('headerTabApagado').addClass('headerTabPrendido');

           $(this).next('.contAcordion').slideDown();

           $(this).children('.labelHeader').removeClass('labelApagado').addClass('labelPrendido');

           $(this).children('.flechaTabAbajo').removeClass('flechaTabAbajo').addClass('flechaTabArriba');

           $(this).unbind('click');

           $(this).click(apagar);

       }

       function apagarByNombre(nombre) {

         $(nombre).removeClass('headerTabPrendido').addClass('headerTabApagado');

         $(nombre).next('.contAcordion').slideUp();

         $(nombre).children('.labelHeader').removeClass('labelPrendido').addClass('labelApagado');

         $(nombre).children('.flechaTabArriba').removeClass('flechaTabArriba').addClass('flechaTabAbajo');

         $(nombre).unbind('click');

         $(nombre).click(prender);

     }

En las primeras 3 líneas agregamos la funcionalidad de prender un tab al momento de hacer click sobre el.


La función prender primero se encarga de cerrar el tab que se encuentre abierto previamente, eso lo realiza llamando a apagarByNombre. Luego remueve y agrega estilos Css para cambiar el estilo del tab (de gris a morado). Después utiliza la animación SlideDown para mostrar el contenido del tab. Finalmente remueve la función que tiene asociado actualmente al evento click (el de abrir tab) con $(this).unbind('click'); y le agrega la funcionalidad de cerrar el tab al evento click, $(this).click(apagar);.

Las funciones de apagar actúan de manera similar, intercambian las clases CSS para modificar el aspecto visual, luego llaman a la funcion slideUp() para ocultar el contenido del tab, y finalmente modifican la funcionalidad del evento click sobre ese tab con $(nombre).unbind('click'); y $(nombre).click(prender);



Al momento de escribir el tutorial la página aun no se encuentra al aire, pero pueden observar una vista previa del funcionamiento de los tabs en http://legendsoft.com.ve/Lagunamar/FAQ