Una pregunta que se repite es ¿cómo hago para que los gadgets de la sidebar del blog, puedan expandirse y contrarerse y de tal modo ganar espacio?

No es algo facil de responder, no porque sea difícil de hacer sino porque hay cientos de variantes; con y sin librerías, con y sin efectos y todas ellas requieren scripts de alguna clase y modificar o adaptar algo de nuestra plantilla; eso es inevitable; si alguien pretende implementar algo similar, deberá hacerlo con cuidado y tratando de entender lo que hace, aunque sea, minimamente.

En Blogger, todos los widgets o gadgets o cómo se los quiera llamar, tienen la misma estructura básica:
<b:widget id='ALGO' locked='false' title='Indice' type='TIPO'>
<b:includable id='main'>
  <b:if cond='data:title'>
    <h2><data:title/></h2>
  </b:if>
  <div class='widget-content'>
    .......
  </div>
</b:includable>
</b:widget>
En ese esquema, H2 es el título y el DIV que está debajo cuya clase es widget-content contiene todo lo demas, sea lo que sea.

Algunos widgets tienen un DIV distinto, con varias clases o con un ID pero para esto, esos detalles carecen de importancia:
<div expr:class='&Mquot;widget-content &quot; + data:display + &quot;-label-widget-content&quot;'>
<div class='widget-content' expr:id='data:widget.instanceId + &quot;_feedItemListDisplay&quot;'>
<div class='widget-content popular-posts'>
La forma básica de crear un sistema que permita permutar entre algo oculto y algo visible es usar un enlace que ejecute una función de tipo toggle; se lee la propiedad display de cierto elemento; si es none (esta oculto) se cambia por block (visible) y si es block se cambia por none. Esto podemos hacerlo con un script sencillo o usar librerías como Scritpaculous o jQuery.

El script sería algo así:
<script type='text/javascript'>
//<![CDATA[
function SINO(cual) {
   var elElemento=document.getElementById(cual);
   if(elElemento.style.display == 'block') {
      elElemento.style.display = 'none';
   } else {
      elElemento.style.display = 'block';
   }
}
//]]>
</script>
Y en el gadget, deberíamos agregar los atributos y eventos:
<h2 onclick='SINO(&quot;permutar&quot;)'><data:title/></h2>

<div class='widget-content' id='permutar' style='display:none;'>
  .......
</div>
Se le adosa el evento onclick a la etiqueta H2 (o se agrega un enlace común) y se oculta el DIV que requiere que sea identificado con un ID único; si son varios, cada uno deberá tener un ID diferente.

Pero, JavaScript permite que hagamos lo mismo de modo más automático, para eso están addEventListener y attachEvent que son la forma de agregar esos eventos (onclick por ejemplo) en ciertas etiquetas, sin tener que escribir eso atributos ni agregar IDs. Para eso, siempre necesitamos modificar la plantilla porque, de alguna manera debemos indicarle cuáles son las que queremos manipular. Pero, como queremos que sea algo mucho más genérico, en lugar de usar IDs, usamos clases.

Entonces, en cualquier widget de Blogger:
<h2 class='expcon'><data:title/></h2>
<div class='widget-con'>
  ..............
</div>
Agregamos la clase expcon a la etiqueta H2 y cambiamos la clase widget-content del DIV por una nueva llamada widget-con.

Si no se quiere hacer esto y se quieren mantener las etiquetas existente (por las dudas) podemos agregar un DIV de este modo:
<h2 class='expcon'><data:title/></h2>
<div class='widget-con'>
  <div class='widget-content'>
    ..............
  </div>
</div>
Y ahora, las funciones del script antes de </head>:
<script type='text/javascript'>
//<![CDATA[

// agrega un ID a la etiqueta si se usa Internet Explorer
// http://www.codingforums.com/archive/index.php/t-125144.html
var IEelem={};
function IEaddID(fn,uniqueID) {
  return function(event) {return fn.call(IEelem[uniqueID],event);}
}

// esta es la función que agregará el evento onclick
function agregarEVENTO() {
  // creo una lista con todas las etiquetas H2
  var el = document.getElementsByTagName("h2");
  // leo la lista una por una
  for (var i=0; i<el.length; i++) {
    var c = el[i].className; // leo el contenido del atributo class
    // si es una etiqueta H2 con la clase que definí (expcon)
    // le agrego un evento que ejecute una función a la que llamo togglewidget
    if (c=="expcon") {
      if (el[i].addEventListener) {
         // Firefox, Chrome, Opera, IE9
        el[i].addEventListener("click", togglewidget, false);
      } else if (el[i].attachEvent) {
        // Internet Explore 8
        var uniqueID = el[i].uniqueID;IEelem[uniqueID] = el[i];
        el[i].attachEvent("onclick",IEaddID(togglewidget,uniqueID));
      }
    }
  }
}

// y esta es la función que permuta el contenido
function togglewidget() {
  // hice click en la etiqueta H2 pero, debo ocultar la etiqueta DIV que es la siguiente; así que la busco
  var obj = this.nextElementSibling || this.nextSibling;
  // y le invierto la clase
  if(obj.className=="widget-con") {
    // esta oculta así que la muestro
    obj.className = "widget-exp";
  } else {
    // esta visible así que la oculto
    obj.className = "widget-con";
  }
}

// una vez que la página web se carga, ejecuto la función
onload=function() { agregarEVENTO(); }

//]]>
</script>
Algo de CSS me permite definir las reglas para esas clases nuevas:
<style>
  h2.expcon { cursor: pointer; }
  .widget-exp { display: block; }
  .widget-con { display: none; }
</style>
De este modo, cada vez que agregue un widget que quiera ocultar y desplegar, sólo deberé cambiar esas dos clases del código que agrega Blogger.

Es verdad que en lugar de cambiar la clase podría cambiar la propiedad display pero, perfiero que quede así ya que esto, me permitirá agregar efectos ... otro dia.

8 comentarios:

Lui'S Y  

Buena entrada!!

Yo me tire una noche haciendo el mio con lo que te comente!
Solo me quedaría darle el toque "deslizante" que usas tu por ejemplo en "banners".
Porque a mi me aparece directamente y desaparece con el click..

Un saludo maquina!

Responder
Mariela Marianetti  

Un día lo voy a intentar. Me resulta muy interesante lo de ganar espacio ya que no quiero que mi blog tarde tanto en cargarse.

Un saludo JM y gracias por tus enseñanzas.

Responder
Bonzu Pipinpadaloxicopolis III  

Tengo una duda JMiur, esto de ocultar y mostrar con efectos, ¿podría hacerse únicamente con CSS3?

Responder
JMiur  

Lui'S Y:
Eso se verá en otra entrada.

Gracias, Mariela :D

Bonzu Pipinpadaloxicopolis III:
En la siguiente entrada hay una explicación al respecto. A mi entenser, no es posible ya que si hablamos de transiciones, se requiere saber la altura del elemento y eso es variable.

Responder
Federico Terzaghi  

Muchas gracias por la info!!! como puedo hacer para que tenga algun efecto al mostrarse!!!gracias :)

te dejo el link para q veas a lo que me refiero:

http://excelparalagestion.blogspot.com/

Responder
JMiur  

Depende del tipo de efecto que busques, en general, para este tipo de contenido dinámico, se requiere de alguna Librería extra.

Responder
blasblog  

Gentilisimo Jmiur:
no sè si ya lo has tratado en otras entradas, una pregunta:
es posible insertar un gadget (tipo la nube de las etiquetas) en una pàgina estàtica de blogger?
gracias y saludos
Blas

Responder
JMiur  

Si te refieres a insertarla en la entrada misma, no. No puede hacerse porque en las entradas, sean estas de posts o páginas estáticas, no pueden usarse los códigos especiales de Blogger; estos, sólo pueden ser usados en al plantilla misma..

Responder

¿Quiere dejar un comentario?

recuerde que los comentarios están siendo moderados y serán publicados a la brevedad ...

Todos los archivos y demos alojados en Fileden han sido redireccionados y deberían estar funcionando correctamente.
De todos modos, también puede accederse a ellos a través de SkyDrive

Nota: sólo los miembros de este blog pueden publicar comentarios.

Si le gusta ir a lo seguro utilice este botón para abrir los comentarios en una ventana modal en esta misma pagina.

Si añora tiempos idos, use este enlace para agregar un comentario al viejo estilo ...

 
CERRAR