Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if cursor is on the first line in a textarea (with soft-newlines)

Given a textarea with content that flows like this

     ––––––––––––––––––––––––––
    | This is some text, which |
    | wraps like this.         |
     ––––––––––––––––––––––––––

How can one tell if the text-cursor is on the first line of the textarea?

Obviously, checking for a newline character (\n) works if one wants to see if the cursor appears before the first line break, but testing for a 'soft' line break seems more challenging.

Here is a sample jsFiddle to experiment with.

I have not yet come up with a strategy, but I suspect it may involve copying the text up until the cursor position into a cloned textarea (or div), and making the width as long as it needs to be so it doesn't wrap. If the cloned area has a width less than the original's width, then the cursor would seem to have to be on the first line. There may a simpler option, something more elegant, or (best of all) an existing and well-tested solution.

Target browsers are Webkit (Chrome/Safari) & Firefox. I.e. IE compatibility is not a concern at this time (if that makes any difference).

Thanks for reading.

EDIT: Seeking line number of text caret, not mouse cursor.

falsarella gave an excellent answer, that highlighted an ambiguity in the question. What I am seeking is whether the text cursor (“caret” may be a better word) is on the first line. I have updated the question and the jsFiddle to reflect.

like image 772
Brian M. Hunt Avatar asked Aug 07 '12 17:08

Brian M. Hunt


2 Answers

I only know of one "working method". The method requires use of textarea's "cols" attribute. Long story short, set the cols to the width you want, then divide the cursor position and floor it to see if it is less than 1, thus it = line 1!

Might be easier to explain if I just show you a code example.

$("textarea").live("keyup", function(e) {
    if ($("textarea").attr("cols")) {
        var cols = parseInt($("textarea").attr("cols")),
            curPos = $('textarea').prop("selectionStart"),
            result = Math.floor(curPos/cols);
        var msg = (result < 1) ? "Cursor is on the First line!" : "Cursor is on the line #"+(result+1);
        console.log($("p").text(msg).text());
    };
});​

however, this may still require some wired math as some col sizes may still say "line 2" when the cursor is simply at the END of line one (which technically would still be right since any character would drop to line 2)

jsFiddle

like image 193
SpYk3HH Avatar answered Sep 20 '22 15:09

SpYk3HH


Having that 15 is the line height, this works (tested in firefox):

http://jsfiddle.net/h46jh/12/

$("textarea").click(function (evt) {
  cursor_position = evt.pageY - $('textarea').offset().top;
  if (cursor_position <= 15) {
    alert("first line");
  } else {
    alert("other line");
  }
});

Credits:

Find mouse position relative to element

like image 20
falsarella Avatar answered Sep 17 '22 15:09

falsarella