Blupixel IT Blog – Computer Science and Web Developing Articles

Offical Blog of Blupixel IT Srl

Scroll textarea to selected word using javascript / jQuery

Here now one of those article which content will not be found easily on the net.
This is the solution to a problem I’ve never found answer before…

The question is really simple: We have a textarea, how can we scroll inside it to a specific word?

If you look on the net you’ll find a lot of solutions with strange numbers that work only in specific cases and not when the textarea has fluid dimension.

After a lot of time, finally, I found in Math the real solution!

Let’s start from the code and let’s suppose our textarea has id=”my_textarea”
Be aware that there is just one rule: specify a line-height in the css of the textarea!
We’ll use jquery but you can easily convert the code in pure javascript.
To see better the searched word we will highlight it!

The code is written using italian words, but it’s commented in english language

var parola_cercata = "parola"; // the searched word
var posi = jQuery('#my_textarea').val().indexOf(parola_cercata); // take the position of the word in the text
if (posi != -1) {
	var target = document.getElementById("my_textarea");
        // select the textarea and the word
	target.focus();
        if (target.setSelectionRange)
            target.setSelectionRange(posi, posi+parola_cercata.length);
        else {
            var r = target.createTextRange();
            r.collapse(true);
            r.moveEnd('character',  posi+parola_cercata);
            r.moveStart('character', posi);
            r.select();
        }
        var objDiv = document.getElementById("my_textarea");
	var sh = objDiv.scrollHeight; //height in pixel of the textarea (n_rows*line_height)
	var line_ht = jQuery('#my_textarea').css('line-height').replace('px',''); //height in pixel of each row
	var n_lines = sh/line_ht; // the total amount of lines
	var char_in_line = jQuery('#my_textarea').val().length / n_lines; // amount of chars for each line
	var height = Math.floor(posi/char_in_line); // amount of lines in the textarea
	jQuery('#my_textarea').scrollTop(height*line_ht); // scroll to the selected line
} else {
        alert('parola '+parola_cercata+' non trovata'); // alert word not found
}

Let’s have a look to the code:

  • The searched word is stored in a javascript variable. If you need to create a function you can pass it as an input parameter
  • In the variable named “posi” we store the position of the word found in the text of the textarea
  • If the word has been found (posi != -1) we continue. Otherwise return an alert saying that the word has not been found
  • We select the word to highlight it and make it more visible
  • We take the scroll height in pixel of the textarea
  • We get the height in pixel of the line-height paramater replacing the “px” word from the result
  • We calculate the total amount of rows of the textarea dividing the total height for the height of the single row
  • The fundamental part is now! We need to know how many chars there are in a row. So we get it making a division between the length of all the text and the total number of rows
  • Now everything is easy! The row where the word has been found and then where we have to scroll to is the division between the position of the word in the text and the number of chars for each row.
  • To get the scroll now just recalculate the pixel height as the number of the row multiplied the line-height

You can test it here with a word in the textarea (it has been tested on Firefox Web Browser):

See you soon!

  • Michelle says:

    Bless your heart!! I’ve been searching for hours on how to do this!
    Thanks you so much!!!

    July 15, 2013 at 7:27 pm
  • Irving Salgado says:

    Hi, Blupixel IT Sr.

    Is an excelent blog, this solution is great, well, I look for the complete code, don’t can find, please Where Can I download the code..??

    Thank’s a millon..!

    December 18, 2013 at 7:26 pm
  • Chris says:

    Thank You very much. Based on your model I added a style attribute to my textarea element. (style=”line-height:20px”). Then in the script after counting the number of lines from the top to get the required position:

    textarea.scrollTop= linecount* parseInt(textarea.style.lineHeight);

    this is behaving very well for me so again

    THANKS !!!

    February 5, 2014 at 5:47 am
    • reus says:

      grate work master! thank you for this. more power!

      March 7, 2014 at 1:24 pm
  • Dave K says:

    Tested it in both Firefox and Chrome, both working but code will only return the first found item.
    e.g. search ‘the’, only the first will be highlighted the remain 6 are not

    May 29, 2014 at 12:54 am
    • admin says:

      Yes, it finds only the first occurrences. If you want more I think you can add a Next button to execute again the function and change the command:
      var posi = jQuery(‘#my_textarea’).val().indexOf(parola_cercata);
      in
      var posi = jQuery(‘#my_textarea’).val().indexOf(parola_cercata, start_from_here);
      where start_from_here is the last position + 1

      If you want it to be automatized, insetad, just put the code in a loop changing the commands as above and checking everytime if there is a new occurrences starting from last position.

      Hope this helps

      May 29, 2014 at 8:52 am
  • denis says:

    hello admin i changed to find second occurrences but dosent work pleas any help ,it find only first pleas check my code thnks

    <!–
    function findWord(parola_cercata) {
    var posi = jQuery(‘#my_textarea’).val().indexOf(parola_cercata, start_from_here);
    where start_from_here is the last position + 1 // take the position of the word in the text
    if (posi != -1) {
    var target = document.getElementById("my_textarea");
    // seleziono la parola
    target.focus();
    if (target.setSelectionRange)
    target.setSelectionRange(posi, posi+parola_cercata.length);
    else {
    var r = target.createTextRange();
    r.collapse(true);
    r.moveEnd('character', posi+parola_cercata);
    r.moveStart('character', posi);
    r.select();
    } var objDiv = document.getElementById("my_textarea");
    var sh = objDiv.scrollHeight; //height in pixel of the textarea
    var line_ht = jQuery('#my_textarea').css('line-height').replace('px',''); //height in pixel of each row
    var n_lines = sh/line_ht; // total amount of lines in the textarea
    var char_in_line = jQuery('#my_textarea').val().length / n_lines; // the total amount of chars in each row
    var height = Math.floor(posi/char_in_line); // height in number of rows of the searched word
    jQuery('#my_textarea').scrollTop(height*line_ht); // scroll to the selected line containing the word
    } else {
    alert('parola '+parola_cercata+' non trovata');
    }
    }

    July 13, 2014 at 1:00 am
  • Wen shoo says:

    Not that perfect if there are some new blank lines or lines with just one or two letters in the textarea

    July 28, 2014 at 2:24 am
  • Abubakar says:

    There is error in code .
    It is not showing alert if i type half word, but it shows half word.

    September 15, 2014 at 2:47 pm
  • Abubakar says:

    for example : if i type “asily” it shows easily.

    September 15, 2014 at 2:49 pm
  • Nagesh says:

    This is what i exactly looking for from couple of hours..Great post

    September 8, 2015 at 9:46 am
    • Nagesh says:

      Hi

      Search text is getting highlight with position, but not scrolling to correct location.
      My content in TextArea has newlines on every end P tag. i considered them also but not helping, Can you please check the below code.

      //findIndex –Identified position of search word
      //res —is matched word
      //dataLength —is total content length of TextArea
      textAreaElement.setSelectionRange(findIndex, res.length + findIndex);
      var sh = textAreaElement.scrollHeight;
      var patt = new RegExp(“”, “g”);
      var newLineCount = data.match(patt).length;
      var line_ht = 15; //This is defined in CSS
      var n_lines = sh / line_ht-newLineCount;
      var char_in_line = dataLength / n_lines;
      var height = Math.abs(Math.floor(findIndex / char_in_line));
      textAreaElement.scrollTop = height * line_ht;

      I really appreciate your response.

      October 28, 2015 at 11:28 am
      • admin says:

        @Nagesh:
        Hi Nagesh,
        try to calculate how many empty lines there are in the text and to add to the calculation.

        Add something like:
        var text = jQuery(‘#my_textarea’).val(); // this is the text in the textarea
        var newlinesbeforeword = text.substring(0, posi).match(/^[ \t]*$/gm).length // this is the number of void lines before the found word

        Then change;
        var n_lines = sh/line_ht+newlinesbeforeword;

        The rest should remain the same.
        Let us now if it works.

        Hope this helps

        October 28, 2015 at 9:13 pm
  • Chris says:

    Hello, what exactly is “#insert_textarea” and where is it? I’m snooping around the html build of the example you posted (via browser inspector) but can’t see it anywhere… :/

    February 3, 2016 at 6:15 pm
    • admin says:

      Hi,
      sorry, it’s my error. It should be #my_textarea because it must be the same selector as before.
      Thank you for finding this error. I’m going to correct it now.

      Hope this helps

      February 3, 2016 at 9:18 pm
      • Chris says:

        Thanks for the reply! Another thing is that target.createTextRange() is giving me issues. Browsers says that “document.getElementById(…).createTextRange is not a function”. Am I missing something? :/

        February 24, 2016 at 1:25 am
        • admin says:

          Hi Chris,
          unfortunately the selection methods are not the same for all browser. createTextRange is a valid function only on some browser and a limited set of html elements. Which browser are you using? And what element are you applying the function on?
          You can try also with some cross browser selection library, like https://github.com/timdown/rangy
          Hope this helps, otherwise let me know some more detail

          February 24, 2016 at 8:38 am

Your email address will not be published. Required fields are marked *

*

YPl0q

Please type the text above: