Limiting number of lines in textarea

empi picture empi · Feb 17, 2009 · Viewed 87.5k times · Source

I'm looking for a javascript that can limit the number of lines (by line I mean some text ended by user pressing enter on the keyboard) the user is able to enter in textarea. I've found some solutions but they simply don't work or behave really weird. The best solution would be a jquery plugin that can do the work - something like CharLimit, but it should be able to limit text line count not character count.

Answer

marktucks picture marktucks · Feb 17, 2009

This might help (probably be best using jQuery, onDomReady and unobtrusively adding the keydown event to the textarea) but tested in IE7 and FF3:

<html>
  <head><title>Test</title></head>
  <body>
    <script type="text/javascript">
      var keynum, lines = 1;

      function limitLines(obj, e) {
        // IE
        if(window.event) {
          keynum = e.keyCode;
        // Netscape/Firefox/Opera
        } else if(e.which) {
          keynum = e.which;
        }

        if(keynum == 13) {
          if(lines == obj.rows) {
            return false;
          }else{
            lines++;
          }
        }
      }
      </script>
    <textarea rows="4" onkeydown="return limitLines(this, event)"></textarea>
  </body>
</html>

*Edit - explanation: It catches the keypress if the ENTER key is pressed and just doesn't add a new line if the lines in the textarea are the same number as the rows of the textarea. Else it increments the number of lines.

Edit #2: Considering people are still coming to this answer I thought I'd update it to handle paste, delete and cut, as best as I can.

<html>

<head>
    <title>Test</title>
    <style>
        .limit-me {
            height: 500px;
            width: 500px;
        }
    </style>
</head>

<body>
<textarea rows="4" class="limit-me"></textarea>

<script>
    var lines = 1;

    function getKeyNum(e) {
        var keynum;
        // IE
        if (window.event) {
            keynum = e.keyCode;
            // Netscape/Firefox/Opera
        } else if (e.which) {
            keynum = e.which;
        }

        return keynum;
    }

    var limitLines = function (e) {
        var keynum = getKeyNum(e);

        if (keynum === 13) {
            if (lines >= this.rows) {
                e.stopPropagation();
                e.preventDefault();
            } else {
                lines++;
            }
        }
    };

    var setNumberOfLines = function (e) {
        lines = getNumberOfLines(this.value);
    };

    var limitPaste = function (e) {
        var clipboardData, pastedData;

        // Stop data actually being pasted into div
        e.stopPropagation();
        e.preventDefault();

        // Get pasted data via clipboard API
        clipboardData = e.clipboardData || window.clipboardData;
        pastedData = clipboardData.getData('Text');

        var pastedLines = getNumberOfLines(pastedData);

        // Do whatever with pasteddata
        if (pastedLines <= this.rows) {
            lines = pastedLines;
            this.value = pastedData;
        }
        else if (pastedLines > this.rows) {
            // alert("Too many lines pasted ");
            this.value = pastedData
                .split(/\r\n|\r|\n/)
                .slice(0, this.rows)
                .join("\n ");
        }
    };

    function getNumberOfLines(str) {
        if (str) {
            return str.split(/\r\n|\r|\n/).length;
        }

        return 1;
    }

    var limitedElements = document.getElementsByClassName('limit-me');

    Array.from(limitedElements).forEach(function (element) {
        element.addEventListener('keydown', limitLines);
        element.addEventListener('keyup', setNumberOfLines);
        element.addEventListener('cut', setNumberOfLines);
        element.addEventListener('paste', limitPaste);
    });
</script>
</body>
</html>