Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

HTML Line Numbering using textarea

5.00/5 (4 votes)
26 Jul 2019CPOL2 min read 33.6K   639  
HTML line numbering using textarea

Introduction

This is a simple solution for numbering lines in a text in HTML page (i.e., code writing). Since, to my knowledge, there is no HTML element that is offering this possibility by default, I created a small and simple code that perfectly and effectively does the trick, even for very long texts.

Image 1

It uses 2 textarea elements, the right one is for writing or pasting text, and the left one is readonly and populated by JavaScript, it shows the lines of the text. The 2 textarea elements are scroll-synced in the JS code. There is also another element underneath that is showing the current position/selection in the text.

Using the Code

The HTML part is very short, there are 2 textarea elements, wrapped together in a div; the textarea for writing is wrapped together with input element for showing current position/selection in a span - this is purely for easier access to these elements from within the JavaScript code.

HTML
<body onload="initialize()" onresize="onresize_sub()">
    <h1>Line numbering using &lt;textarea&gt;</h1>
    <div>
        <textarea class="rownr" rows="20" 
        cols="3" value="1" readonly></textarea>
        <span>
            <textarea class="txt" rows="20" 
            cols="150" nowrap="nowrap" wrap="off"
            autocomplete="off" autocorrect="off" 
            autocapitalize="off" spellcheck="false"
            onclick="selectionchanged(this)" 
            onkeyup="keyup(this,event)" oninput="input_changed(this)" 
            onscroll="scroll_changed(this)"></textarea><br/><br/>
            <label>Current position: 
            </label><input id="sel_in" style="border-style:none" readonly>
        </span>
    </div>
</body>

The CSS is also very simple, some coloring and text alignment:

CSS
<style>
   .rownr {overflow-y: hidden; background-color: rgb(105,105,105); color: white; 
           text-align: right; vertical-align:top}
   .txt {width: 95%; overflow-x: scroll}
</style>

The main textarea uses event handlers for:

  • oninput (for populating line numbers)
  • onscroll (for scroll syncing)
  • onclick and onkeyup events (for reading current position/selection)

Oninput Event Handler

When some text is entered into the textarea, function input_changed is called:

JavaScript
function input_changed(obj_txt)
    {
        obj_rownr = obj_txt.parentElement.parentElement.getElementsByTagName('textarea')[0];
        cntline = count_lines(obj_txt.value);
        if(cntline == 0) cntline = 1;
        tmp_arr = obj_rownr.value.split('\n');
        cntline_old = parseInt(tmp_arr[tmp_arr.length - 1], 10);
        // if there was a change in line count
        if(cntline != cntline_old)
        {
            obj_rownr.cols = cntline.toString().length; // new width of txt_rownr
            populate_rownr(obj_rownr, cntline);
            scroll_changed(obj_txt);
        }
        selectionchanged(obj_txt);
    }

This function is calling another function count_lines to count the lines in the text (by splitting text by \n and counts the elements of the resulting array). Then, if there was indeed a change in the number of lines, rownr textarea is repopulated.

Onscroll Event Handler

The onscroll event handler ( scroll_changed ) is, basically, reading the scrollTop attribute of one textarea, and sets this attribute for the other textarea. (This function can also work with any 2 scrollable HTML elements.)

JavaScript
function scroll_changed(obj_txt)
    {
        obj_rownr = obj_txt.parentElement.parentElement.getElementsByTagName('textarea')[0];
        scrollsync(obj_txt,obj_rownr);
    }
    
function scrollsync(obj1, obj2)
    {
        // scroll text in object id1 the same as object id2
        obj2.scrollTop = obj1.scrollTop;
    }

Onclick and onkeyup Event Handlers

When the textarea is clicked, selectionchanged function is called.

JavaScript
function selectionchanged(obj)
{
    var substr = obj.value.substring(0,obj.selectionStart).split('\n');
    var row = substr.length;
    var col = substr[substr.length-1].length;
    var tmpstr = '(' + row.toString() + ',' + col.toString() + ')';
    // if selection spans over
    if(obj.selectionStart != obj.selectionEnd)
    {
        substr = obj.value.substring(obj.selectionStart, obj.selectionEnd).split('\n');
        row += substr.length - 1;
        col = substr[substr.length-1].length;
        tmpstr += ' - (' + row.toString() + ',' + col.toString() + ')';
    }
    obj.parentElement.getElementsByTagName('input')[0].value = tmpstr;
}

This simple function uses the selectionStart and selectionEnd attributes of textarea objects (also works for some other HTML elements) to calculate the current line and column where the snippet is located.

In order to handle also the arrow keys on the keyboard, plus the Home, End, Page Up and Page Down keys, there is also a handler function for keyUp event. This function is doing nothing but calling the selectionchanged function if any of these keys are pressed.

JavaScript
function keyup(obj, e)
{
        if(e.keyCode >= 33 && e.keyCode <= 40) // arrows ; home ; end ; page up/down
            selectionchanged(obj, e.keyCode);
}

Image 2

History

  • 26th July, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)