Plugin jQuery: textarea con cuenta de caracteres

  • Por
Segundo ejemplo de plugin práctico en jQuery para hacer textarea que lleva la cuenta de los caracteres escritos por el usuario.
Este es un taller práctico sobre jQuery que esperamos sirva para que las personas puedan continuar aprendiendo la manera de crear sus propios plugins. Como ya sabemos, los plugins son una manera óptima de programar tus scripts jQuery, ya que permitirán solucionar sus necesidades y además crear código limpio y reutilizable.

En los dos artículos anteriores ya estuvimos hablando de los Plugins en jQuery y de las reglas fundamentales para desarrollarlos. También vimos un primer ejemplo de un plugin sencillo, que espero nos haya abierto las miras y dado una idea sobre las posibilidades de construcción de componentes para páginas web. En este artículo continuaremos ofreciendo ejemplos para reforzar lo aprendido y para que las personas puedan familiarizarse aun más con el modo de creación de plugins en jQuery.

El objetivo del ejemplo que ocupará este artículo es la creación de un plugin para conseguir que un campo textarea de formulario informe en todo momento de caracteres que ha escrito el usuario. Es decir, vamos a hacer un método del objeto jQuery que servirá para decirle a los campos de texto textarea que se expandan para convertirse en un textarea que cuente los caracteres en una capa de texto de al lado.

Para tener una idea exacta de nuestros objetivos podemos ver el ejemplo en marcha que vamos a desarrollar.

Entendamos el plugin textarea con contador de caracteres

Para hacer los textareas que cuenten caracteres nosotros queremos hacer algo como esto en jQuery.

$("textarea").cuentaCaracteres();

Con eso queremos conseguir que a todos los textareas del documento HTML les aparezca una información al lado con el número de caracteres que tenga el textarea escrito dentro. Esa cuenta de caracteres debe mostrarse nada más cargarse la página y actualizarse cuando se escriba algo dentro. Todo eso se automatizará, para que no tengamos que hacer nada, salvo la anterior llamada al plugin.

Entonces, dentro del plugin tenemos que hacer varias cosas.

  1. Un bucle con each para recorrer todos los objetos que pueda haber en el objeto jQuery que reciba el método para activar este plugin. Este paso es igual en todos los plugins.
  2. Dentro de ese bucle podemos iterar con todos los elementos que haya en el objeto jQuery, que vamos a suponer son textareas. Vamos a crear un nuevo elemento DIV sobre la macha y vamos a iniciarlo con el texto de la cuenta de caracteres actual del textarea. Ese elemento creado "on the fly" lo añadiremos al cuerpo de la página, justo después de la etiqueta del textarea.
  3. Además, haremos un evento, para que cuando el usuario escriba algo en el textarea, el texto con la cuenta de caracteres se actualice automáticamente.

Estos tres pasos serían un resumen del funcionamiento del plugin, cuyo código completo podemos ver a continuación.

//creo el plugin cuentaCaracteres
jQuery.fn.cuentaCaracteres = function() {
   //para cada uno de los elementos del objeto jQuery
   this.each(function(){
      //creo una variable elem con el elemento actual, suponemos un textarea
      elem = $(this);
      //creo un elemento DIV sobre la marcha
      var contador = $('<div>Contador caracteres: ' + elem.attr("value").length + '</div>');
      //inserto el DIV después del elemento textarea
      elem.after(contador);
      //guardo una referencia al elemento DIV en los datos del objeto jQuery
      elem.data("campocontador", contador);
      
      //creo un evento keyup para este elemento actual
      elem.keyup(function(){
         //creo una variable elem con el elemento actual, suponemos un textarea
         var elem = $(this);
         //recupero el objeto que tiene el elemento DIV contador asociado al textarea
         var campocontador = elem.data("campocontador");
         //modifico el texto del contador, para actualizarlo con el número de caracteres escritos
         campocontador.text('Contador caracteres: ' + elem.attr("value").length);
      });
   });
   //siempre tengo que devolver this
   return this;
};

El código está comentado para que se pueda entender mejor. Quizás nos pueda llamar más la atención la línea donde se utiliza la función jQuery para generar sobre la marcha un objeto jQuery con el campo DIV con el que vamos a seguir la cuenta. Vemos que a través del método attr() accedemos al value del textarea y con la propiedad length a su longitud en caracteres.

var contador = $('<div>Contador caracteres: ' + elem.attr("value").length + '</div>');

Luego también puede que nos llame la atención el funcionamiento del método data(), que nos permite almacenar y recuperar datos que se guardarán en el propio objeto jQuery de cada textarea.

Así guardo una referencia al objeto con la capa contador en el textarea, en un dato llamado "campocontador".

elem.data("campocontador", contador);

Y con este otro código en el evento recupero esa capa, pues luego en el evento tengo que cambiar el contenido con la cuenta de caracteres actualizada.

var campocontador = elem.data("campocontador");

Una vez creado el plugin, convierto todos los textareas en textareas-contador de caracteres, con este código:

$(document).ready(function(){
   $("textarea").cuentaCaracteres();
})

Eso es todo, pero quizás se vea más claro si vemos el código completo del ejemplo.

<html>
<head>
<title>Creando plugins en jQuery</title>
   <script src="../jquery-1.4.1.min.js"></script>
<script>

//creo el plugin cuentaCaracteres
jQuery.fn.cuentaCaracteres = function() {
   //para cada uno de los elementos del objeto jQuery
   this.each(function(){
      //creo una variable elem con el elemento actual, suponemos un textarea
      elem = $(this);
      //creo un elemento DIV sobre la marcha
      var contador = $('<div>Contador caracteres: ' + elem.attr("value").length + '</div>');
      //inserto el DIV después del elemento textarea
      elem.after(contador);
      //guardo una referencia al elemento DIV en los datos del objeto jQuery
      elem.data("campocontador", contador);
      
      //creo un evento keyup para este elemento actual
      elem.keyup(function(){
         //creo una variable elem con el elemento actual, suponemos un textarea
         var elem = $(this);
         //recupero el objeto que tiene el elemento DIV contador asociado al textarea
         var campocontador = elem.data("campocontador");
         //modifico el texto del contador, para actualizarlo con el número de caracteres escritos
         campocontador.text('Contador caracteres: ' + elem.attr("value").length);
      });
   });
   //siempre tengo que devolver this
   return this;
};
$(document).ready(function(){
   $("textarea").cuentaCaracteres();
})
</script>
   
</head>
<body>
<form>
      <textarea rows=5 cols=30 id="mitextarea">hola</textarea>
      <br>
      <br>
      <textarea rows=5 cols=30 id="otrotextarea">Otra cuenta...</textarea>
   </form>
</body>
</html>

Este ejemplo se puede ver en una página aparte.

Nota: Si quieres ver más ejemplos prácticos de creación de plugins te recomiendo que leas el Taller de JQuery.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

carlos_de_jesus_castaeda

31/3/2010
Funcionamiento
Muy buen artículo, sin embargo al mostrar el ejemplo en la página aparte no se muestra el funcionamiento, solo aparacen los textarea.
Saludos

midesweb

20/4/2010
Daba un problema con Explorer, que está resuelto
Hola,

Este plugin daba un problema tonto con Internet Explorer, que ya se ha resuelto. El tema era en la etiqueta SCRIPT, que genera mi editor Komodo Edit, que le coloca un atributo que no es compatible con Explorer. Vamos una tontería, pero que hacía que el Explorer no ejecutase ningún código javascript.

<script type="application/x-javascript">

No lo interpreta el Explorer y lo he colocado ahora simplemente como:

<script>

Y ya funcionan los ejemplos.

Gracias por el aviso!

andres

01/8/2012
jumm duda la .......?
he seguido todos los capitulos de este manual... que de hecho agradesco por ello.. pero agradeceria a alguien o a ustedes que me expliquen bien en detalle las lineas codigos del plugin ("donde me confundo"),ps mi pregunta es por que creas el elmento html y despues lo agregas, por que utilizas el data,por que el evento keyup esta dentro del pluging (intente a ver si funcionaba detro de $(document).ready)... pero en si tengo en realidad esa duda.. yo lo tomo si fuera una marca pero me enredo y que diferencia habria entre una capa ya creada en el html(es decir sin haberla creado en jquery).. agradeceria a cualquiera que respoda esta inquietud ..gracias de antemano... por si no quedo claro .. no entiendo en si el funcionamiento plugin(el dat y recuperar con el data)

andres

01/8/2012
Creo que lo entendi.. pero forma correcta?
me levante y me dije debes entederlo y lo hize de dos maneras -pero mi pregunta es correcto en las dos formas de hacerlo o solo en la forma del manual(los dos son funcionales, pero es correcto si/no porque ).. gracias su pronta respuesta:
##############################################
<html lang="es">
<head>
<title>ensayo contador</title>
<script src="jquery/jquery.js" language="javascritp" type="text/javascript"></script>
<script>
jQuery.fn.CampoDatos=function(i){
this.each(function(){
var elem=$(this);
var contador=$('<div>Numero Caracteres: '+elem.attr("value").length+'</div>');
//alert("elemento "+i +" top :"+elem.offset().top+"px left:"+elem.offset().left)
contador.css({
"top":elem.offset().top+"px",
"left":((elem.offset().left+elem.outerWidth())+5)+"px",
"position":"absolute"
});
elem.data("Datos",contador);
$(document.body).append(contador);


});
return this;
};
$(document).ready(function(){
$("textarea").CampoDatos();
$("textarea").keyup(function(){
elem=$(this);
var contador=elem.data("Datos");
contador.html("Numero Caracteres: "+elem.attr("value").length)
});
});
</script>
</head>
<body>
<form>
<textarea name="area1" cols=40 rows=5>escriba algo...</textarea>
<br>
<textarea name="area2" cols=40 rows=5>hola de nuevo...</textarea>
</form>
</body>
</html>


################################################
y la otra precido al del manual pero sin recuperar los datos:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"
>
<html lang="es">
<head>
<title>ensayo contador</title>
<script src="jquery/jquery.js" language="javascritp" type="text/javascript"></script>
<script>
jQuery.fn.CampoDatos=function(i){
this.each(function(){
var elem=$(this);
var contador=$('<div>Numero Caracteres: '+elem.attr("value").length+'</div>');
//alert("elemento "+i +" top :"+elem.offset().top+"px left:"+elem.offset().left)
contador.css({
"top":elem.offset().top+"px",
"left":((elem.offset().left+elem.outerWidth())+5)+"px",
"position":"absolute"
});
elem.data("Datos",contador);
$(document.body).append(contador);

elem.keyup(function(){

contador.html("Numero Caracteres: "+elem.attr("value").length)
});
});
return this;
};
$(document).ready(function(){
$("textarea").CampoDatos();
});
</script>
</head>
<body>
<form>
<textarea name="area1" cols=40 rows=5>escriba algo...</textarea>
<br>
<textarea name="area2" cols=40 rows=5>hola de nuevo...</textarea>
</form>
</body>
</html>
##########################################