Mati Tucci
Mati Tucci

Reputation: 2976

Get how many lines a textarea has

Using javascript how can I get how many lines a textarea has? in this example I should get 4 (without reading the rows attr)

<textarea rows="4">Long text here foo bar lorem ipsum Long text here foo bar lorem ipsum Long text here foo bar</textarea>

Also, the text area can have a different style than the default one.

Any help? Thanks!

Upvotes: 4

Views: 1664

Answers (1)

skyline3000
skyline3000

Reputation: 7913

This is a very difficult problem because you can't call getBoundingClientRect() on a range within an <input> or <textarea> element (all browsers return 0s for the rect). See: How to get the bounding rect of selected text inside an <input>?

However, you can "clone" the node as a <div>, copy over the <textarea>'s computed style and text, and find the rects using the <div>. You can get the height of all of the text and divide it by the height of just one character in the selection (the line-height).

I had to do this for a project for work and this was the only reliable way to find geometry information about text inside <input> and <textarea> elements.

const clone = document.createElement('div');
const range = document.createRange();
const textarea = document.querySelector('textarea');

let rect = textarea.getBoundingClientRect();
let lineHeight;
let totalHeight;

// "Clone" the textarea and add it into the DOM
clone.style.cssText = window.getComputedStyle(textarea).cssText;
clone.style.left = rect.left + 'px';
clone.style.position = 'absolute';
clone.style.top = rect.top + 'px';
clone.textContent = textarea.value;
document.body.appendChild(clone);

// Determine the number of visible rows
range.setStart(clone.firstChild, 0);
range.setEnd(clone.firstChild, 1);
rect = range.getBoundingClientRect();
lineHeight = rect.height;

range.setEnd(clone.firstChild, clone.textContent.length);
rect = range.getBoundingClientRect();
totalHeight = rect.height;

console.log(totalHeight / lineHeight);

document.body.removeChild(clone);
<textarea rows="4">Long text here foo bar lorem ipsum Long text here foo bar lorem ipsum Long text here foo bar</textarea>

Upvotes: 3

Related Questions