121

I would like to have some functionality by which if I write

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

it will automatically impose the maxlength on the textArea. If possible please do not provide the solution in jQuery.

Note: This can be done if I do something like this:

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

Copied from What is the best way to emulate an HTML input “maxlength” attribute on an HTML textarea?

But the point is I don't want to write onKeyPress and onKeyUp every time I declare a textArea.

Community
  • 1
  • 1
Rakesh Juyal
  • 35,919
  • 68
  • 173
  • 214
  • 4
    maxlenth for textareas is in html5. Right now it works in Chrome but not Firefox. – Dave Dec 20 '10 at 05:59

16 Answers16

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

}
Chris Bier
  • 14,183
  • 17
  • 67
  • 103
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
  • 3
    Josh it seems it will work but will u please explain what this thing will do --- if(/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) { --- – Rakesh Juyal Jul 14 '09 at 14:05
  • That makes sure the maxlength attribute is numeric before assigning the event handler. – Josh Stodola Jul 14 '09 at 14:34
  • I bet this has some problems when the textarea has hard line breaks in it (that is, line breaks explicitly inserted by the user by hitting "return"). Firefox and IE report the text length differently when there are hard line breaks. (At least, I think I remember that.) – Pointy Apr 30 '10 at 20:30
  • 2
    I think I remember what the deal is: either FF or IE (I think it's FF) returns a different string when Javascript checks the "value" attribute than what it sends back to the server when the form is posted! It has something to do with how hard line breaks do/don't get a carriage return character inserted. It's easy to figure out with some debug code on the client and server sides. – Pointy Apr 30 '10 at 20:35
  • Answer updated - changed to additionally handle the `onblur` event to enforce the maxlength when the user tries to paste with the context menu. – Josh Stodola May 06 '10 at 16:42
  • 7
    I switched the order of the alert and the value truncate - in the original order, the onkeyup would alert, causing the control to lose focus and the onblur to fire since the field had not been truncated yet. – GalacticCowboy Jun 09 '10 at 14:37
  • 1
    @JoshStodola - `onblur` will not handle the paste until the user clicks out of the textarea. `onkeyup` will not handle the paste if it is done through a context menu or a browser menu. This approach works if you do not need to screen for paste. See this answer for a timer based approach http://stackoverflow.com/a/10390626/1026459 – Travis J Apr 30 '12 at 21:18
  • @TravisJ "until the user clicks out of the textarea" so what? You can't submit the form without bluring the textarea. – Josh Stodola Apr 30 '12 at 22:03
  • 3
    @JoshStodola - Indeed you cannot. It would really annoy me as a user if I had pasted a whole piece of something in a textarea, clicked submit, and only saw a small portion of it go through without any response. – Travis J Apr 30 '12 at 22:05
  • @JoshStodola It is not working on IE8 when we try to copy paste the text in Area :( – Satish Sharma Jun 14 '13 at 09:43
  • @SatishSharma `"paste"` have its own event and do not trigger `"keypress"` event. When you get the textarea value from inside the `paste` event handler, the innerhtml might be the one before the content has been updated.. Therefore you might need to set a timeout function to execute any validity tests/code based on the textarea's updated value. – Stphane Jun 03 '15 at 12:57
  • This doesn't work like maxlength because when you enter a character in the middle of the input it will delete the last character in the field. It should prevent further input at all. Thanks for the code though this is really nice! – Chris Bier Dec 10 '15 at 04:05
  • I think changing `onkeyup` to `onkeypress`, comparing `this.value.length > (len-1)`, and removing the `substr` line does the trick to solve that issue – Chris Bier Dec 10 '15 at 04:14
81

I know you want to avoid jQuery, but as the solution requires JavaScript, this solution (using jQuery 1.4) is the most consise and robust.

Inspired by, but an improvement over Dana Woodman's answer:

Changes from that answer are: Simplified and more generic, using jQuery.live and also not setting val if length is OK (leads to working arrow-keys in IE, and noticable speedup in 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: Updated version for jQuery 1.7+, using on instead of live

// 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));
    }
});
pjam
  • 6,356
  • 5
  • 30
  • 40
Eirik W
  • 3,086
  • 26
  • 29
  • 1
    Nice Eirik, like the use of live (forgot about it!). – Dana Woodman Aug 08 '11 at 21:40
  • 5
    I found bugs in live() and jQuery have since deprecated it. Use on() instead. If you care why: http://www.britishdeveloper.co.uk/2012/04/jquery-dont-use-bind-and-dont-use-live.html – BritishDeveloper May 10 '12 at 10:30
  • 6
    But if they edited in the middle, this will kill the last character, not the new character, right? – Joe Mabel Jun 06 '12 at 17:13
  • @Joe, this is true using this solution – Chris R Jul 02 '12 at 17:26
  • 6
    Yep used on() and it works like a gem. THanks. here's a modified and tweaked slightly fiddle: http://jsfiddle.net/nXMqc/ – B-Money Sep 26 '12 at 21:39
  • 6
    Problem with slicing is that if you enter characters to the middle, they are inserted and the string is cut from end. If the whole text is not visible at once, this can be confusing. Also using the val(..) function to change the value seems to move the cursor to the end of the string. (if you want to test these with modern browser in fiddle, you need to remove the maxlength attribute - otherwise the browser will enforce the limit). – Juha Palomäki Jan 20 '13 at 23:16
  • If using more recent JQuery, change the first line to this: $(document).on('keyup blur', 'textarea[maxlength]', function () { – Chris Jul 18 '13 at 14:58
33

Update Use Eirik's solution using .live() instead as it is a bit more robust.


Even though you wanted a solution that wasn't using jQuery, I thought I'd add one in for anyone finding this page via Google and looking for a jQuery-esque solution:

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

    });
});

Hope that is useful to you Googlers out there...

actual_kangaroo
  • 5,971
  • 2
  • 31
  • 45
Dana Woodman
  • 4,148
  • 1
  • 38
  • 35
32

HTML5 adds a maxlength attribute to the textarea element, like so:

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

This is currently supported in Chrome 13, FF 5, and Safari 5. Not surprisingly, this is not supported in IE 9. (Tested on Win 7)

james.garriss
  • 12,959
  • 7
  • 83
  • 96
5

This solution avoids the issue in IE where the last character is removed when a character in the middle of the text is added. It also works fine with other browsers.

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

My form validation then deals with any issues where the user may have pasted (only seems to be a problem in IE) text exceeding the maximum length of the textarea.

Chris R
  • 135
  • 2
  • 10
4

This is some tweaked code I've just been using on my site. It is improved to display the number of remaining characters to the user.

(Sorry again to OP who requested no jQuery. But seriously, who doesn't use jQuery these days?)

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

    });
});

Has NOT been tested with international multi-byte characters, so I'm not sure how it works with those exactly.

Simon East
  • 55,742
  • 17
  • 139
  • 133
3

Also add the following event to deal with pasting into the 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
  • 1,836
  • 19
  • 19
2

The maxlength attribute is supported in Internet Explorer 10, Firefox, Chrome, and Safari.

Note: The maxlength attribute of the <textarea> tag is not supported in Internet Explorer 9 and earlier versions, or in Opera.

from HTML maxlength Attribute w3schools.com

For IE8 or earlier versions you have to use the following

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

P.S.

The maxlength attribute of the <input> tag is supported in all major browsers.

from HTML maxlength Attribute w3schools.com

Community
  • 1
  • 1
Eason
  • 76
  • 5
2

You can use jQuery to make it easy and clear

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>

It is tested in Firefox, Google Chrome and Opera

MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
  • I fear that when the handler is executed, `text` is filled with the "value" of the texarea before it has been updated. This means that your test should be `if( text.length +1 > maxlength) {return false;}`. Otherwise, one would only be able to put `maxlength - 1` chars inside `:/` – Stphane Jun 03 '15 at 12:57
  • Your fiddle lets the user enter one more character. IMO, your test should be either `if(text.length+1 > maxlength)` or `if(text.length >= maxlength)`... – Stphane Jun 05 '15 at 08:36
  • Its not working as expected when I copy and paste the content – Ranjit Kumar Sep 14 '15 at 12:13
1

Better Solution compared to trimming the value of the textarea.

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

    if (val.length > maxlength) {
        return false;
    }
});
Bharat
  • 3,491
  • 1
  • 22
  • 22
0

I implemented maxlength behaviour on textarea recently, and run into problem described in this question: Chrome counts characters wrong in textarea with maxlength attribute.

So all implementations listed here will work little buggy. To solve this issue I add .replace(/(\r\n|\n|\r)/g, "11") before .length. And kept it in mind when cuting string.

I ended with something like this:

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

Don't sure if it solves problem completely, but it works for me for now.

Community
  • 1
  • 1
Roman Pominov
  • 1,403
  • 1
  • 12
  • 17
0

Try this jQuery which works in IE9, FF, Chrome and provides a countdown to users:

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

Try to use this code example:

$("#TextAreaID1").bind('input propertychange', function () {
    var maxLength = 4000;
    if ($(this).val().length > maxLength) {
        $(this).val($(this).val().substring(0, maxLength));
    }
});
AlexVogel
  • 10,601
  • 10
  • 61
  • 71
naveen
  • 1
  • 1
0

2022 Update

You can set the HTML attribute for "maxlength" with the property maxLength (note the uppercase L). You might end up on this page if you were trying to use maxlength (all lowercase) and it wasn't working.

textareaElement1.maxLength = 50;
textareaElement2.maxLength = 150;
textareaElement3.maxLength = 250;

If you wanted to programmatically do it to all existing textareas, you could just iterate over a getElementsByTagName result:

const textAreas = document.getElementsByTagName('textarea');
for (const element of textAreas) {
    element.maxLength = 150;
}
Darren S
  • 516
  • 4
  • 8
0

Small problem with code above is that val() does not trigger change() event, so if you using backbone.js (or another frameworks for model binding), model won't be updated.

I'm posting the solution worked great for me.

$(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
  • 19,453
  • 9
  • 63
  • 86
-1

This is much easier:

<textarea onKeyPress="return ( this.value.length < 1000 );"></textarea>
Chris Bier
  • 14,183
  • 17
  • 67
  • 103
erdomester
  • 11,789
  • 32
  • 132
  • 234
  • 2
    Note that this solution doesn't fully replicate `maxlength` because you can paste strings in that are longer than the desired length. – Chris Bier Dec 10 '15 at 03:52