javascripttextarea

Find out the 'line' (row) number of the cursor in a textarea


I would like to find out and keep track of the 'line number' (rows) of the cursor in a textarea. (The 'bigger picture' is to parse the text on the line every time a new line is created/modified/selected, if of course the text was not pasted in. This saves parsing the whole text un-necessarily at set intervals.)

There are a couple of posts on StackOverflow however none of them specifically answer my question, most questions are for cursor position in pixels or displaying lines numbers besides the textarea.

My attempt is below, it works fine when starting at line 1 and not leaving the textarea. It fails when clicking out of the textarea and back onto it on a different line. It also fails when pasting text into it because the starting line is not 1.

My JavaScript knowledge is pretty limited.

<html>

<head>
<title>DEVBug</title>

<script type="text/javascript">

    var total_lines = 1; // total lines
    var current_line = 1; // current line
    var old_line_count;

    // main editor function
    function code(e) {

        // declare some needed vars
        var keypress_code = e.keyCode; // key press
        var editor = document.getElementById('editor'); // the editor textarea
        var source_code = editor.value; // contents of the editor

        // work out how many lines we have used in total    
            var lines = source_code.split("\n");
            var total_lines = lines.length;

    // do stuff on key presses
    if (keypress_code == '13') { // Enter
        current_line += 1;
    } else if (keypress_code == '8') { // Backspace
        if (old_line_count > total_lines) { current_line -= 1; }
    } else if (keypress_code == '38') { // Up
        if (total_lines > 1 && current_line > 1) { current_line -= 1; }
    } else if (keypress_code == '40') { // Down
        if (total_lines > 1 && current_line < total_lines) { current_line += 1; }
    } else {
        //document.getElementById('keycodes').innerHTML += keypress_code;
    }

    // for some reason chrome doesn't enter a newline char on enter
    // you have to press enter and then an additional key for \n to appear
    // making the total_lines counter lag.
    if (total_lines < current_line) { total_lines += 1 };

    // putput the data
    document.getElementById('total_lines').innerHTML = "Total lines: " + total_lines;
    document.getElementById('current_line').innerHTML = "Current line: " + current_line;

    // save the old line count for comparison on next run
    old_line_count = total_lines;

}

</script>

</head>

<body>

<textarea id="editor" rows="30" cols="100" value="" onkeydown="code(event)"></textarea>
<div id="total_lines"></div>
<div id="current_line"></div>

</body>

</html>

Solution

  • You would want to use selectionStart to do this:

    function getLineNumber(textarea, indicator) {
        indicator.innerHTML = textarea.value.substr(0, textarea.selectionStart).split("\n").length;
    }
    <textarea onkeyup="getLineNumber(this, document.getElementById('lineNo'));" onmouseup="this.onkeyup();"></textarea>
    <div id="lineNo"></div>

    This works when you change the cursor position using the mouse as well.