Prevent user from writing more than N characters in a textarea using Prototype event observers

javascript, prototypejs

Solution

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>

Problem

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?

Original source