views:

504

answers:

3

I am aware that it's possible to emulate the maxlength property from input elements on a textarea by using this trick:

<textarea rows="5" cols="30" onkeydown="return checkLength(this)"></textarea>

<script type="text/javascript">
var maxLength = 30;

function checkLength(elem) {
  if (elem.value.length == maxLength) {
    return false;
  }
  return true;
}
</script>

By using checkLenght's return value as the return value for the onkeydown event, I'm able to effectively prevent the user from writing beyond the configured limit, as the event chain will be broken before the inputted letter appears.

I've tried the same technique using Prototype's event observers, but it didn't work. Here's a simplified version of what I tried:

<textarea rows="5" cols="30" id="myTextArea"></textarea>

<script type="text/javascript">
var maxLength = 30;

function checkLength() {
  if ($('myTextArea').value.length == maxLength)) {
    return false;
  }
  return true;
}

document.observe('dom:loaded',function(){
  $('myTextArea').observe('keydown',checkLength);
});
</script>

Apparently, this won't work because I can't break the event chain by returning false (and Event.stop() will only prevent this event from bubbling up, not stopping execution altogether).

I've workarounded this problem by checking the textarea's length on the onkeyup event and trimming its value if the limit is exceeded; but it isn't the same, as the user will see text appearing and disappearing.

Is there a way to achieve the same result?

+1  A: 

The documentation states that Event#stop stops propagation as well as prevents default action. Does it not work?

Also, binding it to keydown/keyup doesn't prevent them from pasting large amount of text in the text area.

Like Joel said in his comment, preventing users from typing may not be a good idea. It is much better to put a validation + warning (like in the comment field of Stackoverflow).

Chetan Sastry
It did work! I forgot to set `event` as the argument to `Event.stop()`. Regarding your comment about pasting a large amount of text, I took that into account and trim the text on the `keyup` event. But now that I think of it, maybe I should also do that on the `onclick` event.
Boro
You can never handle all the cases. Users can add text by right-click-paste or even by selecting and dragging text from other applications. And god knows what other ways they have customized their computers to allow them to enter data (virtual keyboard for example).
Chetan Sastry
A: 

Consider the other answers and comments. Better make a post-validation and just don't accept the post.

Nonetheless the following should work (it does in FF and IE, in Opera it doesn't. Can't be bothered to check why)

<textarea rows="5" cols="30" id="myTextArea"></textarea>
<script type="text/javascript">
    var maxLength = 30;
    Event.observe('myTextArea', 'keydown', function (event) {
     if ($('myTextArea').value.length == maxLength) {
      Event.stop(event);
      return false;
     }
    });
</script>
jitter
Well, it did work after all! I just forgot to set `event` as the argument to `Event.stop()`.
Boro
I always cringe a little when I see `stop()` or similar in key events. Consider the fact that, depending on browser, you're also blocking system/application keyboard commands. It's a simple check to see that, for instance, `ctrl` and `alt` are not pressed (and system is not Mac) or `cmd` and `ctrl` are not pressed (and system is Mac).Another concern is that you are preventing the user from replacing any content, by blocking the `delete` and `backspace` keys, as well as any typing that would replace selected text.
eyelidlessness
Well that's exactly why you shouldn't do this at all
jitter
A: 

Use setInterval to periodically check state of your textarea, trim text if you want.

Anatoliy