1.- Validaciones de formularios El alumno debe realizar las siguientes validaciones: En el formulario registro: o No se pueden dejar en blanco ni el nick ni el password y ambos no pueden ser iguales. o El campo nick debe ser una dirección de correo electrónico correcta. o El password1 y el password2 deben ser iguales. o El password debe tener una longitud mínima de 6 caracteres, y debe contener al menos un número y una letra. En el formulario login: o No se pueden dejar en blanco ni el nick ni el password y ambos no pueden ser iguales. o El campo nick debe ser una dirección de correo electrónico correcta. o El password debe tener una longitud de al menos 6 caracteres y debe contener al menos un número y una letra. Cuando los datos introducidos por el usuario no pasen la validación, en lugar de mostrar un mensaje de error mediante un alert, crearemos un <div> debajo del formulario e introduciremos ese mensaje dentro del <div>. Para ello utilizaremos las funciones del DOM. Si la validación es correcta se llamará al método submit del formulario. Como se puede observar, las validaciones son muy parecidas, por lo que, se recomienda crear funciones que hagan las distintas validaciones, para así llamarlas desde ambas validaciones. Se valorará el uso de expresiones regulares para realizar las validaciones correspondientes. 2.- Botones de formato de la página editar.php Al pulsar los botones (o enlaces) de negrita, cursiva e insertar URL, se insertará código HTML en el textarea que contiene el texto de la entrada. En concreto: Si no hay texto seleccionado, el mismo botón (o enlace) servirá, tanto para abrir negrita o cursiva como para cerrarla. Para ello, cuando se pulse negrita o cursiva se buscará hacia atrás en el textarea (desde la posición del cursor) la etiqueta HTML correspondiente (<strong> o <em> respectivamente). Si no está, o bien, se encuentra antes la etiqueta cerrada, se insertará una etiqueta de apertura en el punto donde está el cursor. Si hay texto seleccionado, se insertará, antes y después de la selección, la etiqueta correspondiente de apertura y cierre, respectivamente. Cuando se pulse el botón de insertar URL, mediante dos prompt se pedirá al usuario la URL y el texto del enlace, y se insertará el HTML correspondiente en el textarea en el punto en que esté el cursor. Si al pulsar el enlace hay un texto seleccionado, sólo se pedirá la url del enlace y se tomará el texto seleccionado como texto del enlace. Las siguientes funciones nos devuelven la posición de inicio y fin de la selección de texto en el área de texto. function dame_posicion_seleccion_inicial(area_de_texto) { if (document.selection) // Soporte IE { area_de_texto.focus(); var range = document.selection.createRange(); var stored_range = range.duplicate(); stored_range.moveToElementText(area_de_texto); stored_range.setEndPoint('EndToEnd', range); return stored_range.text.length - range.text.length; } else { // Soporte Firefox if (area_de_texto.selectionStart || area_de_texto.selectionStart == '0') return area_de_texto.selectionStart; else return NaN; } } function dame_posicion_seleccion_final(area_de_texto, seleccion_inicial) { if (document.selection) // Soporte IE { area_de_texto.focus(); var range = document.selection.createRange(); var stored_range = range.duplicate(); stored_range.moveToElementText(area_de_texto); stored_range.setEndPoint('EndToEnd', range); return stored_range.text.length; } else { // Soporte Firefox if (area_de_texto.selectionStart || area_de_texto.selectionStart == '0') return area_de_texto.selectionEnd; else return NaN; } } La llamada se efectuaría de la siguiente forma: var area_de_texto = document.getElementById("texto"); var inicio_seleccion = dame_posicion_seleccion_inicial(area_de_texto); Pasos a seguir: Una vez obtenidas las posiciones inicial y final de la selección, si estas son iguales, quiere decir que no hay nada seleccionado. Para buscar dentro de un texto desde el final usaremos el método texto.lastIndexOf. Para insertar texto en una posición concreta del área de texto seguiremos los siguientes pasos: Extraemos la subcadena que va desde el inicio del texto hasta el punto de inserción mediante el método area_de_texto.value.substring. A esta subcadena le sumamos el texto a insertar. A esto le sumamos la subcadena desde el punto de inserción hasta el final del texto, utilizando de nuevo el método substring. 3.- Animación javascript En este ejercicio vamos a trabajar con un elemento que llamaremos persiana y que se encontrará en todas las páginas del sitio web. Construiremos este elemento de la siguiente forma: El aspecto puede ser parecido al siguiente: está formado por tres elementos <div>. El primero de ellos es la propia persiana, que contiene a los otros dos: titulo_persiana y contenido_persiana. El contenido de la persiana está vacío (posteriormente trabajaremos con su contenido). Los estilos que debemos aplicar al elemento contenido_persiana son los siguientes: si nos fijamos en sus estilos, observaremos que no está visible porque tiene un alto de 0px (height: 0px). El título de la persiana contiene, a su vez dos divs más: texto_titulo_persiana, que contiene el texto de título de la persiana. cerrar_persiana, que contiene tres imágenes que nos van a servir para darle funcionalidad a la persiana, ya que, al hacer clic sobre ellas, se llama a las correspondientes funciones javascript. El objetivo del ejercicio es hacer que cuando pulsemos el botón de plegar_desplegar, se inicie una animación que muestre como la persiana se va desplegando poco a poco hasta alcanzar un alto de 235px. El aspecto de la persiana desplegada será el de la imagen siguiente. Como se puede observar, al hacer la persiana más grande, el resto de elementos de la página se coloca debajo de la persiana. Además, cuando termina la animación la imagen plegar_desplegar cambia y se muestra la flecha hacia arriba. El proceso para realizar el ejercicio será el siguiente: Al pulsar la imagen plegar_desplegar se llamará a la función plegar_desplegar_persiana(). En esta función se iniciará una animación mediante el método setInterval que llamará a una determinada función, por ejemplo, despliega_persiana cada 100 ms. La función despliega_persiana irá incrementando el alto de la persiana en 10px cada llamada. Para hacer esto, habrá que obtener el alto actual, verificar si ha llegado al alto máximo y, si no es así, incrementarlo en 10px. Hemos de tener en cuenta que habrá que incrementar el alto, tanto del div persiana como del div contenido_persiana. El div persiana no puede tener un alto menor de 35px para que siempre quede visible el título. Cuando la persiana está desplegada, si se vuelve a pulsar el botón, la persiana iniciará de nuevo la animación, pero en este caso se plegará la persiana hasta volver al estado inicial. Para saber si la persiana está plegada o desplegada, una posibilidad sería ver qué imagen estamos mostrando en el botón, si estamos mostrando la imagen “plegar.gif” la persiana está desplegada, y si estamos mostrando la imagen “desplegar.gif” la persiana está plegada. Como se puede observar en la imagen la persiana tiene dos botones más, un ancla y un aspa. El ancla lo veremos en el siguiente ejercicio, mientras que la funcionalidad del aspa será cerrar la persiana. Para cerrar la persiana sólo tendremos que cambiarle los siguientes estilos: El estilo position lo pondremos absolute, de esta forma lo desanclaremos del resto de la página. El estilo visibility lo pondremos hidden para que se oculte. 4.- Trabajar con eventos En este ejercicio seguiremos dándole nuevas funcionalidades a la persiana del ejercicio anterior. En concreto, haremos que se pueda arrastrar la persiana por la ventana, pulsando y arrastrando sobre el título. Para hacer esto, tendremos que crear manejadores de eventos para los siguientes elementos: El elemento texto_titulo_persiana: onmousedown: en este manejador de evento se desanclará la persiana del contenido de la página poniendo el estilo position a absolute y se iniciará el movimiento de la persiana. Para controlar cuando se está moviendo la persiana, podemos mantener una variable global que nos lo indique. Además, colocaremos el centro del título de la persiana en la posición del cursor del ratón. El código para obtener la posición del cursor del ratón es el siguiente (se proporciona la función dame_posicion_scroll_Y): Funciones de apoyo: function getStyle(elemento, propiedadCss) { var valor = ""; if(document.defaultView && document.defaultView.getComputedStyle) { valor = document.defaultView.getComputedStyle(elemento,'').getPropertyValue(pr opiedadCss); } else if(elemento.currentStyle) { propiedadCss = propiedadCss.replace(/\-(\w)/g, function (strMatch, p1) {return p1.toUpperCase();}); valor = elemento.currentStyle[propiedadCss]; } return valor; } // ------------------------------------------------------------// Función Javascript para unificar el evento en Explorer y Firefox // ------------------------------------------------------------- function formatEvent(evt) { if(!evt) { evt = window.event; evt.charCode = (evt.type=="keypress") ? evt.keyCode:0; evt.eventPhase = 2; evt.isChar = (evt.charCode > 0); evt.pageX = evt.clientX + document.body.scrollLeft; evt.pageY = evt.clientY + document.body.scrollTop; evt.preventDefault = function(){this.returnValue = false;}; if(evt.type == "mouseout") { evt.relatedTarget = evt.toElement; } else if(evt.type == "mouseover") { evt.relatedTarget = evt.fromElement } evt.stopPropagation = function(){this.cancelBuble = true;}; evt.target = evt.srcElement; evt.time = (new Date).getTime(); } return evt; } // ------------------------------------------------------------// Función Javascript que obtiene la posición del scroll vertical // ------------------------------------------------------------- function dame_posicion_scroll_Y() { var posicion_scroll_Y = 0; if (document.body && document.body.scrollTop) // Soporte firefox posicion_scroll_Y = document.body.scrollTop; else if( document.documentElement && document.documentElement.scrollTop) // Soporte Explorer posicion_scroll_Y = document.documentElement.scrollTop; return posicion_scroll_Y; } El elemento document: onmousemove: Si la persiana se está moviendo (la variable global anterior nos lo indica), desplazamos la persiana a la posición del ratón. onmouseup: ponemos la variable que nos indica si la persiana se está moviendo a false. Además, al pulsar sobre el ancla, la persiana se volverá a anclar en el sitio en el que se encontraba poniendo el estilo position a static.