Introducción
Si de algo no cabe duda es que en los últimos años las interfaces web han ido poco a poco enriqueciéndose, ajustándose a las necesidades del usuario y mejorando la experienciade mismo a la hora de usar la aplicación.
Poco a poco, los grandes sitios como Facebook o Yahoo! han ido modificando los controles aburridos y sosos estándar de HTML para hacerlos más vistosos, y sobre todo, más usables.
Cada vez son más los sitios web que incorporan mejoras y nuevos controles alternativos a los básicos que HTML ofrece.
Así pues no es raro, sino bastante típico encontrarse controles como campos de texto con autocompletado de palabras, o textareas que se ajustan en altura, y nosotros, no deberíamos quedarnos atrás.
Al finalizar este tutorial, serás capaz de implementar controles del tipo textarea que crezcan automáticamente en altura dentro de tu sitio web gracias a jQuery.
¿Cómo funcionará nuestro textarea?
La verdad es que como siempre, buscando por internet he visto varios métodos para crear este tipo de controles. La primera solución con la que me encontré, y la primera que me vino a la cabeza, se basaba en la creación de un temporizador que revisaba cada X milisegundos el texto contenido en el textarea y ajustaba su altura.
No era mala idea, pero continué buscando, ya que nunca me acabaron de convencer los timers en Javascript.
La segunda solución que encontré se basaba en la escucha de los eventos keypress y la propiedad scrollHeight del textarea para así ajustar la altura.
Para que el textarea se ajuste al tamaño de texto, dos cosas son importantes: el eventokeypress y la propiedad scrollHeight.
Me pareció una mejor solución, pero al implementarlo no me acaba de convencer, ya que su funcionamiento no era todo lo fino que esperaba.
Al final una idea surgió en mi cabeza para mejorar el script, por lo que dejé de googlear y me puse manos a la obra para probar si funcionaría.
Mi idea era básicamente hacer un clon del textarea, exactamente con las mismas propiedades pero oculto y un poco menos ancho que el original. Luego, en cada pulsación de tecla en el textarea original, copiamos el texto al clon; de forma que en el clon, al ser mas estrecho saltará antes la barra de scroll y por lo tanto sabemos que ya podemos incrementar la altura de nuestro textarea original.
No se si existen mejores soluciones, pero para mí, fue la que mejor resultado me dió a la hora de implementarlo en Erasmusu, proyecto propio en el que trabamos desde los inicios deCokidoo.
Como siempre, veremos paso a paso cómo crear un textarea que crezca automáticamente en altura. ¡Vamos a ello!
Estructura pincipal
Como comentaba en la introducción, emplearemos jQuery para el desarrollo. La idea es que sea fácil de implementar en cualquier web, crearemos nuestro código como un plugin para jQuery. Si no sabes cómo se crean, puedes revisar el tutorial Cómo crear un Plugin para jQuery.
La estructura principal será pues la siguiente:
- (function($){
- $.fn.extend({
- autoResize: function(options){
- this.each(function(){
- /*Código aquí*/
- });
- }
- })
- }(jQuery));
De esta forma podremos transformar nuestros controles del tipo textarea por defecto en textareas dinámicos:
- $(SELECTOR).autoResize();
Echemos un vistazo a las opciones que tendrá nuestro plugin…
Opciones que se aceptarán
Para hacer un poco más dinámico el plugin y le pueda ser útil a más gente, se van a añadir unas cuantas opciones para poder personalizar un poco su funcionamiento y ajustarse a las necesidades de cada uno. Las opciones que aceptará son las siguientes:
- (int) maxHeight – Maximo en altura que podrá alcanzar, luego se aplicará scrollbar.
- (int) minHeight – Altura que tomará al coger el foco.
- (string) textHold – Texto que se mostrará cuando esté vacío y sin foco.
- (string) activeClass – Clase que se añadirá cuando recibe el foco.
Ninguna de las opciones anteriores es obligatoria, podemos optar por no configurarlas.
Paso 1: Recogiendo las opciones de forma adecuada
Lo primero que debe de hacer nuestro código es recoger y preparar de forma adecuada las opciones del plugin para que no salten errores en la siguiente ejecución del código.
Para ello creamos un nuevo objeto que recoge los valores que se pasan a la función o un valor predeterminado en su defecto.
- //Si no se envía nada, se crea un objeto vacío para que no de error a continuación
- if(!options){
- options = {};
- }
- //Almacena las opciones pasadas a la función o valores predeterminados en su defecto
- var _options = {
- //Maximo en altura que podrá alcanzar, luego se aplicará scrollbar
- maxHeight: options.maxHeight || null,
- //Altura que tomará al coger el foco
- minHeight: options.minHeight || null,
- //Texto que se mostrará cuando esté vacío y sin foco
- textHold: options.textHold || null,
- //Clase que se añadirá cuando recibe el foco
- activeClass: options.activeClass || null
- };
Paso 2: Crear el clon
Una vez tenemos la información preparada, llega el momento de crear el código que será ejecutado para cada textarea seleccionado con el selector de jQuery. Recordad, este código va dentro del this.each();.
Aquí se encuentra el código para crear el clon y las subscripciones a los eventos necesarias para el funcionamiento.
- //Encapsulamos con jQuery
- var $this = $(this);
- //Establece el texto por defecto si ha sido establecido
- if($this.val() == "" && _options.textHold){
- $this.val(_options.textHold);
- }
- //Guarda la altura inicial
- $this.initHeight = $this.css("height");
- //Establece el atributo CSS overflow según el caso
- if(_options.maxHeight){
- $this.css("overflow", "auto");
- }else{
- $this.css("overflow", "hidden");
- }
- //Para guardar el texto y comparar si hay cambios
- var _value = null;
- //Crea el clon del textarea
- var $clon = $this.clone(true);
- //Establece propiedades del clon y lo añade al DOM
- $clon.css({
- visibility: "hidden",
- position: "absolute",
- top: 0,
- overflow: "hidden",
- width: parseInt($this.width())-10
- });
- $clon.attr("name","");
- $clon.attr("id", "");
- $this.parent().append($clon);
- //Aux
- var clon = $clon[0];
- var me = $this;
- //Eventos del textarea
- $this.bind("keyup" , autoFit)
- .bind("focus", function(){})
- .bind("blur", function(){});
- function autoFit(force){}
Como podéis ver, estamos dejando algunas partes del código simplemente con comentarios, no te preocupes, las iremos rellenando a continuación.
Paso 3: Rellenando los eventos
El evento focus
En este evento insertaremos el código que realice las siguientes tareas:
- Comprobar si el texto que contiene el es mismo que el establecido mediante la opciontextHold, en dicho caso se borrará para comenzar a escribir.
- Cambiar la altura a la establecida en la opcion minHeight
- Añadir la clase establecida en la opcion activeClass
El código es el siguiente:
- if(_options.textHold){
- if(this.value == _options.textHold){
- this.value = "";
- }
- }
- if(_options.minHeight){
- me.css("height", _options.minHeight+"px");
- $clon.css("height", _options.minHeight+"px");
- autoFit(true);
- }
- if(_options.activeClass){
- me.addClass(_options.activeClass);
- }
Nada complicado, ¿no? Vamos a por el siguiente evento.
El evento blur
Cuando el textarea pierde el foco, tiene que deshacer algunas características establecidas en el evento focus:
- Volver a poner el texto textHold en caso de que el valor esté vacío
- Quitar la clase activeClass previamente añadida
- if(_options.textHold){
- if(this.value == ""){
- this.value = _options.textHold;
- if(_options.minHeight && me.initHeight){
- $clon.css("height", me.initHeight);
- me.css("height", me.initHeight);
- autoFit();
- }
- }
- }else{
- if(_options.minHeight && me.initHeight){
- $clon.css("height", me.initHeight);
- me.css("height", me.initHeight);
- autoFit();
- }
- }
- if(_options.activeClass){
- me.removeClass(_options.activeClass);
- }
Una vez tenemos definido el comportamiento en ambos eventos, vamos a ver qué hará la función autoFit().
Paso 4: La función autoFit
Esta es la función que se encarga de ajustar el tamaño del textarea, comprobando siempre si el clon ha cambiado de tamaño o no. En realidad, lo que se comprueba del clon, es la propiedad scrollHeight, que nos devuelve el alto en pixels de la zona de scroll.
Es decir, el textarea puede tener por ejemplo 100px de scrollHeight y sólo 50px de height, lo que quiere decir que los otros 50px del textarea están ocultos.
La propiedad scrollHeight nos devuelve el alto total en pixels del contenido del elemento HTML.
Lo único que hace esta función es establecer el alto del textarea al scrollHeight sabiendo que el clon siempre va a ir un paso por delante al ser más estrecho que el original.
La función también tiene que encargarse de controlar el alto máximo y evitar que el textarea siga creciendo:
- clon.value = me.val();
- //Comprueba si ha cambiado el valor del textarea
- if (_value != clon.value || force===true){
- _value = clon.value;
- var h = clon.scrollHeight;
- if(_options.maxHeight && h > _options.maxHeight){
- me.css("height", options.maxHeight + "px");
- }else{
- me.css("height", parseInt(h) + "px");
- }
- }
Paso 5: Probando nuestro plugin con ejemplos…
Una vez hemos visto paso a paso cómo crear el plugin, os dejo con dos ejemplos de uso:
- $("textarea").autoResize();
En este primer ejemplo, estamos activando el plugin para todos los textarea de nuestra página.
- $("textarea").autoResize({textHold: "Escribe aquí tu texto", minHeight: 40, maxHeight: 400, activeClass: "active"});
En este segundo ejemplo estamos activando el plugin para todos los textarea y además estableciendo un texto por defecto, una altura mínima, una altura máxima y aplicando una clase de css “active” con la que podemos dar estilo a nuestro textarea.
Reflexión final
Bueno esto ha sido todo, espero que os resulte útil el tutorial y sobretodo os aporte a vuestra vida dura vida como programadores
.
No dudéis en preguntar en los comentarios o incluso sugerir nuevas aportaciones o ideas para próximos tutoriales.
¡Nos vemos en la próxima publicación!
No hay comentarios:
Publicar un comentario