viernes, 12 de noviembre de 2010

Saca tus scripts de tu código HTML

Buenas! En el post anterior os comenté el soporte de Unobtrusive Ajax en ASP.NET MVC3. Hoy quiero mostraros que esa técnica ni es exclusiva de MVC3, ni  requiere HTML5 para nada. En fin, que podéis empezar a usarla ya, con independencia de la tecnología que uséis. Lo que contaré en este artículo no es nada “revolucionario” ni una “técnica nueva”…

De hecho, el ejemplo va a ser una página HTML, nada de ASP.NET :)

Veamos, la técnica de Unobtrusive Javascript, se refiere a no tener mezclado código javascript con código de marcado HTML. Es decir, no queremos algo como:

<input type="text" id="txtName" onkeypress="checkKey();" />





Aquí estamos mezclando código HTML con el código javascript (la llamada checkKey en el onkeypress).



Imaginemos que queremos que nuestros textboxes sólo acepten números. Y recordad que el objetivo es no tener código javascript mezclado con nuestro código HTML.



Eso lo podemos conseguir fácilmente, ya con jQuery:




<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Demo Unobtrusive Javascript</title>
<script src="jquery-1.4.1.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function () {
$('input:text').keypress(function (event) {
if (event.keyCode < 47 || event.keyCode > 58) {
event.preventDefault();
}
});
});
</script>

Introduce sólo números: <br />
<input type="text" />
</body>
</html>





Incluso, si no queréis que haya el tag <script> con todo el código, podemos moverlo a un .js separado y usarlo desde nuestra página HTML que entonces quedaría como:




<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Demo Unobtrusive Javascript</title>
<script src="jquery-1.4.1.js" type="text/javascript"></script>
<script src="myscript.js" type="text/javascript"></script>
</head>
<body>
Introduce sólo números: <br />
<input type="text" />
</body>
</html>





Por lo tanto vemos que con jQuery es muy fácil asignar comportamiento a objetos DOM, sin necesidad de andar con los handlers onXXXX.



Ahora bien, el código jQuery selecciona todos los <input type=”text”>, que passa si sólo quiero seleccionar algunos? Como le indico a mi código jQuery que sólo algunos textboxes son numéricos?



Una solución es invertarnos un atributo que indique que elementos queremos como numéricos. De esta manera p.ej. la página HTML queda como:




<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Demo Unobtrusive Javascript</title>
<script src="jquery-1.4.1.js" type="text/javascript"></script>
<script src="myscript.js" type="text/javascript"></script>
</head>
<body>
Introduce sólo números: <br />
<input type="text" datatype="numeric" /> <br />
Aquí puedes introducir lo que quieras: <br />
<input type="text" />
</body>
</html>





Fijaos en el “datatype=”numeric” que es el atributo que me va a servir para decidir que textboxes son numéricos.



Y el código de myscript.js queda como:




$(document).ready(function () {
$('input[datatype=numeric]').keypress(function (event) {
if (event.keyCode < 47 || event.keyCode > 58) {
event.preventDefault();
}
});
});





Y listos, simplemente incluyendo “myscript.js” en cualquier página ya podemos declarar que un textbox es numérico simplemente poniendo el atributo datatype=”numeric”.



Ahora, si alguien hace otra librería javascript para textboxes numéricos si también usa este atributo para indicarlos (ahí está el quid de la cuestión) simplemente cambiando el <script> para que en lugar de ir a myscript.js vaya a la nueva librería, ya tengo todo el cambio hecho… es decir, me he independizado del framework javascript que use.



Y por ahí por donde entra HTML5? Pues bien, como eso de crearnos nuestros propios atributos está bien pero genera HTML que podríamos llamar inválido (en el sentido de que estos atributos no forman parte de HTML), para HTML5 han decidido simplemente que todos estos atributos “inventados” empiecen por data-.



Lo “único” que dice al respecto HTML5 es: “Hey, si tienes que invertarte un atributo para lo que sea, haz que su nombre empiece por data-. Todos los atributos que empiecen por data- son atributos inventados por alquien y deben ser ignorados a todos los efectos (salvo para quien lo haya inventado que hará con él lo que le plazca, claro). Ok, también añade una API específica (element.dataset) para leer esos atributos (pero eso de momento no nos importa ya que no está soportada por la mayoría de navegadores).



Por lo tanto, si en lugar de que mi atributo se llame datatype, hago que le llame data-datatype (p.ej. cualquier nombre que empiece por data-) ya lo tengo todo HTML5 compliant!



De hecho podéis hacer la prueba en http://validator.w3.org/check. Entráis el código HTML de la página y lo validáis contra:




  • HTML5 usando el atributo datatype=”numeric” y os dará error (Attribute not allowed)


  • HTML5 usando el atributo data-datatype=”numeric” y os validará correctamente.


  • Cualquier otra versión de HTML y os dará error en ambos casos.



Y listos! Por lo tanto fijaos que desde ya podeis empezar a aplicar técnicas de “Unobtrusive Javascript”: no necesitáis HTML5 para nada, ni MVC3 ni nada y la recompensa es un HTML mucho más claro y sencillo de ver!



Mi opinión es que, gracias a que HTML5 ha definido un espacio de nombres (data-) para los atrbutos inventados empezaremos a ver, cada ves más, librerías de javascript que usarán esos atributos, y seguramente algunos de ellos terminarán siendo estándares de facto (si yo hago una librería de javascript para validación. pues intentaré usar los mismos atributos data- que use la librería que sea líder en aquel momento, para compatibilizarme con ella).



Por cierto, si vais a usar muchos atributos data- en vuestras páginas web, echadle un vistazo a este plugin de jQuery: HTML5 Dataset.



Un saludo!



Nota: El código de ese artículo lo he probado con IE9 y Firefox 3.6.10.



PD: Esto es un crosspost de mi blog en geeks.ms (como no…)

No hay comentarios: