Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save nicohaemhouts/cd1c95c4e342ff65589b to your computer and use it in GitHub Desktop.

Select an option

Save nicohaemhouts/cd1c95c4e342ff65589b to your computer and use it in GitHub Desktop.
Limit the number of lines in a textarea
<textarea data-limit-rows="true" cols="60" rows="8"></textarea>

Limit the number of lines in a textarea

This limits the number of lines of any textarea that has the attribute 'data-limit-rows' set to 'true'. The limit is the 'rows'-attribute of the textarea.

To know how many lines have been entered you have to look at the number of newline characters (\n) in the text. You could do this by splitting text on the newline character, and looking at the length of the resulting array: i.e. myText.split(/\n/g).length; This would work fine in every browser, except for one special case in Internet Explorer 8, whereby the user hits the enter key several times in a row, thus producing empty lines. In this case Internet Explorer 8 excludes all empty values from the resulting array, ie those places where the delimiters appear next to each other. The result is that the usr can enter more lines of text than permitted. This is probably also true for Internet Explorer versions lower than 8, but I didn't check.

To know which key was pressed it's best to use jQuery's event.which as that means you don't have to bother with charCode and keyCode.

A Pen by Nico Haemhouts on CodePen.

License.

$(document).ready(function () {
$('textarea[data-limit-rows=true]').on('keypress', function (event) {
var textarea = $(this),
numberOfLines = (textarea.val().match(/\n/g) || []).length + 1,
maxRows = parseInt(textarea.attr('rows'));
if (event.which === 13 && numberOfLines === maxRows ) {
return false;
}
});
});
@MadhuSubedi
Copy link

Thank you for the gist. It is useful, How can we limit characters per line in textarea also? Thanks in advance for the solution.

@lazarevkristijan
Copy link

Is there an updated version of this? Or it still wroks

@noahjames404
Copy link

Is there an updated version of this? Or it still wroks

it's 2024, and it still works.

@shinsenter
Copy link

It may not work when copy&paste.

@aranjamestaylor
Copy link

@shinsenter You're right, it doesn't protect against copy and pasting.
However, if you change:
if (event.which === 13 && numberOfLines === maxRows ) {
to
if (event.which === 13 && numberOfLines >= maxRows ) {
it will at least stop any more lines being added. Still not ideal, but a very slight improvement.

@nicohaemhouts
Copy link
Author

Hey 👋

So here is an updated one that can prevent pasting as well using jQuery:

$(document).ready(function () {
  const numberOfLines = (text) => (text.match(/\n/g) || []).length + 1;
  const maxRows = (textarea) => parseInt(textarea.attr('rows'));
  
  $('textarea[data-limit-rows=true]').on('keypress', function (event) {
    const textarea = $(this);
        
    if (event.which === 13 && numberOfLines(textarea.val()) === maxRows(textarea)) {
      return false;
    }
  }).on('paste', function (event) {
    const textarea = $(this),
          pastedText = (event.originalEvent || event).clipboardData.getData('text/plain');   
    
    if (!pastedText || numberOfLines(textarea.val() + pastedText) > maxRows(textarea)) {
      return false
    }    
  });
});

And here is the same without jQuery using just plain JavaScript:

document.addEventListener('DOMContentLoaded', () => {
  const numberOfLines = (text) => (text.match(/\n/g) || []).length + 1;
  const isTextArea = (element) => element.matches('textarea[data-limit-rows=true]');
  const maxRows = (textarea) => parseInt(textarea.getAttribute('rows'));

  document.addEventListener('keypress', (event) => {
    const target = event.target;
    
    if (isTextArea(target) && 
        event.which === 13 && 
        numberOfLines(target.value) === maxRows(target)) {
      
      event.preventDefault(); // Prevents adding more lines
    }
  });

  document.addEventListener('paste', (event) => {
    const target = event.target;
    
    if (isTextArea(target)) {
      const pastedText = (event.clipboardData || window.clipboardData).getData('text/plain');

      if (!pastedText || 
          numberOfLines(target.value + pastedText) > maxRows(target)) {
        
        event.preventDefault(); // Prevents pasting
      }
    }
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment