Como impor maxlength em textArea em HTML usando JavaScript

116

Eu gostaria de ter alguma funcionalidade pela qual, se eu escrever

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

ele irá impor automaticamente o maxlength no textArea. Se possível, não forneça a solução em jQuery.

Observação: isso pode ser feito se eu fizer algo assim:

<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 Qual é a melhor maneira de emular um atributo “maxlength” de entrada HTML em uma área de texto HTML?

Mas a questão é que não quero escrever onKeyPress e onKeyUp toda vez que declaro uma textArea.

Rakesh Juyal
fonte
4
maxlenth para textareas está em html5. No momento, ele funciona no Chrome, mas não no Firefox.
Dave

Respostas:

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
fonte
3
Josh, parece que vai funcionar, mas você vai explicar o que isso vai fazer --- if (/ ^ [0-9] + $ /. Test (txts [i] .getAttribute ("maxlength"))) {- -
Rakesh Juyal
2
Acho que me lembro qual é o problema: FF ou IE (acho que é FF) retorna uma string diferente quando o Javascript verifica o atributo "valor" do que o que envia de volta para o servidor quando o formulário é postado! Tem algo a ver com a forma como as quebras de linha fazem / não inserem um caractere de retorno de carro. É fácil descobrir com algum código de depuração no lado do cliente e do servidor.
Pointy
7
Troquei a ordem do alerta e o valor truncado - na ordem original, o onkeyup alertaria, fazendo com que o controle perdesse o foco e o onblur fosse disparado, pois o campo ainda não havia sido truncado.
GalacticCowboy
1
@JoshStodola - onblurnão manipulará a colagem até que o usuário clique para sair da área de texto. onkeyupnão irá lidar com a colagem se for feito por meio de um menu de contexto ou um menu do navegador. Essa abordagem funciona se você não precisar filtrar para colar. Veja esta resposta para uma abordagem baseada em cronômetro stackoverflow.com/a/10390626/1026459
Travis J
3
@JoshStodola - Certamente você não pode. Eu realmente ficaria chateado como usuário se eu colasse um pedaço inteiro de algo em uma área de texto, clicasse em enviar e visse apenas uma pequena parte passar sem qualquer resposta.
Travis J
80

Eu sei que você quer evitar jQuery, mas como a solução requer JavaScript, esta solução (usando jQuery 1.4) é a mais consistente e robusta.

Inspirado, mas uma melhoria em relação à resposta de Dana Woodman:

As mudanças dessa resposta são: simplificadas e mais genéricas, usando jQuery.live e também não definindo val se o comprimento estiver OK (leva a teclas de seta funcionais no IE e aumento perceptível no 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));
    }
});

EDIT: versão atualizada para jQuery 1.7+ , usando em onvez 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
fonte
1
Eirik legal, gosto do uso de live (esqueci!).
Dana Woodman
5
Encontrei bugs no live () e o jQuery o tornou obsoleto desde então. Em vez disso, use em (). Se você se importa por quê: britishdeveloper.co.uk/2012/04/…
BritishDeveloper
6
Mas se eles editarem no meio, isso vai matar o último personagem, não o novo personagem, certo?
Joe Mabel
6
Sim, usei em () e funciona como uma joia. Obrigado. aqui está um violino ligeiramente modificado e ajustado: jsfiddle.net/nXMqc
B-Money
6
O problema com o fatiamento é que, se você inserir caracteres no meio, eles serão inseridos e o barbante será cortado no final. Se todo o texto não estiver visível de uma vez, isso pode ser confuso. Usar também a função val (..) para alterar o valor parece mover o cursor para o final da string. (se você quiser testá-los com um navegador moderno no fiddle, você precisa remover o atributo maxlength - caso contrário, o navegador aplicará o limite).
Juha Palomäki de
33

Atualizar Use a solução de Eirik usando .live(), pois é um pouco mais robusta.


Mesmo que você quisesse uma solução que não usasse jQuery, pensei em adicionar uma para qualquer pessoa que encontrasse esta página por meio do Google e estivesse procurando uma solução 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 isso seja útil para vocês, Googlers ...

Dana Woodman
fonte
1
A função de limite de keyup deve ser: $ (this) .val ($ (this) .val (). Slice (0, maxlength));
Brian Vallelunga
@brian Sim, você está correto. Obrigado por detectar meu erro, corrigido!
Dana Woodman
$ (this) .val (function (i, val) {return val.slice (0, maxlength)});
Dima Bildin
este trecho ainda é útil, pois os feeds de linha são contados como 1 caractere no navegador e 2 no servidor ...
bebbo
32

HTML5 adiciona um maxlengthatributo ao textareaelemento, assim:

<!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>

Atualmente, isso é compatível com o Chrome 13, FF 5 e Safari 5. Não é de surpreender que isso não seja compatível com o IE 9. (Testado no Win 7)

james.garriss
fonte
5

Essa solução evita o problema no IE, onde o último caractere é removido quando um caractere no meio do texto é adicionado. Também funciona bem com outros 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" );
});

Minha validação de formulário lida com quaisquer problemas em que o usuário possa ter colado (apenas parece ser um problema no IE) texto excedendo o comprimento máximo da textarea.

Chris R
fonte
4

Este é um código ajustado que acabei de usar no meu site. Foi aprimorado para exibir o número de caracteres restantes para o usuário.

(Desculpe novamente para OP que não solicitou jQuery. Mas, falando sério, quem não usa jQuery atualmente?)

$(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");

    });
});

NÃO foi testado com caracteres internacionais de bytes múltiplos, então não tenho certeza de como funciona exatamente com eles.

Simon East
fonte
2

Também adicione o seguinte evento para lidar com a colagem na textarea:

...

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
fonte
Alguém poderia adicionar isso ao corpo da resposta se achar que está tudo bem? Não tenho pontos suficientes para fazer isso ainda.
stusherwin
A função de colar não é padronizada. Acredito que só funcione no IE.
Josh Stodola
Atualizei minha resposta para lidar com a situação de colar. Obrigado!
Josh Stodola
2

O atributo maxlength é compatível com Internet Explorer 10, Firefox, Chrome e Safari.

Nota: O atributo maxlength da <textarea>tag não é compatível com o Internet Explorer 9 e versões anteriores ou no Opera.

do atributo HTML maxlength w3schools.com

Para o IE8 ou versões anteriores, você deve usar o seguinte

//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);
        }
    });
}

PS

O atributo maxlength da <input>tag é compatível com todos os principais navegadores.

do atributo HTML maxlength w3schools.com

Eason
fonte
1

Melhor solução em comparação com o corte do valor da textarea.

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

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

Você pode usar jQuery para torná-lo fácil e claro

JSFiddle DEMO

<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>

É testado em Firefox, Google ChromeeOpera

MaxEcho
fonte
Temo que, quando o manipulador é executado, texté preenchido com o "valor" da texarea antes de ser atualizado. Isso significa que seu teste deve ser if( text.length +1 > maxlength) {return false;}. Caso contrário, só seria possível colocar maxlength - 1chars dentro:/
Stphane
Seu violino permite que o usuário insira mais um caractere. IMO, seu teste deve ser if(text.length+1 > maxlength)ou if(text.length >= maxlength)...
Stphane
Não está funcionando como esperado quando copio e colo o conteúdo
Ranjit Kumar,
0

O pequeno problema com o código acima é que val () não aciona o evento change (), então se você usar backbone.js (ou outra estrutura para vinculação de modelo), o modelo não será atualizado.

Estou postando que a solução funcionou muito bem para mim.

$(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
fonte
0

Implementei o maxlengthcomportamento textarearecentemente e encontrei o problema descrito nesta pergunta: o Chrome conta os caracteres errados em textarea com o atributo maxlength .

Portanto, todas as implementações listadas aqui funcionarão com poucos erros. Para resolver este problema, acrescento .replace(/(\r\n|\n|\r)/g, "11")antes .length. E tenha isso em mente ao cortar cordas.

Eu terminei com algo assim:

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)));
}

Não tenho certeza se isso resolve o problema completamente, mas funciona para mim por enquanto.

Roman Pominov
fonte
0

Experimente este jQuery que funciona no IE9, FF, Chrome e fornece uma contagem regressiva para os usuários:

$("#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 King
fonte
0

Tente usar este exemplo de código:

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

Isso é muito mais fácil:

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

erdomester
fonte
2
Observe que esta solução não replica totalmente maxlengthporque você pode colar strings que são mais longas do que o comprimento desejado.
Chris Bier