Cómo imponer maxlength en textArea en HTML usando JavaScript

116

Me gustaría tener alguna funcionalidad por la cual si escribo

<textarea maxlength="50"></textarea>
<textarea maxlength="150"></textarea>
<textarea maxlength="250"></textarea>

impondrá automáticamente el maxlength en el textArea. Si es posible, no proporcione la solución en jQuery.

Nota: Esto se puede hacer si hago algo como esto:

<textarea onkeypress="return imposeMaxLength(event, this, 110);" rows="4" cols="50">

function imposeMaxLength(Event, Object, MaxLen)
{
    return (Object.value.length <= MaxLen)||(Event.keyCode == 8 ||Event.keyCode==46||(Event.keyCode>=35&&Event.keyCode<=40))
}

Copiado de ¿Cuál es la mejor manera de emular un atributo "maxlength" de entrada HTML en un área de texto HTML?

Pero el punto es que no quiero escribir onKeyPress y onKeyUp cada vez que declaro un textArea.

Rakesh Juyal
fuente
4
maxlenth para textareas está en html5. Ahora mismo funciona en Chrome pero no en Firefox.
Dave

Respuestas:

113
window.onload = function() { 
  var txts = document.getElementsByTagName('TEXTAREA'); 

  for(var i = 0, l = txts.length; i < l; i++) {
    if(/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) { 
      var func = function() { 
        var len = parseInt(this.getAttribute("maxlength"), 10); 

        if(this.value.length > len) { 
          alert('Maximum length exceeded: ' + len); 
          this.value = this.value.substr(0, len); 
          return false; 
        } 
      }

      txts[i].onkeyup = func;
      txts[i].onblur = func;
    } 
  };

}
Josh Stodola
fuente
3
Josh, parece que funcionará, pero ¿podrías explicar qué hará esto --- if (/ ^ [0-9] + $ /. Test (txts [i] .getAttribute ("maxlength"))) {- -
Rakesh Juyal
2
Creo recordar cuál es el trato: FF o IE (creo que es FF) devuelve una cadena diferente cuando Javascript verifica el atributo "valor" que lo que envía de vuelta al servidor cuando se publica el formulario. Tiene algo que ver con la fuerza con la que los saltos de línea hacen / no consiguen insertar un carácter de retorno de carro. Es fácil de entender con algún código de depuración en el lado del cliente y del servidor.
Puntiagudo
7
Cambié el orden de la alerta y el valor truncar; en el orden original, el onkeyup alertaría, haciendo que el control perdiera el foco y el onblur se disparara ya que el campo aún no se había truncado.
GalacticCowboy
1
@JoshStodola: onblurno manejará el pegado hasta que el usuario haga clic fuera del área de texto. onkeyupno manejará el pegado si se hace a través de un menú contextual o un menú del navegador. Este enfoque funciona si no necesita filtrar para pegar. Vea esta respuesta para un enfoque basado en temporizador stackoverflow.com/a/10390626/1026459
Travis J
3
@JoshStodola - De hecho, no puedes. Realmente me molestaría como usuario si hubiera pegado una parte completa de algo en un área de texto, hubiera hecho clic en enviar y solo hubiera visto una pequeña parte sin respuesta.
Travis J
80

Sé que desea evitar jQuery, pero como la solución requiere JavaScript, esta solución (usando jQuery 1.4) es la más consistente y robusta.

Inspirado por, pero una mejora con respecto a la respuesta de Dana Woodman:

Los cambios de esa respuesta son: Simplificado y más genérico, usando jQuery.live y tampoco estableciendo val si la longitud está bien (conduce a teclas de flecha de trabajo en IE y una aceleración notable en IE):

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').live('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});

EDITAR: Versión actualizada para jQuery 1.7+ , usando en onlugar delive

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').on('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});
Eirik W
fuente
1
Buen Eirik, como el uso de live (¡lo olvidé!).
Dana Woodman
5
Encontré errores en live () y jQuery lo ha desaprobado desde entonces. Use on () en su lugar. Si le importa por qué: britishdeveloper.co.uk/2012/04/…
BritishDeveloper
6
Pero si editaron en el medio, esto matará al último personaje, no al nuevo personaje, ¿verdad?
Joe Mabel
6
Sí, usado en () y funciona como una joya. Gracias. aquí hay un violín ligeramente modificado y ajustado: jsfiddle.net/nXMqc
B-Money
6
El problema con el corte es que si ingresa caracteres en el medio, se insertan y la cadena se corta desde el final. Si no se ve todo el texto a la vez, esto puede resultar confuso. Además, el uso de la función val (..) para cambiar el valor parece mover el cursor al final de la cadena. (si desea probarlos con el navegador moderno en violín, debe eliminar el atributo maxlength; de lo contrario, el navegador impondrá el límite).
Juha Palomäki
33

Actualización Utilice la solución de Eirik en su .live()lugar, ya que es un poco más robusta.


Aunque querías una solución que no usara jQuery, pensé en agregar una para cualquiera que encuentre esta página a través de Google y busque una solución al estilo de jQuery:

$(function() {        
    // Get all textareas that have a "maxlength" property.
    $('textarea[maxlength]').each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field.
        var maxlength = $textarea.attr('maxlength');
        var val = $textarea.val();

        // Trim the field if it has content over the maxlength.
        $textarea.val(val.slice(0, maxlength));

        // Bind the trimming behavior to the "keyup" event.
        $textarea.bind('keyup', function() {
            $textarea.val($textarea.val().slice(0, maxlength));
        });

    });
});

Espero que les sea útil a los empleados de Google ...

Dana Woodman
fuente
1
La función enlazada de keyup debe ser: $ (this) .val ($ (this) .val (). Slice (0, maxlength));
Brian Vallelunga
@brian Sí, tienes razón. Gracias por detectar mi error, ¡solucionado!
Dana Woodman
$ (this) .val (function (i, val) {return val.slice (0, maxlength)});
Dima Bildin
este fragmento sigue siendo útil ya que los avances de línea se cuentan como 1 carácter en el navegador y 2 en el servidor ...
bebbo
32

HTML5 agrega un maxlengthatributo al textareaelemento, así:

<!DOCTYPE html>
<html>
    <body>
        <form action="processForm.php" action="post">
            <label for="story">Tell me your story:</label><br>
            <textarea id="story" maxlength="100"></textarea>
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

Actualmente, esto es compatible con Chrome 13, FF 5 y Safari 5. No es sorprendente que esto no sea compatible con IE 9. (Probado en Win 7)

james.garriss
fuente
5

Esta solución evita el problema en IE donde se elimina el último carácter cuando se agrega un carácter en el medio del texto. También funciona bien con otros navegadores.

$("textarea[maxlength]").keydown( function(e) {
    var key = e.which;  // backspace = 8, delete = 46, arrows = 37,38,39,40

    if ( ( key >= 37 && key <= 40 ) || key == 8 || key == 46 ) return;

    return $(this).val().length < $(this).attr( "maxlength" );
});

La validación de mi formulario se ocupa de cualquier problema en el que el usuario haya pegado (solo parece ser un problema en IE) texto que exceda la longitud máxima del área de texto.

Chris R
fuente
4

Este es un código modificado que acabo de usar en mi sitio. Se ha mejorado para mostrar el número de caracteres restantes al usuario.

(Lo siento nuevamente por OP que no solicitó jQuery. Pero en serio, ¿quién no usa jQuery en estos días?)

$(function() {
    // Get all textareas that have a "maxlength" property.
    $("textarea[maxlength]").each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field
        var maxlength = $textarea.attr("maxlength");

        // Add a DIV to display remaining characters to user
        $textarea.after($("<div>").addClass("charsRemaining"));

        // Bind the trimming behavior to the "keyup" & "blur" events (to handle mouse-based paste)
        $textarea.on("keyup blur", function(event) {
            // Fix OS-specific line-returns to do an accurate count
            var val = $textarea.val().replace(/\r\n|\r|\n/g, "\r\n").slice(0, maxlength);
            $textarea.val(val);
            // Display updated count to user
            $textarea.next(".charsRemaining").html(maxlength - val.length + " characters remaining");
        }).trigger("blur");

    });
});

NO se ha probado con caracteres internacionales de varios bytes, por lo que no estoy seguro de cómo funciona exactamente con ellos.

Simon East
fuente
2

También agregue el siguiente evento para lidiar con pegar en el área de texto:

...

txts[i].onkeyup = function() {
  ...
}

txts[i].paste = function() {
  var len = parseInt(this.getAttribute("maxlength"), 10);

  if (this.value.length + window.clipboardData.getData("Text").length > len) {
    alert('Maximum length exceeded: ' + len);
    this.value = this.value.substr(0, len);
    return false;
  }
}

...
Stusherwin
fuente
¿Alguien podría agregar esto al cuerpo de la respuesta si cree que está bien? Todavía no tengo suficientes puntos para hacer eso.
stusherwin
La función de pegar no está estandarizada. Creo que solo funciona en IE.
Josh Stodola
Actualicé mi respuesta para manejar la situación del pegado. ¡Gracias!
Josh Stodola
2

El atributo maxlength es compatible con Internet Explorer 10, Firefox, Chrome y Safari.

Nota: El atributo maxlength de la <textarea>etiqueta no se admite en Internet Explorer 9 y versiones anteriores, ni en Opera.

del atributo HTML maxlength w3schools.com

Para IE8 o versiones anteriores, debe usar lo siguiente

//only call this function in IE
function maxLengthLimit($textarea){
    var maxlength = parseInt($textarea.attr("maxlength"));
    //in IE7,maxlength attribute can't be got,I don't know why...
    if($.browser.version=="7.0"){
        maxlength = parseInt($textarea.attr("length"));
    }
    $textarea.bind("keyup blur",function(){
        if(this.value.length>maxlength){
            this.value=this.value.substr(0,maxlength);
        }
    });
}

PD

El atributo maxlength de la <input>etiqueta es compatible con todos los navegadores principales.

del atributo HTML maxlength w3schools.com

Eason
fuente
1

Mejor solución en comparación con recortar el valor del área de texto.

$('textarea[maxlength]').live('keypress', function(e) {
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    if (val.length > maxlength) {
        return false;
    }
});
Bharat
fuente
1

Puede usar jQuery para hacerlo fácil y claro

DEMO de JSFiddle

<textarea id="ta" max="10"></textarea>

<script>
$("#ta").keypress(function(e){

    var k = e.which==0 ? e.keyCode : e.which;
    //alert(k);
    if(k==8 || k==37 || k==39 || k==46) return true;

    var text      = $(this).val();
    var maxlength = $(this).attr("max");

    if(text.length >= maxlength) {
        return false;   
    }
    return true;
});
</script>

Se ensayó en Firefox, Google ChromeyOpera

MaxEcho
fuente
Me temo que cuando se ejecuta el controlador, textse llena con el "valor" del texarea antes de que se haya actualizado. Esto significa que su prueba debería ser if( text.length +1 > maxlength) {return false;}. De lo contrario, solo se podrían poner maxlength - 1caracteres dentro:/
Stphane
Su violín le permite al usuario ingresar un carácter más. En mi opinión, su prueba debería ser if(text.length+1 > maxlength)o if(text.length >= maxlength)...
Stphane
No funciona como se esperaba cuando copio y pego el contenido
Ranjit Kumar
0

El pequeño problema con el código anterior es que val () no activa el evento change (), por lo que si usa backbone.js (u otros marcos para el enlace de modelos), el modelo no se actualizará.

Estoy publicando que la solución funcionó muy bien para mí.

$(function () {

    $(document).on('keyup', '.ie8 textarea[maxlength], .ie9 textarea[maxlength]', function (e) {
        var maxLength = $(this).attr('maxlength');
        if (e.keyCode > 47 && $(this).val().length >= maxLength) {
            $(this).val($(this).val().substring(0, maxLength)).trigger('change');
        }
        return true;
    });

});
Alexander Beletsky
fuente
0

Implementé el maxlengthcomportamiento textarearecientemente y encontré el problema descrito en esta pregunta: Chrome cuenta los caracteres incorrectamente en el área de texto con el atributo maxlength .

Entonces, todas las implementaciones enumeradas aquí funcionarán con pocos errores. Para solucionar este problema agrego .replace(/(\r\n|\n|\r)/g, "11")antes .length. Y tenlo en cuenta al cortar hilo.

Terminé con algo como esto:

var maxlength = el.attr("maxlength");
var val = el.val();
var length = val.length;
var realLength = val.replace(/(\r\n|\n|\r)/g, "11").length;
if (realLength > maxlength) {
    el.val(val.slice(0, maxlength - (realLength - length)));
}

No estoy seguro si resuelve el problema por completo, pero me funciona por ahora.

Roman Pominov
fuente
0

Pruebe este jQuery que funciona en IE9, FF, Chrome y proporciona una cuenta regresiva a los usuarios:

$("#comments").bind("keyup keydown", function() {
    var max = 500;
    var value = $(this).val();
    var left = max - value.length;
    if(left < 0) {
        $(this).val( value.slice(0, left) );
        left = 0;
    }
    $("#charcount").text(left);
}); 

<textarea id="comments" onkeyup="ismaxlength(this,500)"></textarea>
<span class="max-char-limit"><span id="charcount">500</span> characters left</span>
Leslie rey
fuente
0

Intente utilizar este ejemplo de código:

$("#TextAreaID1").bind('input propertychange', function () {
    var maxLength = 4000;
    if ($(this).val().length > maxLength) {
        $(this).val($(this).val().substring(0, maxLength));
    }
});
naveen
fuente
-1

Esto es mucho más fácil:

<textarea onKeyPress="return ( this.value.length < 1000 );"></textarea>

erdomester
fuente
2
Tenga en cuenta que esta solución no se replica completamente maxlengthporque puede pegar cadenas que sean más largas que la longitud deseada.
Chris Bier