miércoles, 16 de junio de 2010

Recuperando nombres de checkbox con jQuery

¿En algún momento han necesitado recuperar una lista de nombres de checkboxs que están seleccionados en una página?

Pues yo ahora me he visto en la necesidad de hacerlo y para ello he creado el siguiente script:




   1:      $(document).ready(
   2:          function()
   3:          {
   4:          //Esta funcion agrega y elimina los nombres de los checkbox al hidValores
   5:              $('*:checkbox').click(
   6:              function()
   7:              {
   8:                  var tagId = $(this)[0].id;
   9:                  var valoresActuales = document.getElementById('hidValores').value;
  10:                  if ($(this)[0].checked)
  11:                  {
  12:                      if (valoresActuales.indexOf(tagId) != -1)
  13:                      { alert('ya existe'); }
  14:                      else
  15:                      {
  16:                          alert('no Existe');
  17:                          document.getElementById('hidValores').value += tagId;
  18:                          alert('Se ha agregado');
  19:                      }
  20:                  }
  21:                  else
  22:                  {
  23:                      if (valoresActuales.indexOf(tagId) != -1)
  24:                      {
  25:                          alert('ya existe');
  26:                          valoresActuales = valoresActuales.substring(0, valoresActuales.indexOf(tagId)) +
  27:                          valoresActuales.substring(valoresActuales.indexOf(tagId)+tagId.length, valoresActuales.length);
  28:                          document.getElementById('hidValores').value =valoresActuales ;
  29:                          alert('Se ha eliminado');
  30:                      }
  31:                      else { alert('no Existe'); }
  32:                  }
  33:   
  34:              }
  35:              );
  36:          }
  37:      );
 

Obviamente, los alerts pueden eliminarse en entornos productivos, yo los usé para entorno de desarrollo y testeo.

lo que hace este script es, a todos los checkboxs de la página($('*:checkbox'))  asociarles en el evento click la función javascript que ahi se detalla, la que accede a un campo hidden en la página llamado hidValores y agrega o elimina el nombre del checkbox clicado segun corresponda.

Con este se puede, por ejemplo, en el codeBehind recuperar este hidden y extraer de él la data necesaria y llevar a cabo las tareas necesarias sin las toneladas de código javascript que serian necesarias de otro modo y sin estar complicandose por los controles checkbox creados dinamicamente.

Eso por ahora, hasta la próxima

Manuel Gatica Holtmann

miércoles, 9 de junio de 2010

Video 1 - Introducción a jQuery

Estimados

Nuevamente, bienvenidos a jotequery.

Para hacer un poco mas simple esta etapa introductoria he grabado unos videos en jing con algunas explicaciones desde la descarga de jQuery hasta como usarlo en vstudio y unos primeros ejemplos que si bien son simples puedn ser bastante ilustrativos.

Sin mas, esta es la lista de videos:





Hasta la próxima, saludos

Manuel Gatica Holtmann

martes, 1 de junio de 2010

tropiezo 2 - Trabajando con eventos



Diferencia entre onload y $(document).ready
El evento onLoad, usado en javascript se ejecuta cuando terminan de cargarse todos los elementos de la página, el evento $(document).ready se dispara cuando se ha cargado el DOM esto es cuando se carga la estructura de la página y todos los elementos de esta pueden ser accedidos por jQuery, sin que implique esto la carga total de los elementos mas pesados como los videos o las imágenes.
Consideraciones sobre el prefijo $
Pueden darse entornos donde jQuery coexista con otras librerías, como prototype, donde el símbolo $ va a generar ambigüedades, en estos casos podemos iniciar nuestros scripts jQuery con el prefijo jQuery.
Así un script $(document).ready debiese escribirse jQuery(document).ready
También podemos escribir lo siguiente
jQuery(document).ready(function($) {
// Dentro de ésta function podemos usar el símbolo $ sin problemas
});
Otros eventos
Así como javascript puede asociarse al evento onload, este también puede asociarse a otros eventos como el clic del mouse (onclic), o al redimensionamiento de la página (onresize). jQuery también puede asociarse a estos eventos.
Ejemplo con eventos
En una página nueva vamos a definir este html
<div id="switcher">
<h3>Style Switcher</h3>
<div class="button selected" id="switcher-default">
Default
</div>
<div class="button" id="switcher-narrow">
Narrow Column
</div>
<div class="button" id="switcher-large">
Large Print
</div>
</div>
Los botones incuidos en este switch los utilizaremos para redimensionar el texto de una página según lo indique cada botón.
Combinado con texto esto se vería así

 

Para empezar, vamos a incluir lo siguiente en un css referido en la página.
body.large .chapter {
font-size: 1.5em;
}
La idea es aplicar esta clase al body de la página. Por lo visto anteriormente en el script debiéramos incluir esto para seleccionar el body y agregar esta clase:
$('body').addClass('large');
Pero esto solo ha de ocurrir cuando se presione el botón que definimos en el div con este tag <div class="button" id="switcher-large">, para asociarlo usaremos este script:

 
$(document).ready(
function() {
$('#switcher-large').bind('click',
function() {
$('body').addClass('large');
});
});

 
Ahora, al dar clic sobre el botón que dice Large Print el resultado es el siguiente:

El método bind nos permite asociar cuantas funciones necesitemos a los elementos de la página en un evento determinado.
Para habilitar los 3 botones el script completo es este:

 
$(document).ready(function() {

$('#switcher-default').bind('click', function() {

$('body').removeClass('narrow');

$('body').removeClass('large');

});

$('#switcher-narrow').bind('click', function() {

$('body').addClass('narrow');

$('body').removeClass('large');

});

$('#switcher-large').bind('click', function() {

$('body').removeClass('narrow');

$('body').addClass('large');

});

});
Ahora, si presionan el botón narrow, el resultado es el siguiente:

Y si presionan el botón default la página vuelve a su estado original.
Si bien esto funciona, no estamos dando feedback respecto a que formato es el vigente. Para ello podemos destacar en negrita el texto del botón que se ha presionado y por ende está activo. Para esto, en nuestro css, agregaremos lo siguiente:
.selected {


font-weight: bold;

}


 
Ahora, al ejecutarse el clic sobre el botón podríamos asociar la clase selected a este con la siguiente línea
$(this).addClass('selected');

Y antes de eso, resetear el switcher con esta otra línea:
$('#switcher .button').removeClass('selected');
Así, todo esto junto y para los 3 botones puede quedar así:
$(document).ready(function() {

$('#switcher-default').bind('click', function() {

$('body').removeClass('narrow');

$('body').removeClass('large');

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

$('#switcher-narrow').bind('click', function() {

$('body').addClass('narrow');

$('body').removeClass('large');

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

$('#switcher-large').bind('click', function() {

$('body').removeClass('narrow');

$('body').addClass('large');

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

});
Si bien este script es funcional, es optimizable, podemos conseguir el mismo efecto con menos líneas con esta nueva versión:
$(document).ready(function() {

$('#switcher-default').bind('click', function() {

$('body').removeClass('narrow').removeClass('large');

});

$('#switcher-narrow').bind('click', function() {

$('body').addClass('narrow').removeClass('large');

});

$('#switcher-large').bind('click', function() {

$('body').removeClass('narrow').addClass('large');

});


 

$('#switcher .button').bind('click', function() {

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

});
Si bien es mejor, aún es optimizable:
$(document).ready(function() {

$('#switcher-default').bind('click', function() {

$('body').removeClass();

});

$('#switcher-narrow').bind('click', function() {

$('body').removeClass().addClass('narrow');

});

$('#switcher-large').bind('click', function() {

$('body').removeClass().addClass('large');

});


 

$('#switcher .button').bind('click', function() {

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

});
Iterando otra vez, también podemos escribirlo así:
$(document).ready(function() {

$('#switcher .button').bind('click', function() {

$('body').removeClass();

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});


 

$('#switcher-narrow').bind('click', function() {

$('body').addClass('narrow');

});

$('#switcher-large').bind('click', function() {

$('body').addClass('large');

});

});
OJO: Como este script está pensado para operar en una página completa, es posible usar removeClass de forma tan abierta. Si nuestro script estuviese inmerso en un control que formará parte de otras páginas que lo utilizaran y que tendrán su propio control gráfico, nuestro script debe limitarse a solo afectar las clases de su entorno inmediato.
Continuando con el ejemplo. Cuando en un script nos referimos a $(this) estamos refiriéndonos a this como un objeto jQuery, pero cuando lo accedemos directamente como this nos estamos refiriendo a un objeto DOM y tenemos acceso a todas sus propiedades DOM, por ejemplo, el nombre o el Id.
Aprovechándonos de esta característica, el script anterior podemos seguir factorizándolo a una versión como esta:
$(document).ready(function() {

$('#switcher .button').bind('click', function() {

$('body').removeClass();


if (this.id == 'switcher-narrow') {

$('body').addClass('narrow');

}


else
if (this.id == 'switcher-large') {

$('body').addClass('large');

}


 

$('#switcher .button').removeClass('selected');

$(this).addClass('selected');

});

});
Hay que considerar lo siguiente:


  • En la versión anterior a esta usamos 3 veces el método Bind. La primera vez lo usamos para asociar a todos los botones los comporatmientos que tenían en común(eliminar las clases de switcher, eliminar las clases de la página y asociarse a si mismos la clase selected) y las siguientes 2 veces lo usamos para asociar a los botones de narrow y large el apéndice de las clases correspondientes al body.


  • En la versión actual usamos solo una vez el método bind a nivel general para todos los botones del switcher y la única función asociada al evento clic dentro de si determina que botón la ha invocado(por medio de la propiedad DOM this.id) y según eso toma elimina y agrega esta y aquella clase.
Atajos
Algunas tareas, como el asociar una función a un clic, son tan habituales que jquery provee atajos que permiten hacer lo mismo pero escribiendo menos, así el código: $('#switcher .button').bind('click', function() puede escribirse también de este modo: $('#switcher .button').click(function()Como pueden ver, hemosa prescindido de bind y asociado directamente el método click.
Otros métodos que están disponibles son los siguientes


  • blur


  • change


  • click


  • dblclick


  • error


  • focus


  • keydown


  • keypress


  • keyup


  • load


  • mousedown


  • mousemove


  • mouseout


  • mouseover


  • mouseup


  • resize


  • scroll


  • select


  • submit


  • unload
Si bien jquery se gatilla por métodos esencialmente conocidos en javascript, maneja también algunos eventos propios como el evento .ready que ya hemos visto. Otros eventos propios de jQuery son .toggle y .hover.
A continuación usaremos el evento .toggle para mostrar u ocultar los botones del switcher de estilos.
Primero, en el css agregaremos esta clase:
.hidden {


display: none;

}
Ahora, agregaremos este script
$(document).ready(function() {

$('#switcher h3').toggle(function() {

$('#switcher .button').addClass('hidden');

}, function() {

$('#switcher .button').removeClass('hidden');

});

});
Este script hace que al momento de dar clic sobre el <h3>Style Switcher</h3> que es el h3 que está dentro de switcher al que referimos con $('#switcher h3') en el script anterior.
Toggle utiliza 2 parámetros, ambas funciones que ejecuta alternadamente cada vez que se presenta el evento. De este modo muestra o esconde los botones al agregar o quitar la clase hidden a $('#switcher .button').
Otro modo de conseguir el mismo efecto en menos líneas de código es usando toggleClass que es un toggle especializado para cambiar clases. En este script aparece como usarlo:

 
$(document).ready(function() {

$('#switcher h3').click(function() {

$('#switcher .button').toggleClass('hidden');

});

});
Como podrán deducir, lo que hace es agregar o eliminar la clase hidden indicada en .toggleClass('hidden')sobre el o los elementos identificados por $('#switcher .button')
También, es posible mostrar u ocultar este switcher según pasemos el mouse por encima de él con el siguiente script:
$(document).ready(function() {

$('#switcher').mouseleave(function() {

$('#switcher .button').addClass('hidden');

});

$('#switcher').mouseover(function() {

$('#switcher .button').removeClass('hidden');

});

});
Como puede apreciarse, se selecciona $('#switcher') y se le asocian los eventos mouseleave y mouseover, y según esto, en caso que el mouse esté sobre el switcher este se desplegará o contraerá.
Note que en este caso, el evento no está asociado al h3 com en los casos anteriores, esto porque para apretar los botones el mouse perderíamos el foco sobre h3 y se cerraría, no así si aplicamos el evento al div switcher.

Tropiezo 1 - Selección de elementos


(Parto con tropiezo 1 porque paso es mucho decir)
Por motivos laborales me he visto en la obligación de investigar jQuery.

Debo decir que los primeros dos dias fueron frustrantes y pesados. Estando acostumbrado a trabajar en c# en codebehind esta tecnología(jQuery)  se me hizo críptica, inhóspita y demasiado extensa como para abordarla hasta que afortunadamente di con el libro Learning Jquery 1.3 publicado por la gente del sitio http://www.learningjquery.com/ .

Me ha ayudado bastante para comprender la filosofia y modo de trabajo de jQuery, acá publicaré los apuntes que voy sacando de este material esperando ayudar a rellenar los vacíos que pueden quedar cuando uno comienza a buscar documentación a tientas en internet.
Entrando en materia

 Asumiendo que ya se descargaron jquery y lo tienen disponible para usar y que lo han referenciado y que saben como es un css lo básico es que podemos seleccionar cualquier elemento del DOM con la sintaxis
$(algo) , donde algo puede ser un tag, un id o una clase

Selección jerárquica
$(elementopadre > elementohijo)
selecciona todos los hijos del elemento padre.
Ejemplo:
$(‘#selected-plays > li’).addClass(‘horizontal’);
Añade la clase horizontal a todos los elementos li encontrados en los elementos de clase selected-plays.
 Filtrando la selección
$(‘#selected-plays li:not(.horizontal)’).addClass(‘subLevel’);
Este otro ejemplo selecciona aquellos li contenidos en selected-plays que no tienen la clase horizontal y les agrega la clase sublevel.
Selección por atributo
Es posible seleccionar elementos por un atributo HTML, para ello se indica el atributo en paréntesis cuadrados. Por ejemplo, para seleccionar todos los elementos img de una página que tienen definido un alt se puede hacer del modo siguiente:
$(‘img[alt]’)
Comodines
Es posible filtrar lo buscado con comodines, usando los siguientes símbolos:
^: Texto al inicio
$: Texto al final
*: Texto en cualquier parte
Esto se puede combinar con los métodos de selección vistos previamente, por ejemplo:
$(‘a[href^=mailto]’) selecciona todos los elementos que tienen href y este en su comienzo dice mailto
 

As You Like It Comedy
All's Well that Ends Well Comedy 1601
Hamlet Tragedy 1604
Macbeth Tragedy 1606
Romeo and Juliet Tragedy 1595
Henry IV, Part I History 1596
Henry V History 1599

El único problema que presenta este método es que no distingue los tr’s entre tablas, por tanto, el primer tr de la siguiente tabla tendría un fondo gris. Para evitar esto se modifica el filtro de la siguiente forma:
$(document).ready(function() {
$('tr:nth-child(even)').addClass('alt');
});
Luego, podríamos necesitar destacar algo dentro de esta tabla. Agregamos, por ejemplo,  al css la siguiente clase
.highlight {font-weight:bold; font-style: italics;}
Luego modificamos nuevamente nuestro selector de la siguiente forma:
$(document).ready(function() {
$('tr:nth-child(even)').addClass('alt');
$('td:contains(Henry)').addClass('highlight');
});
El código anterior hace lo siguiente:
1.       Aplica la clase tr del css a todos los tr
2.       A los tr impares asocia la clase alt del css
3.       A aquellos td que contienen el texto Henry, asocia la clase highlight del css

Así como se puede evaluar la paridad o imparidad de la numeración de elementos con even y odd, es posible evaluar la igualdad con eq
El resultado sería este:

Si en lugar de destacar la columna del título para aquellos tr que tienen un td con el texto Henry, quisiéramos destacar  la segunda columna, podríamos usar el siguiente comando:
$(document).ready(function() {
$('td:contains(Henry)').next().addClass('highlight');
});
.next() le indica que debe seleccionar el siguiente elemento del mismo tipo y en este caso a este aplicar la clase highlight.
Así el resultado es el siguiente:

Así como tenemos .next(),  existen otros selectores para elementos del mismo tipo, son estos:
.next()                 : El elemento del mismo tipo a este nivel siguiente a este.
.nextAll()            : Todos los elementos del mismo tipo a este nivel siguientes a este.
.prev()                  : El elemento del mismo tipo a este nivel previo a este.
.prevAll()            : Todos los elementos del mismo tipo a este nivel previos a este
.siblings()           : Todos los elementos del mismo tipo a este nivel
.andSelf()           : El elemento en si
.parent()             : El elemento que contiene al elemento actual
.children()          : los elementos contenidos en el elemento actual
Selectores FORM
Cuando se trabaja con forms es posible acceder a sus elementos con esta sintaxis
$(‘:elementoForm’), donde :elementoForm puede ser un :text, :checkbox o cualquiera de los descritos en la siguiente imagen: 

Combinando estos selectores podemos, por ejemplo, hacer lo siguiente:
$(':radio:checked')

Esto es, seleccionar los elementos form de tipo radio que están checkeados.

Acceder a una propiedad de un elemento del dom
var myTag = $('#my-element')[0].tagName;
En este caso, en myTag estamos almacenando el tagName de $('#my-element')[0]
Con [0] estamos seleccionando el primer elemento de la colección $('#my-element'), si hemos entregado un nombre univoco entonces siempre nuestra colección será de cardinalidad no mayor a 1, por tanto no existiría un $('#my-element')[n] con n>0