2009-02-17 28 views
31

Estoy buscando un javascript que pueda limitar el número de líneas (por línea quiero decir algún texto terminado por el usuario presionando enter en el teclado) el usuario puede ingresar en textarea. He encontrado algunas soluciones, pero simplemente no funcionan o se comportan de manera extraña. La mejor solución sería un plugin de jquery que pueda hacer el trabajo, algo así como CharLimit, pero debería poder limitar el recuento de líneas de texto, no el recuento de caracteres.Limitando el número de líneas en el área de texto

Gracias de antemano.

+3

Definir "línea". ¿Líneas visibles? Líneas delimitadas por un '\ n' o algo más? – alphadogg

Respuesta

22

Este fuerza ayuda (probablemente sea mejor usando jQuery, onDomReady y añadiendo discretamente el evento KeyDown para el área de texto), pero probado en IE7 y FF3:

<html> 
    <head><title>Test</title></head> 
    <body> 
    <script type="text/javascript"> 
     var keynum, lines = 1; 

     function limitLines(obj, e) { 
     // IE 
     if(window.event) { 
      keynum = e.keyCode; 
     // Netscape/Firefox/Opera 
     } else if(e.which) { 
      keynum = e.which; 
     } 

     if(keynum == 13) { 
      if(lines == obj.rows) { 
      return false; 
      }else{ 
      lines++; 
      } 
     } 
     } 
     </script> 
    <textarea rows="4" onkeydown="return limitLines(this, event)"></textarea> 
    </body> 
</html> 

* Editar - Explicación: Se llama la pulsación de tecla si se presiona la tecla ENTER y simplemente no agrega una nueva línea si las líneas en el área de texto son del mismo número que las filas del área de texto. De lo contrario, aumenta el número de líneas.

+4

Esto tiene un problema cuando el usuario presiona el retroceso que lleva a la eliminación de toda la línea, lo que limitará el número de filas disponibles para escribir, y posiblemente elimine todas las filas dejando solo una línea para escribir. Tampoco está funcionando bien cuando el usuario ingresa una gran cantidad de caracteres que hacen que se mueva a una nueva línea, pero luego la línea creada no se cuenta para limitar la línea. –

+0

Muchas gracias marktucks – Visme

+1

también falla en pegar. – Anas

3

El número de líneas visibles/de visualización para un bloque de texto determinado puede variar según los diferentes navegadores, las fuentes utilizadas, etc. Debería establecer una fuente y un tamaño de fuente específicos, como mínimo, para poder cuenta de manera semifalible las líneas de visualización.

ACTUALIZACIÓN: Veo la edición. Entonces, algo como el código de kevchadders debería funcionar bien para ti. Necesitará js que cuente caracteres y '\ r \ n's y compruebe contra un límite definido por el usuario. Además, si no utiliza su secuencia de comandos, asegúrese de utilizar una que implique una verificación de intervalo de tiempo y/o los eventos onKeyDown/onKeyUp del área de texto. Esta puede ser la razón por la que algunos scripts que ha probado parecen "comportarse de manera extraña".

+0

Parece que se ha editado la pregunta sobre ti;) Línea == "\ n" –

1

Esto es básicamente lo mismo que la respuesta de Ivan, usando jQuery. Lo probé para un proyecto propio; parece funcionar bien

<script type="text/javascript" charset="utf-8"> 
    $(function() 
    { 
    function getLines(id) 
    { 
     return $('#' + id).val().split("\n").length 
    } 

    $('#testing').keyup(function() 
    { 
    var allowedNumberOfLines = 4; 

    if(getLines('testing') > allowedNumberOfLines) 
    { 
     modifiedText = $(this).val().split("\n").slice(0, allowedNumberOfLines); 
     $(this).val(modifiedText.join("\n")); 
    } 
    }); 
}); 
</script> 
+0

getLines (id) debe ser getLines (el) donde $ ('# testing') se envía directamente a la función getLines. Una optimización fácil. – jamtoday

+1

Pero, ¿funciona esto con palabras ajustadas automáticamente a medida que escribe? Tu función solo depende de nuevas líneas. – acme

14

Cómo hacerlo con jQuery:

Enlazar a keyDown caso de área de texto.

function limitTextareaLine(e) { 
    if(e.keyCode == 13 && $(this).val().split("\n").length >= $(this).attr('rows')) { 
     return false; 
    } 
} 
+0

Hola Maciej, gracias por la respuesta. ¿Puedes dar un ejemplo de esto por favor? – chainwork

+0

@chainwork Claro. [Ejemplo] (http://jsbin.com/ufeyom/2/edit) – Maciej

+7

Esta estrategia falla cuando el usuario pega nuevas líneas en el área de texto. –

3

(Hecho con jquery). No es perfecto, pero le importa envolverse. No dependiendo del final de la línea (\ n).
jquery scroll event tiene problemas en mozilla y firefox si la propiedad de desbordamiento de css en textarea no es automática; de lo contrario, elimine las líneas correspondientes y establezca el desbordamiento oculto. Podría ayudar a redimensionar el css: ninguno y altura fija.

$('#textarea').scroll(function() { 
    $(this).css("overflow", "hidden");  /* for the mozilla browser problem */ 
    $(this).animate({scrollTop: $(this).outerHeight()}); 
    while ($(this).scrollTop() > 0) {  /* for the copy and paste case */    
     lines=$(this).val().slice(0,-1); 
     $(this).val(lines); 
    } 
    $(this).css("overflow", "auto");  /* For the mozilla browser problem */ 
}); 
0

Lo extendí un poco para detectar incluso el desbordamiento sin un salto de línea manual. Esto es para un área de texto de tamaño fijo con "desbordamiento: oculto".

Por el momento, mi solución hace que la fuente sea más pequeña si no se ajusta a textarea. Y lo hace más grande de nuevo si es posible.

var keynum, allowedLines = 5, defaultFontSize = 13/*px*/; 

$(document).ready(function() { 
    $("textarea").keydown(function(e, obj) { 
     if(window.event) 
      keynum = e.keyCode; 
     else if (e.which) 
      keynum = e.which; 

     if (keynum == 13 && allowedLines <= $(this).val().split("\n").length) 
      return false; 
    }); 
    $("textarea").keyup(function(e, obj) { 
     // Avoid copy-paste 
     if (allowedLines < $(this).val().split("\n").length) {    
      lines = $(this).val().split("\n").slice(0, allowedLines); 
      $(this).val(lines.join('\n')); 
     } 

     // Check overflow 
     if ((this.clientHeight < this.scrollHeight)) { 
      while ((this.clientHeight < this.scrollHeight)) { 
       currFontSize = $(this).css('font-size'); 
       finalNum = parseFloat(currFontSize, 11); 
       stringEnding = currFontSize.slice(-2); 
       $(this).css('font-size', (finalNum-1) + stringEnding); 
      } 
     } else if ($(this).css('fontSize') != defaultFontSize+'px') { 
      while ($(this).css('font-size') != defaultFontSize+'px') { 
       // First lets increase the font size 
       currFontSize = $(this).css('font-size'); 
       finalNum = parseFloat(currFontSize, 11); 
       stringEnding = currFontSize.slice(-2); 
       $(this).css('font-size', (finalNum+1) + stringEnding); 
       // lets loop until its enough or it gets overflow again 
       if(this.clientHeight < this.scrollHeight) { 
        // there was an overflow and we have to recover the value 
        $(this).css('font-size', currFontSize); 
        break; 
       } 
      } 
     } 
    }); 
}); 
4

Esta solución funciona:

<script type="text/javascript"> 
    function limitTextarea(textarea, maxLines, maxChar) { 
     var lines = textarea.value.replace(/\r/g, '').split('\n'), lines_removed, char_removed, i; 
     if (maxLines && lines.length > maxLines) { 
      lines = lines.slice(0, maxLines); 
      lines_removed = 1 
     } 
     if (maxChar) { 
      i = lines.length; 
      while (i-- > 0) if (lines[i].length > maxChar) { 
       lines[i] = lines[i].slice(0, maxChar); 
       char_removed = 1 
      } 
      if (char_removed || lines_removed) { 
       textarea.value = lines.join('\n') 
      } 
     } 
    } 
</script> 

y el texto área sería

<asp:TextBox ID="myWishTB" runat="server" Height="185px" TextMode="MultiLine" 
      Style="overflow: auto;" Width="95%" 
      onkeyup="limitTextarea(this,10,80)"> 
</asp:TextBox> 

en HTML normal:

<textarea id="textareaID" onkeyup="limitTextarea(this,5,100)" cols="20" rows="5"> </textarea> 
1

ejemplo jQuery. Esto funciona tanto para escribir como para pegar.

//Limit to # of rows in textarea or arbitrary # of rows 
    $('#yourtextarea').bind('change keyup', function(event) { 
    //Option 1: Limit to # of rows in textarea 
    rows = $(this).attr('rows'); 
    //Optiion 2: Limit to arbitrary # of rows 
    rows = 6; 

    var value = ''; 
    var splitval = $(this).val().split("\n"); 

    for(var a=0;a<rows && typeof splitval[a] != 'undefined';a++) { 
     if(a>0) value += "\n"; 
     value += splitval[a]; 
    } 
    $(this).val(value); 
    }); 
Cuestiones relacionadas