Comment imposer maxlength sur textArea en HTML à l'aide de JavaScript

116

Je voudrais avoir une fonctionnalité par laquelle si j'écris

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

il imposera automatiquement la longueur maximale au textArea. Si possible, veuillez ne pas fournir la solution dans jQuery.

Remarque: cela peut être fait si je fais quelque chose comme ceci:

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

Copié depuis Quelle est la meilleure façon d'émuler un attribut «maxlength» d'entrée HTML sur une zone de texte HTML?

Mais le fait est que je ne veux pas écrire onKeyPress et onKeyUp chaque fois que je déclare un textArea.

Rakesh Juyal
la source
4
maxlenth pour textareas est en html5. À l'heure actuelle, cela fonctionne dans Chrome mais pas dans Firefox.
Dave

Réponses:

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
la source
3
Josh, il semble que cela fonctionnera mais vous expliquerez ce que cette chose va faire --- if (/ ^ [0-9] + $ /. Test (txts [i] .getAttribute ("maxlength"))) {- -
Rakesh Juyal le
2
Je pense que je me souviens de ce qu'est l'affaire: soit FF, soit IE (je pense que c'est FF) renvoie une chaîne différente lorsque Javascript vérifie l'attribut "valeur" que ce qu'il renvoie au serveur lorsque le formulaire est posté! Cela a quelque chose à voir avec la façon dont les sauts de ligne durs font / ne font pas insérer un caractère de retour chariot. C'est facile à comprendre avec du code de débogage côté client et côté serveur.
Pointy
7
J'ai changé l'ordre de l'alerte et la valeur tronquée - dans l'ordre d'origine, le onkeyup alerterait, provoquant la perte de focus du contrôle et le déclenchement du onblur puisque le champ n'avait pas encore été tronqué.
GalacticCowboy
1
@JoshStodola - onblurne gérera pas la pâte jusqu'à ce que l'utilisateur clique hors de la zone de texte. onkeyupne gérera pas le collage s'il est effectué via un menu contextuel ou un menu du navigateur. Cette approche fonctionne si vous n'avez pas besoin de filtrer pour coller. Voir cette réponse pour une approche basée sur la minuterie stackoverflow.com/a/10390626/1026459
Travis J
3
@JoshStodola - En effet, vous ne pouvez pas. En tant qu'utilisateur, cela m'ennuierait vraiment si j'avais collé un morceau entier de quelque chose dans une zone de texte, cliqué sur Soumettre et n'en ai vu qu'une petite partie sans aucune réponse.
Travis J
80

Je sais que vous voulez éviter jQuery, mais comme la solution nécessite JavaScript, cette solution (utilisant jQuery 1.4) est la plus solide et la plus robuste.

Inspiré par, mais une amélioration par rapport à la réponse de Dana Woodman:

Les changements par rapport à cette réponse sont: Simplifié et plus générique, en utilisant jQuery.live et en ne définissant pas val si la longueur est OK (conduit au fonctionnement des touches fléchées dans IE et à une accélération notable dans 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: version mise à jour pour jQuery 1.7+ , en utilisant onau lieu 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
la source
1
Nice Eirik, comme l'utilisation du live (oublié!).
Dana Woodman
5
J'ai trouvé des bogues dans live () et jQuery l'ont depuis déconseillé. Utilisez plutôt sur (). Si vous vous souciez pourquoi: britishdeveloper.co.uk/2012/04
BritishDeveloper
6
Mais s'ils ont édité au milieu, cela tuera le dernier personnage, pas le nouveau personnage, non?
Joe Mabel
6
Oui utilisé sur () et cela fonctionne comme un bijou. Merci. voici un violon légèrement modifié et peaufiné: jsfiddle.net/nXMqc
B-Money
6
Le problème avec le tranchage est que si vous entrez des caractères au milieu, ils sont insérés et la chaîne est coupée à partir de la fin. Si tout le texte n'est pas visible à la fois, cela peut prêter à confusion. Utiliser également la fonction val (..) pour changer la valeur semble déplacer le curseur à la fin de la chaîne. (si vous voulez les tester avec un navigateur moderne en violon, vous devez supprimer l'attribut maxlength - sinon le navigateur appliquera la limite).
Juha Palomäki
33

Mise à jour Utilisez la solution d'Eirik à la .live()place car elle est un peu plus robuste.


Même si vous vouliez une solution qui n'utilisait pas jQuery, j'ai pensé en ajouter une pour quiconque trouve cette page via Google et recherche une solution jQuery-esque:

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

    });
});

J'espère que cela vous sera utile, les Googleurs ...

Dana Woodman
la source
1
La fonction liée au keyup doit être: $ (this) .val ($ (this) .val (). Slice (0, maxlength));
Brian Vallelunga
@brian Yup, vous avez raison. Merci d'avoir repéré mon erreur, corrigé!
Dana Woodman
$ (this) .val (function (i, val) {return val.slice (0, maxlength)});
Dima Bildin du
cet extrait est toujours utile car les
sauts de
32

HTML5 ajoute un maxlengthattribut à l' textareaélément, comme ceci:

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

Ceci est actuellement pris en charge dans Chrome 13, FF 5 et Safari 5. Sans surprise, cela n'est pas pris en charge dans IE 9. (Testé sur Win 7)

james.garriss
la source
5

Cette solution évite le problème dans IE où le dernier caractère est supprimé lorsqu'un caractère au milieu du texte est ajouté. Cela fonctionne également très bien avec d'autres navigateurs.

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

Ma validation de formulaire traite alors tous les problèmes où l'utilisateur peut avoir collé (cela ne semble être un problème que dans IE) du texte dépassant la longueur maximale de la zone de texte.

Chris R
la source
4

C'est un code modifié que je viens d'utiliser sur mon site. Il est amélioré pour afficher le nombre de caractères restants à l'utilisateur.

(Désolé encore pour OP qui n'a pas demandé de jQuery. Mais sérieusement, qui n'utilise pas jQuery de nos jours?)

$(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'a PAS été testé avec des caractères internationaux multi-octets, donc je ne sais pas comment cela fonctionne exactement avec ceux-ci.

Simon Est
la source
2

Ajoutez également l'événement suivant pour gérer le collage dans la zone de texte:

...

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
la source
Quelqu'un pourrait-il ajouter ceci au corps de la réponse s'il pense que c'est correct? Vous n'avez pas encore assez de points pour le faire.
stusherwin
La fonction coller n'est pas standardisée. Je crois que cela ne fonctionne que dans IE.
Josh Stodola
J'ai mis à jour ma réponse pour gérer la situation de collage. Je vous remercie!
Josh Stodola
2

L'attribut maxlength est pris en charge dans Internet Explorer 10, Firefox, Chrome et Safari.

Remarque: l' attribut maxlength de la <textarea>balise n'est pas pris en charge dans Internet Explorer 9 et les versions antérieures, ni dans Opera.

à partir de l' attribut HTML maxlength w3schools.com

Pour IE8 ou les versions antérieures, vous devez utiliser les éléments suivants

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

L'attribut maxlength de la <input>balise est pris en charge dans tous les principaux navigateurs.

à partir de l' attribut HTML maxlength w3schools.com

Eason
la source
1

Meilleure solution par rapport à la réduction de la valeur de la zone de texte.

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

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

Vous pouvez utiliser jQuery pour le rendre simple et clair

DÉMO 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>

Il est testé dans Firefox, Google ChromeetOpera

MaxEcho
la source
Je crains que lorsque le gestionnaire est exécuté, textsoit rempli avec la "valeur" du texarea avant qu'il n'ait été mis à jour. Cela signifie que votre test devrait être if( text.length +1 > maxlength) {return false;}. Sinon, on ne pourrait mettre que des maxlength - 1caractères à l'intérieur:/
Stphane
Votre violon permet à l'utilisateur d'entrer un caractère supplémentaire. OMI, votre test devrait être soit if(text.length+1 > maxlength)ou if(text.length >= maxlength)...
Stphane
Cela ne fonctionne pas comme prévu lorsque je copie et colle le contenu
Ranjit Kumar
0

Le petit problème avec le code ci-dessus est que val () ne déclenche pas l'événement change (), donc si vous utilisez backbone.js (ou un autre framework pour la liaison de modèle), le modèle ne sera pas mis à jour.

Je poste la solution a très bien fonctionné pour moi.

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

});
Alexandre Beletsky
la source
0

J'ai implémenté un maxlengthcomportement textarearécemment et j'ai rencontré un problème décrit dans cette question: Chrome compte des caractères erronés dans la zone de texte avec l'attribut maxlength .

Donc, toutes les implémentations listées ici fonctionneront peu de bugs. Pour résoudre ce problème, j'ajoute .replace(/(\r\n|\n|\r)/g, "11")avant .length. Et gardé cela à l'esprit lors de la coupe de ficelle.

J'ai terminé avec quelque chose comme ça:

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

Je ne sais pas si cela résout complètement le problème, mais cela fonctionne pour moi pour le moment.

Roman Pominov
la source
0

Essayez ce jQuery qui fonctionne dans IE9, FF, Chrome et fournit un compte à rebours aux utilisateurs:

$("#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
la source
0

Essayez d'utiliser cet exemple de code:

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

C'est beaucoup plus simple:

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

erdomester
la source
2
Notez que cette solution ne se réplique pas complètement maxlengthcar vous pouvez coller des chaînes plus longues que la longueur souhaitée.
Chris Bier