Desarrollo de Aplicaciones Web

Práctica 6: JavaScript

1. Objetivos

2. Recursos

¿Cuál es la sintaxis de JavaScript? ¿Qué palabras clave existen?

¿Cómo puedo comprobar que el código que escribo es correcto?

¿Cómo puedo esconder mi código JavaScript? No se puede, pero puedes emplear un “ofuscador” para ponérselo difícil al que quiera copiar tu código. Estas herramientas también sirven para comprimir el código JavaScript y reducir su tiempo de descarga.

¿Qué es el DOM?

3. ¿Qué tengo que hacer?

En esta práctica tienes que emplear JavaScript para validar los formularios que has realizado en las prácticas anteriores. En concreto, tienes que programar las siguientes restricciones:

Página principal
Contiene un formulario (nombre de usuario y contraseña) para acceder como usuario registrado. Antes de enviar el formulario, debes comprobar que el usuario ha escrito algo en ambos campos, pero evita que el usuario escriba únicamente espacios en blanco o tabuladores.
Página con el formulario de registro como nuevo usuario
Contiene un formulario con los datos necesarios para registrarse (nombre de usuario, contraseña, repetir contraseña, dirección de email, sexo, fecha de nacimiento, ciudad y país de residencia, foto). Antes de enviar el formulario, debes realizar las siguientes comprobaciones:

Algunas de las validaciones se pueden implementar con HTML. Por ejemplo, se puede emplear el atributo pattern para definir una expresión regular, se puede emplear type="email" para comprobar que un correo electrónico es válido, etc. Sin embargo, el objetivo de esta práctica es aprender a utilizar JavaScript, por lo que no se debe hacer uso de esas facilidades que proporciona HTML.

Por último, en la página ‘‘Solicitar álbum”, además de la tabla de tarifas que ya tenía la página, se tiene que mostrar una tabla con el coste de un álbum de fotos según los diferentes parámetros (número de páginas, número de fotos, color y resolución), tal como se puede ver en la Figura 1. Esta tabla se tiene que calcular mediante JavaScript y se tienen que aplicar las tarifas que se proporcionaron en una práctica anterior.

Importante: la tabla se tiene que crear con las funciones del DOM (Document Object Model) que permiten añadir contenido a una página web nodo a nodo. Es decir, no vale añadir el contenido como una cadena mediante innerHTML u otro mecanismo similar.


PIC


Figura 1: Tabla con posibles costes de un álbum


Importante: el código que programes debe ser eficaz, eficiente y modular.

4. ¿Cómo lo hago?

4.1. Inclusión de JavaScript en una página web

JavaScript es un lenguaje de script que comparte la misma sintaxis básica que los lenguajes de programación C, C++ y Java. El código de JavaScript se puede incluir de tres formas en una página web:

Por ejemplo, la siguiente página web contiene dos líneas de código JavaScript que se ejecutan automáticamente al cargar la página web; el atributo type de la etiqueta <script> indica el lenguaje de programación empleado en el código de script17:

<!DOCTYPE html> 
<html lang="es"> 
<head> 
<title>Prueba de JavaScript</title> 
<script type="text/javascript"> 
<!-- 
window.alert("Mensaje 1"); 
alert("Mensaje 2"); 
// --> 
</script> 
</head> 
<body> 
<p> 
Una página web sencilla. 
</p> 
</body> 
</html>

En el ejemplo anterior, el código JavaScript está encerrado en un comentario de HTML para que no sea interpretado por aquellos navegadores que no reconocen JavaScript. Además, la llamada al método alert() que muestra un cuadro de diálogo con un mensaje se realiza de dos formas equivalentes: a través del objeto window y directamente.

En JavaScript hay muchas formas de escribir un código para lograr un objetivo. Por ejemplo, el siguiente código muestra tres formas distintas de asociar una función al evento “click” de un botón:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8" /> 
<title>Prueba de click</title> 
<script> 
function funcionClick(msg) { 
      alert("El mensaje que debo mostrar es: " + msg); 
} 
 
function load() { 
      document.getElementById("boton2").onclick = function(){funcionClick("Botón 2")}; 
      document.getElementById("boton3").addEventListener("click", function(){funcionClick("Botón 3")}); 
} 
 
document.addEventListener("DOMContentLoaded", load, false); 
</script> 
</head> 
<body> 
<p> 
<input type="button" value="Con atributo onclick" id="boton1" onclick="funcionClick('Botón 1')" /> 
<br /> 
<input type="button" value="Con onclick en JS" id="boton2" /> 
<br /> 
<input type="button" value="Con addEventListener en JS" id="boton3" /> 
</p> 
</body> 
</html>

En este ejemplo se han usado las funciones anónimas de JavaScript18 para pasar información específica a la función manejadora del evento “click”. Además, se ha empleado el evento DOMContentLoaded19 para iniciar la ejecución del código JavaScript.

4.2. Validación de formularios

El DOM es una API destinada a trabajar con documentos HTML y XML. El DOM está desarrollado por el W3C.

Para realizar la validación de formularios lo más correcto es emplear expresiones regulares, pero en esta práctica no tienes que utilizar expresiones regulares. Ahora tienes que programar para cada situación el algoritmo de validación apropiado.

Existen varias formas de acceder a un formulario a través del DOM20:

Una vez que se ha seleccionado un formulario, existen varias formas de acceder a los campos que contiene (formu es un objeto que representa un formulario concreto y que ha sido seleccionado con alguno de los métodos explicados en el párrafo anterior):

Una vez que se ha seleccionado un campo, se tiene que consultar la propiedad value para obtener el valor que almacena en un instante concreto.

En el siguiente ejemplo hay un formulario que contiene tres campos de texto para escribir el nombre de tres jugadores, el formulario no se puede enviar si no se han escrito los tres nombres:

<!DOCTYPE html> 
<html lang="es"> 
<head> 
<meta charset="utf-8" /> 
<title>Validación un formulario</title> 
<script> 
function valida(f) { 
var ok = true; 
var msg = "Debes escribir algo en los campos:\n"; 
 
if(f.elements[0].value == "") 
{ 
msg += "- Jugador 1\n"; 
ok = false; 
} 
 
if(f.elements["jugador2"].value == "") 
{ 
msg += "- Jugador 2\n"; 
ok = false; 
} 
 
if(f.jugador3.value == "") 
{ 
msg += "- Jugador 3\n"; 
ok = false; 
} 
 
if(ok == false) 
alert(msg); 
 
return ok; 
} 
</script> 
</head> 
<body> 
<form id="miForm" action="" method="get" onsubmit="return valida(this)"> 
<p> 
Jugador 1: <input type="text" id="jugador1" /> 
<br /> 
Jugador 2: <input type="text" id="jugador2" /> 
<br /> 
Jugador 3: <input type="text" id="jugador3" /> 
<br /> 
<input type="submit" value="Enviar" /> 
<input type="reset" value="Borrar" /> 
</p> 
</form> 
</body> 
</html>

En el ejemplo anterior, cuando se llama a la función valida() desde el evento onsubmit se le pasa como valor del parámetro this, que es un objeto que representa al formulario desde el que se invoca al método. En este ejemplo, se ha empleado el atributo id en vez del atributo name para identificar cada elemento, la forma correcta de identificar de forma única un elemento de HTML.

La función valida() debe devolver true o false según la validación haya sido correcta o haya fallado. Este valor debe ser devuelto al navegador: el valor true significa “continúa y envía el formulario al servidor”, mientras que false significa “cancela y no envíes el formulario al servidor”. Por ello, en el código se debe escribir onsubmit="return valida(this)" para reenviar el valor devuelto al navegador.

Importante: este es el método tradicional de acceder al contenido de un formulario, aquí está explicado por razones históricas, pero no es la forma adecuada de hacerlo en la actualidad.

En DOM Level 1, publicado en octubre de 1998, se añadieron tres funciones que permiten acceder a los elementos de una página web:

Con HTML5 han aparecido nuevas funciones para manipular el DOM, pero se tienen que usar con mucho cuidado para que no se produzcan problemas de compatibilidad con navegadores web antiguos. De las nuevas funciones, las más interesantes son:

En definitiva, existen múltiples formas de acceder a un formulario y a los controles de un formulario. El siguiente código muestra 15 formas distintas de acceder al valor que contiene un cuadro de texto:

<!DOCTYPE html> 
<html lang="es"> 
<head> 
<meta charset="utf-8" /> 
<title>Diferentes modos de acceso</title> 
<script> 
function load() { 
console.log(document.forms[0].elements[0].value); 
console.log(document.forms[0].elements["usuario"].value); 
console.log(document.forms[0].usuario.value); 
 
console.log("----"); 
 
console.log(document.forms["miForm"].elements[0].value); 
console.log(document.forms["miForm"].elements["usuario"].value); 
console.log(document.forms["miForm"].usuario.value); 
 
console.log("----"); 
 
console.log(document.miForm.elements[0].value); 
console.log(document.miForm.elements["usuario"].value); 
console.log(document.miForm.usuario.value); 
 
console.log("----"); 
 
console.log(document.getElementById("usuario").value); 
console.log(document.getElementsByName("usuario")[0].value); 
console.log(document.getElementsByTagName("input")[0].value); 
console.log(document.getElementsByClassName("cuadro-texto")[0].value); 
console.log(document.querySelector("#usuario").value); 
console.log(document.querySelectorAll("input")[0].value); 
} 
 
document.addEventListener("DOMContentLoaded", load, false); 
</script> 
</head> 
<body> 
<form id="miForm" name="miForm" action="" method="get"> 
<p> 
Usuario: <input type="text" id="usuario" name="usuario" class="cuadro-texto" value="Nombre usuario" /> 
</p> 
</form> 
</body> 
</html>

En la Figura 2 se muestra la salida del código anterior por la consola de JavaScript de un navegador web.


PIC


Figura 2: Diferentes modos de acceso a los controles de un formulario


4.3. Manipulación de una página web

El DOM proporciona una representación en forma de árbol de un documento y permite su manipulación (añadir un elemento nuevo, borrar un elemento, mover un elemento de sitio). Algunas funciones útiles del DOM son:

El siguiente ejemplo muestra cómo se pueden añadir párrafos de texto nuevos a una página web con el texto que introduzca el usuario en la misma página web:

<!DOCTYPE html> 
<html lang="es"> 
<head> 
<meta charset="utf-8" /> 
<title>Validación con expresión regular</title> 
<script> 
function nuevoTexto() { 
      // Obtiene el div que tiene id="parrafos" 
      var d = document.getElementById("parrafos"); 
 
      // Crea un nuevo elemento de tipo párrafo 
      var np = document.createElement("p"); 
 
      // Inserta el texto en el contenido del nuevo párrafo 
      // textContent es un atributo (propiedad) de un nodo 
      // que representa el contenido textual 
      np.textContent = document.getElementById("texto").value; 
 
      // Añade el párrafo al final de los elementos que contenga el div 
      d.appendChild(np); 
 
      return false; 
} 
</script> 
</head> 
<body> 
<form id="miForm" action="" method="get" onsubmit="return nuevoTexto()" > 
<p> 
Texto: <input type="text" id="texto" /> 
<br /> 
<input type="submit" value="Añade texto" /> 
</p> 
</form> 
<div id="parrafos"> 
<!-- Inicialmente vacío --> 
</div> 
</body> 
</html>

5. Recomendaciones

Muy importante: en la realización de las prácticas no debes emplear un framework de JavaScript.

Cuanta mayor separación haya entre las distintas partes que componen una página web (HTML, CSS y JavaScript) mucho mejor. Por ello, el código de JavaScript escríbelo en un fichero aparte e inclúyelo en aquellas páginas donde lo necesites con la etiqueta <script src=""></script>.

En el sitio web W3Schools puedes encontrar el apartado JavaScript Form Validation26 que explica algunos tipos de validación sencilla de un formulario. Además de esta página existen muchas otras más como:

Para manipular las cadenas en JavaScript existe el objeto String. Consulta la página JavaScript String Object Reference30 en W3Schools para conocer los métodos y propiedades que posee este objeto. Algunos métodos que puedes necesitar son:

Para trabajar con fechas en JavaScript existe el objeto Date. Consulta la página JavaScript Date Object Reference31 en W3Schools para conocer los métodos y propiedades que posee este objeto. Algunos métodos que puedes necesitar son:

El objeto Date se puede emplear para validar una fecha introducida por el usuario. ¿Cómo? Utiliza la fecha introducida por el usuario para crear un objeto de tipo Date y compara la fecha introducida con los valores que devuelve el objeto.

Cuando una página contiene un error de JavaScript, los navegadores suelen informar de alguna manera al usuario. Por ejemplo, la siguiente página contiene un error, ya que el bloque de código de la función prueba() no está cerrado (falta una llave).

<!DOCTYPE html> 
<html lang="es"> 
<head> 
<title>Prueba de JavaScript</title> 
<script> 
function prueba() { 
window.alert("Mensaje 1"); 
alert("Mensaje 2"); 
 
return false; 
</script> 
</head> 
<body> 
<p> 
Un texto. Pulsa <a href="#" onclick="return prueba()">aquí</a> 
para ejecutar la función. 
</p> 
</body> 
</html>

En los navegadores actuales existe la posibilidad de consultar los mensajes de error de JavaScript a través de la consola de las herramientas para desarrolladores. En la Figura 3 se muestra el mensaje de error que muestra el navegador Google Chrome y en la Figura 4 el mensaje de error que muestra el navegador Mozilla Firefox.


PIC


Figura 3: Consola de errores en Google Chrome



PIC


Figura 4: Consola de errores en Mozilla Firefox


1http://www.w3schools.com/

2http://www.ecma-international.org/publications/standards/Ecma-262.htm

3http://developer.mozilla.org/en/JavaScript

4http://www.opera.com/docs/specs/js/ecma/

5http://www.addedbytes.com/cheat-sheets/javascript-cheat-sheet/

6http://javascript-reference.info/

7http://getfirebug.com/

8http://www.jslint.com/

9http://www.javascriptlint.com/

10http://www.c-point.com/javascript_editor.php

11http://www.virtualpromote.com/tools/javascript-encrypt/

12http://sentidoweb.com/2006/10/11/lista-de-ofuscadores-para-javascript.php

13http://www.w3.org/DOM/

14http://developer.mozilla.org/en/Gecko_DOM_Reference

15http://www.opera.com/docs/specs/js/ecma/dom/index.dml

16http://www.opera.com/docs/specs/js/ecma/dom/html/index.dml

17En HTML5 ya no es necesario utilizar el atributo type.

18https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#The_function_expression_function_expression

19https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event

20Existe alguna forma más que se empleará en la próxima práctica.

21https://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html\#method-getElementById

22https://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html\#method-getElementsByName

23https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html\#method-getElementsByTagName

24http://www.w3.org/TR/dom/

25http://www.w3.org/TR/selectors-api/

26http://www.w3schools.com/js/js_form_validation.asp

27http://www.elated.com/articles/form-validation-with-javascript/

28http://www.webcheatsheet.com/javascript/form_validation.php

29http://www.the-art-of-web.com/javascript/

30http://www.w3schools.com/jsref/jsref_obj_string.asp

31http://www.w3schools.com/jsref/jsref_obj_date.asp