jQueryNumeric: Fuerza al usuario a introducir sólo números.

Llevo unos días sin escribir nada por aquí, cierto es. Me alegra ver que por otra parte el número de lecturas no decae. Hoy he decidido hacerme un hueco en la hora de comer para comentar este plugin de jQuery. Lo podéis descargar de aquí e incorporarlo libremente a vuestros proyectos, junto al framework jQuery, indispensable para su funcionamiento.

Una vez insertado sólo tenéis que utilizar el método numeric() sobre los campos de usuario que queráis que no acepten números. Este primer ejemplo muestra su funcionamiento para permitir sólo la entrada de enteros:

$("#input").numeric();

¿Y para floats? (es decir, números reales)… pues metiende una cadena con el separador como parámetro (en el ejemplo una coma, por mantener el formato latino):

$("#input").numeric(",");

Ojo, esto bloquea el teclado sobre el campo del formulario. Es decir, si os hacen la gracia de copiar y pegar algo sí lo tragará, así que una expresión regular para comprobar el formato, como la del ejemplo, no estaría mal. Por aquello de evitar fallos en el envío del formulario:

/[0-9\.,]+/.test()

Y con esto, liquidamos el consejo javascript del día.

Datepicker fácil en tu web

¿Necesitas un «datepicker»? Con esto quiero decir necesitas introducir un calendario en un formulario web, a día de hoy hay muchos sencillos métodos para hacerlo. Pero estas son las dos más fáciles:

  • Campo date en HTML5: Un campo del formulario definido como de tipo date ya te arregla en gran parte el problema. Tiene el handicap de que cada navegador te saca el calendario con el formato que le da la gana
    <input type="date"/>
  • Calendario datepicker con jQueryUI: Esta opción incluye más opciones de personalización. Lo primero es descargar la librería jQuery y lo siguiente bajar los componentes de jQueryUI necesarios, incluyendo sus estilos. Luego para implantarlo debes cargar las dos librerías en la cabecera del documento, usar un campo input normal (en el ejemplo se llamará #calendario) y un script como el siguiente:
    <script>
    	$(function() {
    		$( "#calendario" ).datepicker({
    			changeMonth: true,
    			changeYear: true
    		});
    	});
    	</script>
    
    <div class="ejemplo">
    
    <p>Date: <input type="text" id="calendario"></p>
    
    </div>
    

En fin, para el caso del jQueryUI tienes muchos más ejemplos en la propia página con las distintas opciones.

Creando un menú de navegación con jQueryMobile

Crear un menú de navegación con jQueryMobile, adaptando la web para una mayor usabiliad en dispositivos móviles, no es complicado.

El primer paso consiste en declarar el atributo data-role del div como navbar. Dentro de este metemos una lista desordenada (ul) y en cada elemento (li) de la misma añadimos un enlace, apuntando a la página a la que tiene que ir. A los enlaces no hay que definirles data-role.

Para cambiar el color de los botones usaremos el atributo data-theme (en el ejemplo data-theme=b para ponerlos de color azul), si no lo hacemos serán del mismo color que la cabecera. Una de las ventajas de jQueryMobile es que definiendo la clase ui-btn-active se un estilo más claro al botón seleccionado, sin que tengamos que currarnos un CSS para ello.

Recuerda también definir el data-icon para que el botón quede más bonito.

<header data-role="header"> 
    <h1>SJV Town Hall</h1>
    <div data-role="navbar">
        <ul>
             <li>
                 <a href="#inicio" class="ui-btn-active" data-icon="home" data-theme="b">Inicio</a>
             </li>

             <li>
                 <a href="#favourites" data-icon="star" data-theme="b">Favoritos</a>
             </li>

             <li>
                 <a href="#contactos data-icon="grid" data-theme="b">Contactos</a>
             </li>
         </ul>
       </div>
</header>

En el ejemplo puedes ver un poco de todo lo que hemos comentado arriba.

Listas en jQueryMobile: ordenadas y desordenadas

A la hora de trabajar tanto con listas ordenadas o listas desordenadas con jQueryMobile no hay mucha ciencia, es como trabajar con listas en html clásico.

Mayormente hay que usar la etiqueta ul para listas desordenadas y ol para ordenadas, como en cualquier página. La única diferencia es añadir el atributo data-role=»listview». Esto es lo único que necesitas en jQueryMobile para aplicar el estilo «móvil» a la lista. Te pongo un ejemplillo


<ol data-role="listview" data-inset="true" data-filter="true">
   <li><a href="#">El Resplandor</a></li>
   <li><a href="#">La Naranja Mecánica</a></li>
   <li><a href="#">Barry Lyndon</a></li>
   <li><a href="#">La Chaqueta Metálica</a></li>
</ol>

<ul data-role="listview" data-inset="true">
   <li><a href="#">Gran Torino</a></li>
   <li><a href="#">Mystic River</a></li>
   <li><a href="#">Million Dollar Baby</a></li>
   <li><a href="#">Sin Perdón</a></li>
</ul>

Sep, la lista ordenada son películas de Kubrick y la sin índices son de Clint Eastwood. Y no hay más que hablar, sólo el atributo data-role=»listview», por el resto HTML de toda la vida.

Menú desplegable con jQuery

Write less, es la idea de jQuery. Usando este framework para Javascript puedes lograr resultados vistosos y mejorar la usabilidad de tu web. En este caso vamos a hacer un menú desplegable usando jQuery, que se abra cuando lo «sobrevolemos» con el ratón. Mi primera experiencia con menús desplegables fue en una empresa (no diré cual, no queda bien hablar mal de los jefes) que querían un menú desplegable en la página (era un menú de sólo dos opciones, por lo que no le veía mucho sentido a hacerlo así, pero eran paranoias del jefe).

Lo primero es descargar jQuery desde su página oficial e incluirlo en la cabecera de la página. Luego insertar el marcado html del menú tal que así:

        <ul class="dropdown">  
            <li class="active">Listado: <span>Ejemplos</span></li>  
            <li class="first"><a href="#">Ej 1</a></li>  
            <li><a href="#">Ej 2</a></li>  
            <li><a href="#">Ej 3</a></li>  
            <li class="last"><a href="#">Ej...</a></li>  
        </ul>  

En fin, lo siguiente son los estilos del menú, el css. En el marcado ya dimos a la lista la clase dropdown, lo que nos simplificará mucho ahora el aplicar estilos en el css.

  
ul.dropdown{  
    width: 250px;  
    border: 1px double #000;  
    border-radius: 5px;  
    -moz-border-radius: 5px;  
    -webkit-border-radius: 5px;  
    background: #1a1a1a;  
    margin-top: 2em;  
}  
ul.dropdown li{  
    display: none;  
    font-size: 12px;  
}  
ul.dropdown li.active{  
    display: block;  
    color: #8c8c8c;  
    font-size: 14px;  
    padding: 12px;  
    color: #555;  
    border-top: 1px solid #313131;  
    border-radius: 4px;  
    -moz-border-radius: 4px;  
    -webkit-border-radius: 4px;  
}  
ul.dropdown li.active span{  
    padding-right: 24px;  
    color: #8c8c8c;  
}  
ul.dropdown li a{  
    display: block;  
    text-decoration: none;  
    padding: 8px 8px 8px 10px;  
    background: #1e1e1e;  
    border-bottom: 1px solid #171717;  
}  
ul.dropdown li.last a{  
    border:0;  
}  
ul.dropdown li.first a{  
    border-top: 3px solid #131313;  
}  
ul.dropdown li a:hover{  
    background: #232323;  
    color: #fff;  
    padding-left: 11px;  
}  

Marcado listo, estilos listos. Falta sólo la funcionalidad, el código javascript que haga furrular todo esto. De momento toda la lista está oculta menos el elemento de la clase active, por lo que tenemos que hacer que se muestre el resto cuando pasemos el ratón por encima, desaparezca cuando lo saquemos y además sea un código reutilizable. Aquí tenemos el procedimiento:


//variable global para almacenar el menú 
var menu = $("ul.dropdown");  
  
//captura de eventos  
$(this.document).ready(function(){  
    menu.mouseover(function(){  
        mostrar($(this).find("li"));  
    });  
    menu.mouseout(function(){  
        ocultar($(this));  
    });  
})  
  
//función que muestra los elementos del menú  
function mostrar(e){  
    e.show();  
}  
//función que los oculta
function ocultar(e){  
    e.find("li").hide();  
    e.find("li.active").show();  
}  

Y con esto ya tienes un menú desplegable chulo chulo que poner en tu web.

Iniciación a jQueryMobile: Maquetando web para móviles con HTML5

A la hora de programar webs para móvil el framework de javascript jQueryMobile, basado en jQuery, nos ofrece una gran productividad, simplificando profundamente las cuestiones de maquetación. Si ya conoces jQuery y jQueryUI la curva de aprendizaje será muy pequeña.

Este framework es compatible con todos los navegadores y sistemas operativos móviles actuales, es ligero (20kb), casi no utiliza imágenes, se puede combinar con PhoneGAP para realizar aplicaciones nativas y es libre y gratuito.

A la hora de crear la estructura, como en cualquier web, lo primero es empezar por la cabecera (la etiqueta HEAD). Ahí agregamos las referencias necesarias a jQuery, jQuery Mobile y el theme básico de CSS. Para definir el ancho de pantalla utilizamos meta viewport, lo dejaremos definido con la constante width=device-width y la escala mínima y máxima a 1; initial-scale=1.0 maximum-scale=1.0.

Una vez que hemos terminado de referenciar las librerías necesarias, creamos la estructura de la plantilla principal de la página utilizando HTML5, y luego definimos las areas de contenido (content region) que proporciona jQueryMobile. El atributo data-role nos permitirá maquetar con comodidad y estructurar la página. Especificaremos la página (data-role=”page”), el encabezado (data-role=”header”), el contenido (data-role=”content”) y el pié (data-role=”footer”). Estos data-role los utiliza jQueryMobile para en Widgets funcionales y con los estilos del theme utilizado las secciones definidas.

Creo que lo mejor es un ejemplo que ilustre lo comentado:

<!DOCTYPE html>
<html>
<head>
    <title>Página prueba</title>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css" />
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js"></script>
</head>
<body> 
 
<!-- Página principal -->
<section data-role="page" data-title="Página de inicio">
 
    <header data-role="header">
        <h1>HW</h1>
    </header>
    <!-- end header -->
 
    <section data-role="content">
        <p>Hello world!</p>
    </section>
    <!-- end content -->
 
    <footer data-role="footer">
        <p>DonnieRock 2012</p>
    </footer>
    <!-- end footer -->  
 
</section>
<!-- end page -->
 
</body>
</html>

Pero el verdadero cambio respecto a la programación web tradicional es el concepto «page within page». Dentro del mismo documento están incrustadas todas las páginas. De ahí que en el ejemplo de arriba utilizaramos el atributo data-role=page, porque tendremos que definir varias páginas, que se diferenciarán entre ellas por su atributo id, que será obligatorio para poder navegar entre ellas.

La navegación entre distintas páginas de un mismo documento es bastante sencilla, tenemos que poner en el ‘href’ del enlace el ‘id’ de la página destino y ya está. Podemos especificar el tipo de transición con el atributo data-transition, la transición por defecto es slide pero existen varias que puedes consultar en la página de jQuery. También podemos definir la dirección de la transición con el atributo data-direction.

Recuperaré el código del primer ejemplo, con alguna modificacación, para explicar esto:

<!DOCTYPE html>
<html>
<head>
    <title>Página prueba</title>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.css" />
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.1.0-rc.1/jquery.mobile-1.1.0-rc.1.min.js"></script>
</head>
<body> 
 
<!-- Página principal -->
<section data-role="page" id="page1" data-title="Página de inicio">
 
    <header data-role="header">
        <h1>HW</h1>
    </header>
    <!-- end header -->
 
    <section data-role="content">
        <p>Hello world!</p>
    </section>
    <!-- end content -->

    <footer data-role="footer">
        <p>
            DonnieRock 2012 
           <a href="#page2" data-role="button" data-transition="slidedown">Ir a la página 2</a>
        </p>
    </footer>
    <!-- end footer -->  
 
</section>
<!-- end page 1-->

<!-- Segunda página -->
<section data-role="page" id="page2" data-title="Página 2">
 
    <header data-role="header">
        <h1>HW2</h1>
    </header>
    <!-- end header -->
 
    <section data-role="content">
        <p>Hello, again, world!</p>
    </section>
    <!-- end content -->
 
    <footer data-role="footer">
        <p>
            DonnieRock 2012 
           <a href="#page1" data-role="button" data-transition="slidedown" data-direction="reverse">Ir a la página 1</a>
        </p>
    </footer>
    <!-- end footer -->  
 
</section>
<!-- end page 2-->
 
</body>
</html>

Finalmente nos queda por elegir el «theme». Podemos crearlo fácilmente con el ThemeRoller que hay en la web de jQueryMobile, con multitud de themes que podemos crear y asignar a cada componente que usemos en nuestra aplicación. También hay themes ya predefinidos, si no queremos rompernos la cabeza. Los themes son diferenciados por una letra identificativa, gracias a la cual podemos identificar el theme y aplicarlo a cualquier componente que queramos, usando el atributo data-theme. Tienes información sobre los distintos themes en la página de jQueryMobile. El theme además puede ser modificado con facilidad tocando los archivos css.

<section data-role="page" id="page1" data-title="Página de inicio" data-theme="b">
 
    <header data-role="header">
        <h1>HW</h1>
    </header>
    <!-- end header -->
 
    <section data-role="content">
        <p>Hello world!</p>
    </section>
    <!-- end content -->

    <footer data-role="footer">
        <p>
            DonnieRock 2012 
           <a href="#page2" data-role="button" data-transition="slidedown">Ir a la página 2</a>
        </p>
    </footer>
    <!-- end footer -->  
 
</section>

Bueno, espero con esto ya tienes unas nociones básicas de cómo empezar. Más adelante tocaré otros temas, como los formularios o la integración con PhoneGAP, de momento podéis ir ojeando esto.

Ventanas modales con jQueryUI

Como soy masoquista, tras un duro día desarrollando en PHP/Javascript creo que voy a hacer una entrada sobre informática en mi blog… por seguir esta racha.

Hoy he tenido mi primera experiencia con jQueryUI, una biblioteca para el framework jQuery. Lo he utilizado para crear un formulario de correo en una ventana modal y… oye, qué fácil, qué productividad reporta esta librería. En este enlace tenéis a vuestra disposición dicha librería, con muchas demos y documentación.

Para el caso de las ventanas modales tendremos que recurrir al widget «dialog», que nos permitirá hacer desde una suerte de alert más sofisticado hasta introducir todo un formulario (como era mi caso).

El uso de dialog() puede resumirse con facilidad en el siguiente ejemplo:

<html>
    <head>
        <link rel="stylesheet" href="css/darkness/jquery-ui-1.8.18.custom.css">
        <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
        <script type="text/javascript" src="js/jquery-ui-1.8.18.custom.min.js"></script>
        <script>
            $(function(){
                $("#ventanaModal").dialog({
                   title:"Título a elegir",
                   modal: true
                });
            })
        </script>
    </head>
    <body>
        <div id="ventanaModal"></div>
            <p>Aquí metes lo que quieras</p>
        </div>
    </body>
</html>

Con esto tenéis lo mínimo para tener una ventana modal: un div con el contenido al que aplicáis el método dialog pasándole como parámetros el título y el parámetro modal como true (si no le pasárais modal: true se abriría también, pero no bloquería los elementos del fondo, como debe hacer una ventana modal). Pero esto queda muy soso, así que vamos a ir haciendo cosillas.

Lo primero es meter algo más de contenido, para que veas las posibilidades. Por ejemplo, una pregunta que requiera confirmación (como en un window.confirm de los de antaño):

<div id="ventanaModal">
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
    ¿Acepta usted las condiciones de uso y que le espiemos impunemente?
</div>

Ahora ya tenemos un aviso de seguridad, vamos con lo siguiente, meterle algún efectillo a la página para que quede chulo cuando se despliega en pantalla:

               $("#ventanaModal").dialog({
                   title:"Título a elegir",
                   modal: true,
                   show: "slide",
                   hide: "explode"
                });

Con esto aparecerá deslizándose y desaparecerá explotando en mil pedazos (bueno, realmente en nueve pedazos). En cualquier caso te habrás fijado en que no hay botones dentro del div. ¿Por qué? Porque los creó la desde javascript definiendo la propiedad buttons, que recibe como parámetro un objeto json con la información y con su función:

           buttons: {
            "Sí": function(){
                alert("has aceptado, tu alma es nuestra");
            },

            "No": function(){
                alert("no has aceptado, te jodes y te quedas sin servicio");
            }
        }

Como resumen entonces el javascript completo quedaría tal que así:

$("#ventanaModal").dialog({
   title:"Título a elegir",
   modal: true,
   show: "slide",
   hide: "explode",
   buttons: {
            "Sí": function(){
                alert("has aceptado, tu alma es nuestra");
            },

            "No": function(){
                alert("no has aceptado, te jodes y te quedas sin servicio");
            }
        }
});

En este caso son dos alerts chorras, pero sirve para que te hagas una idea del potencial que tiene este widget si ya has trabajado antes con javascript.

Nos queda añadir un botón, mismamente, en el html que llame a la ventana y la abra (es decir, el botón en el marcado y el script con la acción). Algo tipo:

<input type="button" name="accept" id="accept" value="Aceptar"/>
<script>
    $("#accept").button().click(function() {
	$("#ventanaModal").dialog("open");
    });
</script>

Y con esto y un bizcocho… se acabó el ejemplo. Ahora te recomiendo que te pelees un rato con esta librería, porque parece que puede dar muchas alegrías.

Introduciendo Prototype // Combinar jQuery con Prototype

Aunque me había planteado llevar mi debate de Twitter con mi colega Jumnper sobre el «Rock the Rebel, Metal the Devil» de Volbeat a este blog (a él le encanta, a mi me recuerda terriblemente al Load de Metallica), creo que mejor seguiré un poco más con entradas centradas en informática, por «comercialidad» porque son las más leídas (curiosamente tengo un montón de visitas desde México en este tipo de entradas)

Más de una vez he hablado de jQuery aquí, un gran facebook que nos da gran productividad en javascript, pero que no es la única opción. Prototype desde un primer momento ha protagonizado una encarnizada batalla con jQuery por la corona de «framework más usado». Podéis descargarlo en este enlace para trastear con él.

Al igual que en jQuery existe una función $, que en Prototype nos permite seleccionar los elementos por su ID. Dirás «en jQuery es mejor porque permite cualquier selector CSS», cierto, pero también existe una función para eso, que es $$

Otros métodos intersantes son $F, que accede al valor de un campo de un formulario, $A, que convierte listas de nodos o colecciones HTML en arrays, $H, que permite crear arrays asociativos o $R, que permite crear rangos de valores.

A la hora de trabajar con cadenas tenemos el método escapeHTML(), que permite transformar los caracteres problemáticos en su entidad HTML. También puedes usar toArray(), que convierte la cadena en un array de caracteres, y dispones de camelize(), que convierte una cadena separada por guiones a notación CamelCase.

Los métodos .show() y .hide() son lo que parecen ser, ocultan o muestran el elemento seleccionado (como sus homónimas en jQuery). En cambio .toogle() lo que hace es cambiar el estado entre show y hide dependiendo de en cual esté el elemento.

En cuanto a métodos para campos de formulario lo más interesante me parece .clear(), que vacía el valor de un campo, y .present(), que es cojonudo para validar campos, dado que devuelve false si el campo está vacío. Y si aplicas .disable() a un formulario lograrás desactivar todos sus campos.

Pero es con Ajax con lo que Prototype realmente te facilita la vida. Tienes Ajax.Updater(), que recibe tres parámetros: el ID del elemento a recargar por ajax, la página php que generará el código y varias opciones, y con Ajax.PeriodicalUpdater sólo tendréis que pasarle el parámetro frecuency seguido de un número ({frecuency:30}) para que realice una recarga automática por cada intervalo de ese número de segundos.

Y trabajando con DOM tampoco os dejará tirados este framework. El método .insert(), por ejemplo, os dejará elegir si queréis ponerlo detrás de, delante de, antes o encima de, y después o debajo de un elemento en concreto.

¿Mejor jQuery o Prototype? Bueno, cada uno tiene sus debilidades y sus potenciales. Yo uso más jQuery, por conocerlo mejor, pero incluso los podéis usar a la vez. Pero cuidado, tenéis que hacer un apañito antes para evitar conflictos, dado que ambos tienen un método $. La forma de evitar el conflicto es usando el método .noConflict() como en el ejemplo:

var $jQ = jQuery.noConflict();

A partir de ese momento la abreviatura de jQuery (que por defecto es $) pasar a ser la que tú has definido en la variable (en este caso $jQ), permitiéndote usar ambos frameworks sin conflicto entre ellos.

De todas formas, no suele ser práctico utilizar dos frameworks, aunque evites los conflictos siempre estás metiendo más carga a la web (aunque por otra parte, pesan bastante más muchas imágenes que los archivos .js de estos frameworks).