Diseño Web/Retos Javascript

De Wikiversidad


See also: Project Euler

¿Estás listo para los retos de Javascript? Estos retos pretenden mejorar tus habilidades de Javascript con actividades prácticas que pueden resultar útiles de forma inmediata para tus propios sitios web.

Asegúrate de que estás familiarizado con los objetos window y document en Javascript antes de abordar estos retos.

Reto 1: Elementos que se esconden[editar]

Pega el siguiente código en un documento HTML nuevo y cárgalo en el navegador.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="es">
  <head>
    <title>Retos JavaScript</title>
  </head>
  <body>
    <form action="">
      <fieldset>

        <legend>Suscripciones de correo</legend>

        <p id="subscribepara">
          <label>
            <input type="checkbox" name="subscribe" id="subscribe">
            Me gustaría recibir el boletín vía correo-e.
          </label>
        </p>

        <p id="emailpara">
          <label>
            Email:
            <input type="text" name="email" id="email">
          </label>
        </p>

      </fieldset>
    </form>
  </body>
</html>

El objeto de este reto es mostrar el párrafo con el campo para el e-mail cuando la caja de selección (checkbox) esté activada, pero lo dividiremos en tareas más pequeñas.


Paso 1: Ocultar el campo de e-mail de forma predeterminada

Agrega algún estilo CSS de manera que el párrafo "emailpara" no se muestre cuando la página se cargue por primera vez (usando la propiedad CSS 'display'). Prueba que funcione.

Paso 2: Agregar una plantilla de función

Crea una nueva función llamada alternaEmail() que muestre una alerta, esto es window.alert("Mi función ha sido llamada");

Agrega un evento de manera que cuando se haga click sobre la caja de selección, la función se active. Prueba que funcione.

¡Cambié algo y todo dejó de funcionar! (o: Depuración)

En HTML y CSS un simple error podría causar que una etiqueta o un color no se muestre, pero generalmente algo aparecerá en la pantalla. Javascript es diferente en que tan pronto como encuentre un error, se detendrá y no dará ninguna pista de por qué.

Casi todos los navegadores tienen una ventana que muestra los errores Javascript con pistas para corregirlos, pero estas ventanas están escondidas de manera predeterminada. Aquí tienes cómo encontrarlas:

  • Firefox: menú Herramientas menú, Consola de errores.
  • Safari: menú Desarrollo, Consola de errores. (Tendrás que activar el menú desde el panel Avanzado de las Preferencias)
  • Opera: menú Herramientas, Avanzado, Consola de errores.
  • Chrome: click the Page button, Developer, JS Console, then the second button at the bottom left of the window.
  • IE8: menú Herramientas, Herramientas de desarrollo, Consola.

Además, podrías emplear herramientas como Firebug para Firefox, o Dragonfly para Opera.

Paso 3: Muestra los campos de e-mail

Ahora reemplazaremos el código alert() de manera que nuestra función haga algo útil. Usando Javascript podemos cambiar el estilo de cualquier elemento de nuestra página usando el objeto style. Todo elemento tiene un objeto style y podemos tener acceso a él de la siguiente manera:

  document.getElementById("subscribepara").style.backgroundColor = "blue";

De manera breve, la instrucción JavaScript que acabamos de escribir dice:

  1. Obtén el elemento de mi documento que tiene el id de "subscribepara",
  2. Obtén su objeto style,
  3. y asigna al valor "blue" a la propiedad backgroundColor de este objeto.


Unas palabras sobre los puntos Verás mucho código JavaScript escrito con puntos que separan objetos, funciones y propiedades. Cuando un nombre de función o de variable siga inmediatamente un punto, significa que pertenece a u opera sobre el objeto justo antes del punto. Por ejemplo, la función getElementById() pertenece y opera sobre el objeto document (en particular, getElementById() busca a través del documento por un elemento con un atributo id específico).

Cuando leas líneas como esta, puede ser muy útil leerlo en sentido inverso a partir del último punto, diciendo 'pertenece a' entre cada punto. Por ejemplo:

El background-color que pertenece al style, que pertenece al elemento con el ID subscribepara, que pertenece al document.

Intenta copiar y pegar el código de arriba en tu función y ve lo que hace. Fíjate en que los nombre de las propiedades de style son ligeramente diferentes de las que usamos en CSS (backgroundColor vs. background-color).

Ahora veamos si puedes modificar tu función de manera que muestre el párrafo "emailpara" cuando se ejecute.


Paso 4: Haciendo que el campo de e-mail alterne

Cuando pruebes tu código verás que puedes hacer click sobre la caja de selección y que el campo de e-mail se muestra, pero cuando desactivas la caja el párrafo no desaparece.

Nuestro reto es agregar una instrucción if a nuestra función alternaEmail() de manera que verifique si la caja de selección está activa. Si lo está entonces debe mostrar el párrafo "emailpara", de otra manera debe ocultarlo.

Para hacer esto necesitamos saber cómo revisar si una caja de selección está activada... Por suerte para nosotros, el elemento que corresponde a la caja de selección tiene una propiedad llamada 'checked' que puede tener como valor true o false. De esta manera podemos usar document.getElementById("id-del-elemento-input").checked para revisar el valor de la caja de selección.


Paso 5: Cuando Javascript está desactivado

Por el momento si un usuario ve la página con CSS activado, pero Javascript desactivado, nunca verá el campo de e-mail. Quita, entonces el CSS que esconde el campo y reemplázalo con Javascript que esconda el párrafo cuando se active el evento onload de la página.

Puedes echarle un ojo a las instrucciones if que utilizaste un poco antes para saber cómo puedes completar este reto. Cuando lo tengas funcionando, exclama "JavaScript es super cool" y toma un descanso.


Reto 2: 'La misma de arriba': direcciones postales[editar]

Agrega el siguiente fieldset a una forma (la que creaste en el Reto 1 sirve bien) y cárgala en el navegador:

<fieldset>

  <legend>Información de cobro</legend>

  <p>
    <label>
      Dirección postal:<br />
    <textarea name="postaladdress" id="postaladdress"></textarea>
    </label>
  </p>
  
  <p>
    Dirección personal:<br />
    <label>
       <input type="checkbox" name="homepostalcheck" id="homepostalcheck">
       La misma de arriba
    </label>
    <br />
    <textarea name="homeaddress" id="homeaddress"></textarea>
  </p>

</fieldset>

La meta de este reto es copiar automáticamente la dirección postal a la dirección personal si un usuario activa la opción "La misma de arriba". Además de esto, desactivaremos el campo de la dirección personal cuando se active la caja de selección.


Paso 1: Agregar una plantilla de función

Agrega una función JavaScript a tu página que se llame ponDireccionPostal que simplemente muestre una alerta, esto es: window.alert("Mi función ha sido llamada");

Agrega un evento de manera que cuando la caja de selección sea activada tu funcionse ejecute y prueba que funciona.


Paso 2: Obteniendo la dirección postal

Antes de que podamos copiar la dirección, necesitamos saber cómo leerla usando JavaScript. En el reto 1 usamos la propiedad .checked para comprobar si una caja de selección estaba activada; esta propiedad contenía como valor ya sea true o false. Si escribimos texto dentro de una <textarea> entonces la propiedad .checked no nos servirá de mucho.

En lugar de esto, usaremos la propiedad .value de textarea. Esta propiedad contiene el texto escrito en ese campo. En tu función ponDireccionPostal(), escribe una línea de código que muestre el contenido del campo Dirección postal mediante la propiedad .value en una ventana de alert.


Paso 3: Poniendo el valor para la dirección personal

Ahora que sabemos cómo encontrar el valor de cualquier elemento en nuestro documento, el truco es establecer el valor de la propiedad .value del elemento homeaddress al valor del elemento postaladdress. Para establecer el valor de homeaddress podríamos hacer algo como lo que sigue:

 document.getElementById("homeaddress").value = "Hola mundo";

Pruébalo y ve que funcione. Debería ocurrir que cuando activas la caja de selección, la dirección personal contiene el texto "Hola mundo".

Ahora veamos si puedes modificar la línea de arriba para que en lugar de poner "Hola mundo" en el campo homeaddress, ponga el valor del campo postaladdress.


Paso 4: Desactivando el campo de Dirección personal

Usa la página de W3Schools sobre el objeto HTML DOM TextArea y ve si puedes encontrar una propiedad que te permita desactivar un campo de este tipo.

Intenta modificar esta propiedad para el elemento "homeaddress" en tu función ponDireccionPersonal(). Asegúrate de probarla.


Paso 5: Alternando el campo de dirección personal

Ahora, cuando pruebes tu forma te darás cuenta de que al desactivar la caja de selección, el campo de dirección personal no se habilita.

Agrega una instrucción if a tu función ponDireccionPersonal() de manera que cuando la caja de selección no esté activada, el campo de dirección personal se habilite (te podría servir el revisar la solución al Reto 1).


Reto 3: Botones de opción múltiple[editar]

Como viste en el Reto 2, algunos campos en los fomularios funcionan de manera distinta a otros cuando se trata de obtener información sobre sus contenidos. <input type="checkbox"> usa la propiedad .checked, <input type="text"> y <textarea> usan la propiedad .value.

Por suerte para nosotros no hay tampoco demasiadas variantes para aprender, y podemos usar un mismo código para saber si el usuario ha dejado un campo vacío, por ejemplo:

  if (document.getElementById("nombre").value == "")
  {
     window.alert("Por favor llena el campo de Nombre.");
     return false;
  }

Nombre es un campo de texto, por lo que estamos examinando la propiedad .value. Pero ¿cómo hacemos esto con los botones de opción múltiple? Pues éstos no toman el valor que nuestro usuario escribe ... un botón de tipo radio está activado o no. ¿Te suena familiar?

Copia el siguiente formulario en un archivo (el que usaste en el reto 2 está bien) y cárgalo en el navegador:

<form action="mailto:me@fakeemail.com">
  <fieldset>
    <legend>Botones de opción múltiple y cajas de verificación</legend>
    <p>
      ¿Cuál es tu fruta favorita?: 
      <label>
        <input type="radio" value="hombre" name="frutafav" id="opcfresa">
        Fresas
      </label>
      <label>
        <input type="radio" value="mujer" name="frutafav" id="opcarand">
        Arándanos
      </label>
    </p>
  </fieldset>

  <input type="submit" value="Enviar">
</form>


Paso 1: Activando la validación de los datos

Primero crea una función vacía llamada revisaFormulario() para tu forma, y asegúrate de que sea ejecutada cuando la forma se envíe (usando una simple llamada window.alert). Esta W3Schools' página sobre eventos te ayudará a usar el evento submit.


Paso 2: Revisando si se seleccionó un botón de opción múltiple

Una vez que te hayas convencido de que tu función revisaFormulario() se ejecuta, rellena la función de manera que se vea así:

function revisaFormulario()
{
  // Primero crea una variable para referirte directamente al campo
  var opcFresa = document.getElementById("opcfresa");

  if (opcFresa.[¿que propiedad tiene que ir aquí?] == false)
  {
    window.alert("Por favor elige tu fruta favorita");
    return false;
  }
       
  return true;
}

Fíjate en que esta función no está completa, necesitamos encontrar cuál propiedad del botón es la que nos dirá si ha sido activado o no. Consulta W3Schools' HTML DOM Radio Object y ve si puedes encontrar la propiedad adecuada. Cuando la encuentres reemplaza su nombre en lugar del texto que dice [¿qué propiedad tiene que ir aquí?].

Prueba el código y ve si hace lo que esperas.


Comentando tu código

El código de ejemplo que viste un poco más arriba incluía texto que comenzaba con dos diagonales. Este tipo de texto se llama comentario -- puede contener cualquier texto que quieras, y no se ejecutará como parte del programa. Lo que los comentarios hacen es ayudarte a recordar qué es lo que hace un segmento particular del código una semana o un mes después de que lo escribiste.

Se recomienda que conforme progreses a través de los retos escribas comentarios siempre que encuentres algo neuvo. Realmente te ayudarán más tarde, cuando los programas que escribas sean más largos y no recuerdes cómo hacer algo.


Paso 3: Haciendo que funcione adecuadamente

Habrás notado que el código no hace en realidad lo que se requiere, aunque está haciendo justo lo que le pedimos. Obliga al usuario a seleccionar la opción de las fresas.

Se necesita modificar el código de manera que alerte al usuario solamente si la opción de las fresas es falsa y la opción de los arándanos el falsa también (esto es, si ninguna de las dos opciones ha sido activada). Puedes revisar la sección sobre los operadores lógicos en el curso Introducción a Javascript para ver si encuentras cómo asegurarse que ambas opciones no estén activadas antes de alertar al usuario.


Paso 4: Deteniendo el avance

Habrás notado que el programa intenta enviar un correo electrónico sin importar si el formulario se ha llenado correctamente o no. Esto no es lo mejor.

Puesto que este es nuestro primer reto empleando el evento onsubmit, puede ser que no te hayas fijado en la instrucción return false. Fíjate en las dos instrucciones return en el código de la función. Ve que return false se emplea cuando hay un error, y return true se usa al final si todo ha estado bien.

El código return de Javascript te permite salir de una función de manera inmediata si no hay razón para continuar. En nuestro caso, cuando encontramos que el usuario no ha seleccionado un opción, lo que queremos es cancelar el envío del formulario incompleto. La instrucción return false le dirá a JavaScript que cancele el envío, pero todavía falta una parte del código que hará que esto funcione.


Puedes revisar la sección sobre validación de formularios en el curso Introducción a Javascript para que veas lo que le falta a tu código.

Reto 4: Mejor validación de datos[editar]

Hasta ahora nuestra validación de los datos ha consistido en mostrar molestas cajas con window.alert() cuando el usuario introduce información incorrecta, pero tendría que haber un modo más amigable para el usuario ¿no?

Este reto te ayudará a crear mensajes de error en el mismo formulario, que sólo aparezcan cuando tienen que hacerlo. Copia el siguiente formulario en una página:

<form action="mailto:me@fakeemail.com" onsubmit="return revisaFormulario();">
  <fieldset>

    <legend>Datos personales</legend>
    <p>
      <label>
        Nombre completo:
        <input type="text" name="nombre" id="nombre">
      </label>
    </p>
    <p class="errormsj" id="msjnombreerror">Por favor introduce arriba tu nombre completo</p>

    <p>
      <label>
        Dirección:
        <input type="text" name="calle" id="calle">
      </label>
    </p>
    <p class="errormsj" id="msjcalleerror">Por favor introduce arriba la calle y el número de tu dirección</p>

  </fieldset>
  <input type="submit" value="¡Envíalo!"> 
</form>


Paso 1: Algo de estilo

Primero agrega algo de CSS. Añade algunos estilos para que los mensajes de error estén en color rojo. Haz que se vean dramáticos. Fíjate en que los mensajes de error tienen class="errormsj".

Una vez que se vean como quieres, usa CSS para esconderlos de manera predeterminada.


Paso 2: Creando la función revisaFormulario()

Necesitas una función vacía que simplemente muestre un window.alert para que sepas que está funcionando. Necesitas agregar un evento de manera que se ejecute cuando presiones el botón enviar.

Reemplazando una función con otra

Como habrás notado, el nombre de nuestra nueva función es el mismo que el de la función que escribimos anteriormente. Si lo deseas puedes conservar el código anterior e ir modificando lo que sea diferente en esta nueva función. Pero otra solución sería renombrar la antigua función como revisaFormulario0() y hacer este cambio también en el formulario que pregunta sobre la fruta favorita. De esta manera puedes conservar un código que ya funcionaba para comparar con el nuevo código que vas a implementar.


Paso 3: Mostrando los mensajes de error

Este paso será similar al Reto 1 "Elementos que se esconden". Cuando la forma se envíe, nuestra función revisaFormulario() se activa. Si el campo nombre está vacío, queremos que entonces se muestre el párrafo con el ID "msjnombreerror".

Después de que tengas esto listo, implementa un funcionamiento similar para la dirección.


Paso 4: Modificando la lógica del programa

Habrás notado hasta el momento dos cosas que no están tan bien:

  1. Cuando envías el formulario con campos en blanco, solamente aparece el primer mensaje de error.
  2. Cuando agregas texto a uno de los campos y vuelves a enviar el formulario, los mensajes de error no desaparecen.


Para arreglar esto, necesitarás cambiar la lógica de tu función ... esto puede ser complicado, pero aquí hay unas sugerencias:

  • ¿Estás usando return false justo después de mostrar el primer mensaje de error? Esto quiere decir que tu programa nunca ejecutará la segunda parte si la primera da un error.
  • Necesitas una variable, tal como "es_valido" que tenga valor true o false dependiendo del resultado de la revisión de los datos. Al final de la función puedes devolver esta variable en lugar de los valores true of false tan pronto como encuentres un error.
  • Estás mostrando el mensaje de error si hay un error, pero también necesitas esconder el mensaje si todo está bien.


Reto 5: Asegurándote de que se haya introducido un número[editar]

Hasta ahora hemos trabajado en cómo checar si un campo está vacío o no. Ahora queremos llevar esto un paso más allá y verificar que lo que se introdujo sea en realidad un número. Imagina que has incluido en el formulario un campo llamado Cantidad, donde el visitante especifique cuántas unidades de un cierto producto quiere comprar. No queremos que introduzca 'Ah' u 'Hola', ¿verdad?


Paso 1: Actualizando el formulario

Agrega un campo de texto a tu formulario que tenga el nombre "cantidad" y modifica tu función revisaFormulario() de manera que el valor no pueda ser vacío.


Paso 2: Revisar que sea un número

Javascript tiene una función especial llamada isNaN(), abreviatura de "es un no-número (is Not a Number en inglés)", que puede ser usada para probar si un valor puede ser interpretado como un número. Por ejemplo, isNaN(1.5) devolverá como resultado falso (pues *se trata* de un número), en tanto que isNaN("hola") devolverá verdadero, (pues no es un número).

Tómate unos pocos minutos para experimentar con el demo de isNaN() de W3Schools hasta que te sientas a gusto y comprendas lo que hace.


¿No está al revés? isNaN() es una función única pues parece que se usa al revés. Seguramente tendría más sentido que nos dijera si algo es un número, ¿no?

Sin embargo, hay una razón para isNan(): es consistente con otro aspecto común de JavaScript. Si intentamos hacer cálculos con algo que no es un número, por ejemplo alert("hola" / 5); tendremos como resultado "NaN" (no es un número).

Cuando JavaScript fue diseñado, isNaN() fue uno de los casos en los que la consistencia ganó sobre la facilidad de uso.

En tu función revisaFormulario(), justo después de que revisas que el campo cantidad no esté vacío, agrega otra instrucción if de la siguiente manera:

  // solo necesitas la siguiente linea si no tienes aun
  // una varaible para el campo cantidad.
  var cantidad = document.getElementById("cantidad");

  // Ahora revisa si el valor del campo cantidad no es un numero
  if (isNaN(cantidad.value))
  {
    // si la cantidad no era un numero, entonces queremos que el
    // usuario sepa que necesita corregir el error
    // Agrega aqui abajo tu codigo: 


    // Al final, devuelve el valor false de manera que la forma no sea enviada.
    return false;
  }


Paso 3: Agregando un campo Código postal

Ahora agrega otro campo a tu formulario llamado 'codigopostal'. Actualiza tu función revisaFormulario() de manera que:

  1. el código postal no pueda quedar vacío.
  2. el código postal deba contener sólo números (ve el paso 2 de este mismo reto).


Paso 4: Revisando la longitud del campo código postal

Todo lo que pueda tener una longitud en JavaScript tiene una propiedad especial llamada length. Esta propiedad puede usarse para saber cuántos caracteres ha introducido un usuario en un campo. Por ejemplo, el siguiente código obtiene el valor del campo "nombre" del documento y entonces muestra un mensaje de alerta diciéndole al usuario cuántos caracteres fueron introducidos:

  var nombre = document.getElementById("nombre");
  window.alert("La longitud del campo nombre es: " + nombre.length);

Tómate unos minutos para ver cómo se usa la propiedad length en este ejemplo de la página W3Schools.

  • Modifica el ejemplo de la página W3Schools de manera que el campo pueda tener hasta 8 caracteres.
  • Ahora modifica tu función revisaFormulario para que el campo de código postal pueda tener sólo 4 caracteres.


Tiempo de repasar[editar]

Hasta ahora te las has arreglado para:

  1. Verificar si una casilla de selección o un botón de selección múltiple está activada;
  2. Verificar si un campo de texto está vacío;
  3. Verificar si el texto introducido es un número usando la función isNaN();
  4. Verificar la longitud del texto introducido en un campo (esto es, cuántos caracteres se introdujeron) usando la propiedad length;
  5. Mejorar la validación de los campos de manera que muestre mensajes de error en la misma página (en lugar de usar la desagradable caja de window.alert()). Esto lo haz hecho escondiendo y mostrando los mensajes de error con el objeto style.

¡Nada mal! Si te parece que necesitas practicar un poco más con estas tareas, intenta agregar algunas de estas características a otro formulario que hayas elaborado antes, como cuando aprendiste (X)HTML. Hacer esto puede ayudarte a encontrar aspectos con los que haz batallado y a ganar más confianza con la sintaxis de JavaScript.

Si usas Firefox y no haz probado aún Firebug, tómate un tiempo para experimentar con este utilísimo depurador de JavaScript.


Reto 6: Comenzando a validar direcciones de correo[editar]

Verificar si un código postal era válido requería revisar que:

  1. el código introducido fuera un número
  2. el código tenía exactamente 5 dígitos (aunque esto depende del país)

¿Qué podemos revisar para asegurarnos de que una dirección de correo electrónico sea válidad? Toma un pedazo de papel y ve si puedes resumir dos o tres cosas que las direcciones de correo electrónico deben tener para ser válidas.


Paso 1: Agregando un campo Correo

Agrega un nuevo campo a tu formulario que se llame 'correo' (asegúrate de ponerle los atributos 'name' e 'id'). ¿Qué tipo de campo es mejor para las direcciones de correo?


Paso 2: Asegurándote de que el símbolo '@' esté presente

Toda dirección de correo contiene un y sólo un símbolo "arroba" (@). La dirección de correo introducida en el formulario es solamente una secuencia de caracteres, un texto tal como "Hola mundo". Todos los lenguajes de programación se refieren a este grupo de caracteres como una cadena de texto (String).

Algo que es muy útil de Javascript es que toda cadena de texto incluye ya un montón de propiedades y métodos incorporados, que podemos usar. De hecho, ya hemos usado la propiedad length en el Reto 5 para saber cuántos caracteres tenía el código postal.

Tómate unos minutos para leer la sección "Funciones útiles para cadenas de texto". Conforme lo leas, puedes intentar algunos de los ejemplo de la página JavaScript String.

Uno de los métodos que deberías haber visto es indexOf(). Podemos usarlo para encontrar en qué parte de nuestra dirección de correo aparece el símbolo "@", si es que aparece. Ten en cuenta que el método indexOf() devuelve un número correspondiente al índice o posición del texto que busca. Si el texto no está en la cade, entonces indexOf() devolverá -1. Por ejemplo:

  var miCadena = "¡Hola Mundo!";

  window.alert("La posición de H es: " + miCadena.indexOf("H")); // la posición será 1

  window.alert("La posición de o es: " + miCadena.indexOf("o")); // la posición será 2

  window.alert("La posición de un es: " + miCadena.indexOf("un")); // la posición será 7

  window.alert("La posición de ! es: " + miCadena.indexOf("!")); // la posición será 11

  window.alert("La posición de Z es: " + miCadena.indexOf("Z")); // la posición será -1

Si quieres probar este código puedes usar la Consola Javascript o el ejemplo de indexOf() en W3Schools.

Agrega el siguiente código a tu función revisaFormulario(), luego modifícalo para que funcione.

  // crea una variable para referirte al campo de correo (ahorra tener que escribir mas despues)
  var correo = document.getElementById("correo");

  // Primero, crea una variable para recordar la posicion del simbolo "@"
  var enPos = correo.value.indexOf("@");

  if (enPos == ¿?) // necesitas reemplazar los signos de interrogacion
  {
    // Entonces no habia un simbolo @ en la direccion de correo.
    // Haz saber al usuario que necesita corregir el error.
    // Agrega tu codigo aqui abajo:


    // Al final devuelve false de manera que el formulario no se envie.
    return false;
  }


Paso 2: Asegurándose de que haya algo antes del @

Ahora estamos seguros de que hay un @ dentro de la dirección de correo, pero hay un gran problema: ¿qué pasa si el usuario no ha puesto nada antes del @?

Escribe una instrucción if adicional en la función revisaFormulario() que se asegure de que el @ no esté al principio de la cadena. Recuerda, indexOf() te dará siempre las posiciones empezando desde 0.


Paso 3: Asegurándose de que haya un punto (.) después del @

Otra parte necesaria en una dirección de correo es el nombre del servidor (la parte resaltada en una dirección como la siguiente: alguien@algunlado.com), que siempre está después del @. Para asegurarte de que el usuario introduzca un nombre de servidor, podemos verificar que haya un punto en esa parte del correo.

Un problema adicional es que algunas direcciones de correo incluyen un punto como parte del nombre de usuario (la parte resaltada en juan.perez@algunlado.com). No podemos usar indexOf() para buscar el punto, pues bien podría encontrar el primer punto en lugar del segundo.

Javascript nos brinda una manera fácil de para resolver este problema con el método lastIndexOf(), que funciona de la misma manera que indexOf(), excepto que encuentra la última vez que el texto aparece, en lugar de la primera.

Escribe una instrucción if extra en la función revisaFormulario() que se asegure de que haya un punto después del símbolo @ en el correo. Podías crear variables que almacenen las dos posiciones para hacer el código más legible.


Paso 4: Asegurándose de que haya al menos dos caracteres después del punto

Con las pruebas de validación actuales el usuario no puede introducir algo sin sentido como "@." o "al.guien@" como su dirección de correo, pero bien podría introducir algo como "alguien@algunlado." ¿Qué es lo que falta al final?

Usamos lastIndexOf() para obtener la posición del último punto. ¿Cómo podrías saber si hay más caracteres después del punto? ¿Qué otra propiedad necesitarías comparar?


Una referencia del mundo real para pensar este problema

Tienes una pieza de listón con una marca a 20cm de uno de sus lados. ¿Qué medida tienes que hacer para calcular cuántos centímetros de listón hay del otro lado de la marca?

Escribe el código que falta en la función revisaFormulario, de manera que se asegure que hay al menos dos caracterers después del último punto.


Avanzado: haciendo todo esto con Expresiones regulares (regex)

Como puedes ver, escribir código para validad puede convertirse en algo largo y complicado, aun para algo que parece tan simple como una dirección de correo. Para validar campos complicados, que requieren tener una cierta forma, existe una técnica mucho más corta y rápida que se llama Expresiones regulares.

Si haz escrito alguna vez "*.*" para encontrar todos los archivos en DOS, o seleccionado "*.doc" en la caja de Tipo de archivo en Windows, entonces ya haz usado una Expresión regular simplificada. Las expresiones regulares son maneras de verificar palabras basadas en un patrón; en el caso "*.doc" estamos buscando algo como alguna palabra, seguida por un punto, seguida por "doc".

Las expresiones regulares se encuentran en casi todos los lenguajes de programación, y lo que aprendas en Javascript te servirá en otros lenguajes de programación tales como PHP y Perl con solamente unos pequeños ajustes.

Javascript: Expresiones regulares es un buen punto inicial para familiarizarse con lo básico de Regex (las expresiones regulares).

Reto 7: Javascript que no estorba[editar]

Hasta ahora hemos estado mezclando nuestro JavaScript con el código HTML... y este es el modo en el que Javascript se ha hecho durante años porque es simple (así como usar las etiquetas <font> en HTML es un poco más cimple que usar CSS). Pero no es la mejor manera.

Así como separamos nuestro contenido (X)HTML de la presentación en CSS de nuestras páginas web, también vale la pena separar el comportamiento de nuestro Javascript. ¿Por qué? Puedes encontrar un poco más de información al respecto en Wikipedia JavaScript no obstructivo, pero si piensas en cómo separar CSS implica que se puede reusar la misma hoja de estilo muy fácilmente, es lo mismo con Javascript. Separando Javascript de la página, podemos aplicar el mismo código a muchas páginas sin tener (usualmente) que modificar la página misma.

Aquí tienes cómo funciona: Normalmente conectamos nuestro código Javascript (como la función revisaFormulario) a un elemento de (X)HTML en particular con un atributo como onsubmit:

  <form method="post" onsubmit="return revisaFormulario()" id="respuestausuario">
    ...
  </form>

Y esto hace el trabajo. Ahora lo que queremos es quitar ese código: 'onsubmit="return revisaFormulario()"' por completo. Hazlo, quítalo de la página.

¿Cómo vamos entonces a vincular nuestro formulario con la función revisaFormulario? Bueno, en realidad podemos establecer eventos para los elementos (X)HTML usando también Javascript de la siguiente manera:

  document.getElementById("respuestausuario").onsubmit = revisaFormulario;

Este pedazo de Javascript reemplazará el código 'onsubmit="return revisaFormulario()"' que habíamos incluido en el código (X)HTML hasta ahora. Pero probablemente te surjan dos preguntas:

  1. ¿Por qué nuestra función revisaFormulario() no tiene aquí los paréntesis?
  2. ¿Dónde pongo este código?

La respuesta más fácil a la primera pregunta es que "no los lleva" - es algo excepcional ver una función sin los paréntesis (Si sigues con curiosidad, cuando omites los paréntesis lo que está ocurriendo no es un llamada a la función, sino que e trata de un apuntador). Para la segunda pregunta, intentemos ponerla en nuestro programa, al principio del documento, así:

  <script type="text/javascript">
    function revisaFormulario()
    {
      window.alert("Ejemplo de validación de datos");
      // Tu codigo de validacion normal va aqui
    }

    document.getElementById("respuestausuario").onsubmit = revisaFormulario;
  </script>

Vuelve a cargar la página en el navegador y ve lo que pasa. En la consola de errores del navegador deberías ver un mensaje de error causado por que no se ha podido encontrar un elemento con el ID de "respuestausuario" - aunque definitivamente debería haber uno (si no lo agregaste, entonces hazlo ahora).

El problema es que nuestro Javascript está en la cabecera del documento (X)HTML y es ejecutado antes de que el resto del documento haya sido todavía leído (e interpretado) por el navegador.

Así que necesitamos una manera de asegurarnos de que ese segmento de código que acabamos de crear sólo se ejecute hasta después de que el documento haya sido cargado por completo ... ¿alguna idea? Probablemente estás pensando algo como lo que sigue:

  <body onload="nuestro código podría ir aquí">

y tienes razón, hasta un cierto punto. Queremos usar el evento onload, pero no escribirlo en el (X)HTML o estaríamos de regreso en el punto original. En su lugar colocaremos nuestra nueva línea de Javascript en su propia función:

  //
  // Esta funcion configura todos los eventos usados por mi Javascript
  //
  function configMisEventos()
  {
    document.getElementById("respuestausuario").onsubmit = revisaFormulario;
  }

y entonces relacionaremos esta función con el evento onload empleando una línea especial de código:

  window.onload = configMisEventos;

De manera que nuestro código Javascript se verá al final de esta manera:

<script type="text/javascript">
  //
  // revisaFormulario()
  // Verifica todos los campos requeridos del formulario.
  //
  function revisaFormulario()
  {
    window.alert("Ejemplos de validacion de datos");
    // Tu codigo normal de validacion va aqui
  }

  //
  // Esta funcion configura todos los eventos usados por mi Javascript
  //
  function configMisEventos()
  {
    document.getElementById("respuestausuario").onsubmit = revisaFormulario;
    // Todos los demas eventos que uses pueden ser agregados de la misma manera aqui.
  }

  window.onload = configMisEventos;
</script>

Inténtalo ahora con tu propio formulario.

El último paso para separar nuestro Javascript es mover el código completo a un archivo aparte, de manera que solamente quede nuestra etiqueta script haciendo referencia al archivo de Javascript:

  <script type="text/javascript" src="mi_archivo_javascript.js">

¡Bravo! Ahora ya estás en el camino para aprender Javascript de la manera no obstructiva. Revisa algunos de los Enlaces externos incluidos en el artículo de Wikipedia JavaScript no obstructivo, pues allí puedes encontrar otros aspectos expuestos con mayor claridad que aquí.

Reto 8: Usando mapas[editar]

Google proporciona una herramienta que te permite incluir su amplia funcionalidad de mapas en tu propio sitio web - todo lo que necesitas es un poco de Javascript (bueno, para hacer algunas de las cosas más útiles necesitarás aprender un poco más de Javascript, pero eso es algo bueno).

Si quieres usar una alternativa abierta, tal como OpenStreetMap, entonces intenta con esta guía paso a paso de OpenLayers (en inglés).

Empieza revisando el ejemplo "Hello, World" de Google Maps. Conforme leas sus ejemplos de Javascript verás que algunas partes lucen familiares (instrucciones if, funciones, eventos, etc), pero otras son nuevas (las variables ue comienzan con google.maps).

  1. La primera parte de este reto es hacer que el mapa funcione en tu propia página. Necesitarás copiar y pegar el código mostrado, y cambiar la instrucción sensor=set_to_true_or_false a sensor=false Entonces ábrelo en tu navegador y/o súbelo a tu servidor web.
  2. Modifica el código para que muestre un mapa de tu localidad en lugar del mapa de Australia que viene predeterminado (si eres de Australia, entonces ubícalo en una ciudad importante en otro país). Para hacer esto necesitarás encontrar las coordenadas de latitud y longitud. (Puedes intentar con http://geohash.org)
  3. Modifica tu código configurar los controles del mapa y/o agregar un marcador.

Eso es sólo el principio, pero esperamos que te haya hecho pensar acerca de las posibilidades.


Reto 9: Una introducción a YUI - Un calendario[editar]

Imagina que tienes un formulario que requiere que el usuario introduzca una fecha. Hay varios formatos que podrían usarse, algunos de los cuales son ambiguos, tales como 08/06/2007 (¿se trata del 8 de junio de 2007 o del 6 de agosto de 2007? Esto depende de dónde vivas.).

Actualmente hay muchas soluciones Javascript que permiten a los usuarios dar click en una opción de calendario en lugar de escribir la fecha directamente. Esta es una forma mucho más certera de obtener esa información del usuario. para esto vamos a conocer las bibliotecas de la Interfaz de Usuario de Yahoo! (YUI).

La biblioteca YUI es muy extensa, y está ampliamente documentada. Por el momento usaremos el elemento Calendario sin entrar en demasiados detalles, pero si quieres conocer más, hay documentación para aventar para arriba (incluyendo tablas de referencia) y videos tales como este: YUI Basics and DOM hacking.

Para comenzar:

  • Crea un documento (X)HTML que contenga la declaración de tipo de documento (doctype), y las etiquetas html, head, title y body, así como un encabezado de nivel 1 (h1) y un párrafo de introducción (tal como, "Una prueba del control de Calendario de YUI").
  • Agrega un pequeño formulario con un campo, incluyendo una etiqueta (label) "Introduce el nombre de tu evento:", seguido por un campo de texto y un botón para enviar los datos.
  • Lee la introducción en YUI Calendar control y sigue las instrucciones de la primera sección "Getting Started" paso a paso. Si te atoras con algo, revisa el código de abajo para saber qué hacer, pero debes resistirte a copiar y pegar.

Una vez que tienes un control de calendario en tu página:

  • Agrega una nueva función a tu Javascript, llamada mostrarFecha(), vincula esta función con el evento onsubmit del formulario y verifica que funcione (por ejemplo, agrega una alerta que diga "Sí, la función se activó").
  • Lee la sección de la documentación de YUI titulada "Obtaining selected dates", pero ten en cuenta que sabemos que solamente se puede elegir una fecha, así que podemos obtener la fecha y almacenarla en una variable de esta manera:
    • var fecha_elegida = cal1.getSelectedDates()[0]
  • Usa el código de arriba en tu función mostrarFecha para mostrar la fecha usando window.alert. Podrías requerir el uso de los métodos getDate(), getMonth() y getFullYear() del objeto date (esto es, fecha_elegida.getMonth() para obtener el mes). Vela referencia del objeto date en W3Schools si requieres más ayuda.

Solamente si estás realmente entusiasmado:

  • Agrega un nuevo campo de texto a tu formulario con la etiqueta "Fecha elegida", y ve si puedes usar el propio evento selectEvent del Calendario para transferir la fecha elegida al nuevo campo (nota: hay mucho por aprender si no has usado los eventos de YUI antes).
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="es">
  <head>
    <title>Calendario YUI</title>

    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.3.0/build/calendar/assets/skins/sam/calendar.css"> 
         
    <!-- Dependencias --> 
    <script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> 
         
    <!-- Archivo fuente --> 
    <script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/calendar/calendar-min.js"></script>

    <script type="text/javascript">

      var cal1;
      function configMisEventos() {
        cal1 = new YAHOO.widget.Calendar("cal1","cal1Container"); 
        cal1.render(); 
      }

      window.onload = configMisEventos;

    </script>
  </head>
  <body class="yui-skin-sam">
   <h1>Calendario - Yahoo! User Interface</h1>
   <p>Este es un ejercicio para probar el calendario de YUI</p>

   <form action="">
     <p>Este formulario deberia tener muchos otros campos</p>
     <p>
       <label>
         Pon aquí el título de tu evento:
         <input type="text" name="tituloevento" id="tituloevento">
       </label>
     </p>
     <p>
       <label>
         Elige la fecha del evento:
         <input id="fechaevento" type="text">
       </label>
     </p>
     <div id="cal1Container"></div>
     <p>
       <input type="submit" value="Enviar">
     </p>
   </form>
  </body>
</html>

Reto 10: Una introducción a jQuery - revisando los elementos que se esconden[editar]

La biblioteca Yahoo! User Interface que se usó en el reto anterior tiene una cantidad increíble de características, pero también puede, por eso mismo, constituir algo muy difícil de aquilatar de principio para quienes sólo buscan hacer unas cosas simples, como mostrar/ocultar un campo de un formulario.

Aquí entra jQuery:

jQuery es una biblioteca que simplifica la forma en que exploramos los documentos (X)HTML, manejamos eventos, realizamos animaciones, y agregamos interacciones de Ajax a nuestras páginas web. jQuery ha sido diseñada para cambiar el modo en que escribes Javascript.

Así que empecemos. Un buen lugar para comenzar es el tutorial Getting started with jQuery. Incluye un kit para principiantes (starter kit) y te guiará a través de un ejemplo hola mundo. Después de terminar las primeras dos secciones (Setup y Hello jQuery), ya estás listo para este reto: revisando los elementos que desaparecen. También puedes buscar otro tutorial de jQuery que te enseñe a hacer lo más básico antes de abordar este reto.

  • Copia y pega el siguiente código HTML en un nuevo archivo - fíjate en que es el mismo formulario del Reto 1 (y queremos implementar la misma funcionalidad).
  • Asegúrate de que tienes la versión más reciente de jQuery guardada en el mismo folder que tu archivo, con el nombre jquery.js
  • Lee el código Javascript para que revises si sabes lo que intenta hacer.
  • Pruébalo en el navegador.¿Hace lo que se espera? ¿Qué es lo que no funciona bien aún? (piensa: "No pensé que tenía que fijarme en eso").
  • Ahora, para el reto, revisa la página jQuery Event documentation, y ve si puedes solucionar el problema que identificaste en el paso previo.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <title>Javascript reto 10</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
      // Configura un codigo para ser ejecutado cuando el documento este listo
      $(function(){

        // Primero esconde todo el parrafo con el campo de correo:
        $("p#emailpara").hide();

        // Agrega una funcion que deberia ejecutarse cada vez que se
        // active la casilla subscribe:
        $("input#subscribe").click(function(){
          $("p#emailpara").show("slow");
        });
      });
    </script>

  </head>
  <body>
    <h1>Probando jQuery</h1>
    <form action="mailto:me@example.com" method="post">
      <fieldset>
        <legend>Suscripciones de correo</legend>

        <p id="subscribepara">
          <label>
            <input type="checkbox" name="subscribe" id="subscribe">
            Me gustaría recibir el boletín vía correo-e.
          </label>
        </p>

        <p id="emailpara">
          <label>
            Email Address:
            <input type="text" name="email" id="email">
          </label>
        </p>

      </fieldset>
    </form>
  </body>
</html>

Una vez que estés listo, fíjate en el código Javascript que usaste en este reto y compáralo con tu código del Reto 1 ... ¿cuál preferirías escribir?

Al final revisa el Reto 4 (donde se mejoró la validación), y reescribe tu solución usando jQuery.