views:

63

answers:

2

Hello. I got a strange requirement:

function TextLimit(elem, maxChars) { ... }

Where elem is a textarea or input of type=text and maxChars is the maximum number of characters that could go into the elem. The code inside the function must limit the length of the text inside elem to maxChars when the user is typing. However, if the user is pasting for the first time, the elem must take everything that was pasted even if the pasted text has more characters then maxChars. EDIT: If the pasted text is longer then maxChars, then after pasting for the first time, the user can't type/paste anymore, unless the text is deleted/backspaced to a length smaller then maxChars.

Any suggestions using plain JavaScript or jQuery would be appreciated.

The maxlenght attribute doesn't allow for pasting. Setting/removing it programmaticaly on paste, doesn't work well in all browsers. Taking substring of elem's value on keydown/keypress/keyup produces some funky results.

+1  A: 

Something like this seems to work:

Couple of things to work out still, like allowing the delete key if the max is reached. Should be easy fixes though.

Try it out: http://jsfiddle.net/wxUZz/7/ (updated)

function TextLimit(elem, maxChars) {
    var permittedKeys = [8,37,38,39,40,46];

    elem.focus(function() {
        if(elem.val().length >= maxChars) {
            elem.data('prevent', true);
            elem.data('value', elem.val());
        }
    });

    elem.blur(function() {
        if( elem.data('prevent') ) {
            elem.val( elem.data('value') );
        }
    });

    elem.keydown(function(event) {
        var count = elem.val().length;
        if(count >= maxChars && $.inArray(event.which, permittedKeys) < 0) {
            elem.data('prevent', true);
            elem.data('value', elem.val());
            return false;
        } else {
            elem.data('prevent', false);
        }
    });  
}

TextLimit($('#myTextarea'), 30);
patrick dw
Thank you, Patrick. But, this is not exactly what I'm looking for. If the pasted text is longer then maxChars, then the user can't input anymore, either by typing nor by pasting. Let me modify my question to reflect this.
Dimskiy
@dimskiy - I updated the example: http://jsfiddle.net/wxUZz/2/ Give it a try.
patrick dw
@Patrick - Backspace has funky behavior, if I highlight all pasted input and then backspace it, I can't type/paste anything in unless I hit backspace again on an empty textarea. Also, the code seems to limit to maxChars+1 Otherwise, I think you're getting close. I like how it's not using the paste event :)
Dimskiy
@dimskiy - I've made a couple changes, but will take another look. I only tested for delete, not backspace. Be back in a few minutes...
patrick dw
@dimskiy - Updated and simplified a bit. Give it a try.http://jsfiddle.net/wxUZz/5/
patrick dw
@patrick - I appreciate your help. I'm leaving the office, will check it out from home in a few hours. Thank you!
Dimskiy
@dimskiy - Sounds good. I updated again http://jsfiddle.net/wxUZz/7/. There was trouble with pasting via the GUI. I made it so that if you paste via the GUI (no key event) when the max has already been reached/exceeded, the textarea will revert back to its old value on blur. This also takes care of 2 pastes in a row via the GUI. The one that exceeds the max will be retained. The second one will be removed on blur.
patrick dw
This is it! Thank you very much, Patrick.
Dimskiy
@dimskiy - You're welcome. :o)
patrick dw
+1  A: 

There is a nice blog article which covers this topic.

Russell Dias
Thank you for you answer. Interesting implementation, but not exactly what I was looking for. On a side note, as with some other implementations that I've seen in the past couple of days, I don't like how it displays the maxlength+1 character after it was typed in and then removes it.
Dimskiy