Nitesh
Nitesh

Reputation: 1637

How to change the color of particular characters of string using JavaScript?

I am using table search functionality using this code - https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_filter_table. When user search for any row data using some search characters like "Jac", I want to change the color of these 3 characters only and want to show entire row. How can I change the color of these 3 characters? Or search input characters? EDIT - My code is:

$("#searchBox").keyup(function() {
var input, filter, table, tr, td, i;
input = document.getElementById("searchBox");
filter = input.value.toUpperCase();
if (filter.length > 1) {
    table = document.getElementById("myTable");
    tr = table.getElementsByTagName("tr");

    for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[1];
        if (td) {
            if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {

                var regx = new RegExp(filter, "g");
                var newstring = td.innerHTML.replace(regx, '<span class="highlight">' + filter + '</span>');
                td.innerHTML = newstring;
                tr[i].style.display = "";
            } else {
                tr[i].style.display = "none";
            }
        }
    }
} else {
    table = document.getElementById("myTable");
    tr = table.getElementsByTagName("tr");
    for (i = 0; i < tr.length; i++) {
        tr[i].style.display = "";
    }
}

});

Output of above code is not correct. It will work only when length of search string is more than 1. If I enter 3 characters it failed.

Upvotes: 1

Views: 5030

Answers (2)

Mohammed Joraid
Mohammed Joraid

Reputation: 6480

Might be an overkill approach. But this how I got it working.

The technique:

1- Get the original table (as a whole DOM) into a JS variable

2- Clone that variable into another JS variable.

3- The clone is used as a reference. Will remain intact never be modified.

4- The highlight works by extracting the found phrase, wrap with a <span> having that span is given a certain CSS to stand out from the rest of the text.


The reason behind this is that, if we edit the original table, and then we try to search again, the HTML tag that got inserted will be included in the searched terms and therefore, the search will break down.

We will be searching the clone always, then will get the text from the clone, process it, and then apply the new processed phrase to the original table. In other words, If the searched phrase is found in the clone object, its content will be copied over to the original table.


If I were to do this again, I would replace the whole thing with JQuery. But anyhow, this code needs to be optimized.

       
            var originalTable = document.getElementById("myTable");
            var realTr = originalTable.getElementsByTagName("tr");

         
            var cloneTable = originalTable.cloneNode(true);
            var cloneTr = cloneTable.getElementsByTagName("tr");

            function myFunction() {


                var input, filter, cloneTd, cloneTdValue, realTd, i, inputValue, inputValueUpper;


                input = document.getElementById("myInput");
                inputValue = input.value;
                inputValueUpper = inputValue.toUpperCase();


                for (i = 0; i < cloneTr.length; i++) {

                    cloneTd = cloneTr[i].getElementsByTagName("td")[0];

                    if (cloneTd) {

                        var cloneTdValue = cloneTd.innerHTML;
                        var cloneTdValueUpper = cloneTdValue.toUpperCase();
                        var index = cloneTdValueUpper.indexOf(inputValueUpper);

                        if (index > -1) {

                            var newStr = wrapStuff(inputValue, cloneTdValue, index);

                            realTr[i].style.display = "";
                            realTd = realTr[i].getElementsByTagName("td")[0];
                            realTd.innerHTML = newStr;



                        } else {
                            realTr[i].style.display = "none";
                        }
                    }
                }
            }


            function wrapStuff(input, tdStr, index) {

                if (input.length === 0)
                {
                    return tdStr;
                }


                var before, after, searched, extractLen, extractedVal, newString;

                extractLen = index + input.length;
                before = tdStr.substring(0, index);
                after = tdStr.substring(extractLen, tdStr.length);

                var newIndex = after.indexOf(input);
                 
                //Recursive function: yeah, my head got spinning. 
                //this is to apply the same code to the second half of the spliced string, because indexOf will only find the first occurance. 
                if (newIndex > -1) {
                    after = wrapStuff(input, after, newIndex);
                }

                extractedVal = tdStr.substring(index, extractLen);

                newString = before + "<span class=\"highlight\">" + extractedVal + "</span>" + after;


                return newString;

            }
    * {
                box-sizing: border-box;
            }

            #myInput {
                background-image: url('/css/searchicon.png');
                background-position: 10px 10px;
                background-repeat: no-repeat;
                width: 100%;
                font-size: 16px;
                padding: 12px 20px 12px 40px;
                border: 1px solid #ddd;
                margin-bottom: 12px;
            }

            #myTable {
                border-collapse: collapse;
                width: 100%;
                border: 1px solid #ddd;
                font-size: 18px;
            }

            #myTable th, #myTable td {
                text-align: left;
                padding: 12px;
            }

            #myTable tr {
                border-bottom: 1px solid #ddd;
            }

            #myTable tr.header, #myTable tr:hover {
                background-color: #f1f1f1;
            }
            .highlight {
                color: red;
            }
 <body>

        <h2>My Customers</h2>

        <input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">

        <table id="myTable">
            <tr class="header">
                <th style="width:60%;">Name</th>
                <th style="width:40%;">Country</th>
            </tr>
            <tr>
                <td>Alfreds Futterkiste</td>
                <td>Germany</td>
            </tr>
            <tr>
                <td>Berglunds snabbkop</td>
                <td>Sweden</td>
            </tr>
            <tr>
                <td>Island Trading</td>
                <td>UK</td>
            </tr>
            <tr>
                <td>Koniglich Essen</td>
                <td>Germany</td>
            </tr>
            <tr>
                <td>Laughing Bacchus Winecellars</td>
                <td>Canada</td>
            </tr>
            <tr>
                <td>Magazzini Alimentari Riuniti</td>
                <td>Italy</td>
            </tr>
            <tr>
                <td>North/South</td>
                <td>UK</td>
            </tr>
            <tr>
                <td>Paris specialites</td>
                <td>France</td>
            </tr>
        </table>

        <script>

        </script>

    </body>

Upvotes: 2

Mohammed Joraid
Mohammed Joraid

Reputation: 6480

Capture the search phrase (the word you are searching or looking for). Capture the search area (the table or paragraph you are searching into). Look into the search area to see if you can find the search phrase. Once it exists, replace with a string that has an HTML element tag surrounding it.

Replace the searched word with the same word but wrapped in a span that has certain CSS class. Use CSS to customize the look.

  var toLookInto = $("#toLookInto").html();

$("#toFind").on("keyup", function() {
  var toFind = $("#toFind").val();
  var regx = new RegExp(toFind, "g");
  var newstring = toLookInto.replace(regx, '<span class="highlight">' + toFind + '</span>')

  $("#toLookInto").html(newstring)

});
.highlight {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<p id="toLookInto">
  dummy text foo bar cat mewo dummy text foo bar cat mewo dummy text foo something odd bar cat mewo dummy text foo bar cat mewo
</p>

<br>

<input type "text" id="toFind" />
<lable>The text field will be triggered on every key pressed</label>

Upvotes: 2

Related Questions