1

I created an input field to search for words or their partial matches. In this example, I'm using the word cool.

The issue is that after 1st found match, I'm seeing matches from the HTML code and can't figure it out why. If I'm trying to find matches for the 3rd time, everything gets stuck.

Words match displaying the HTML code

Can someone help me understand why it's happening this?

Is there a way to write this part of code differently?

if ($(this).html().match(r)) {
                // console.log('this html match r is:' + ' ' + r);
                var matches = $(this).html().match(r);
                
                // loop through them
                $.each(matches, function () {
                    occurrences.push(i);
                    console.log(occurrences);
                });
                // wrap each found search term with our `found` span to highlight it 
                $(this).html($(this).html().replace(r, '<span class="found">$1</span>'));
            }

document.addEventListener("DOMContentLoaded", function() {
    let btn = document.querySelector('#findWord');    
    btn.addEventListener('click', function(){

        let occurrences = [];
        $('.timeline-type__content ul > li > a > .reports-list-item__title--compendium').each(function (i) {
            // create a regexp from our term 
            const word = document.getElementById("searchedWord").value; // Eg: "cool"
            const allCharacters = word.split("");                       // ["c", "o", "o", "l"]

            // Optional: remove duplicate characters:
            const characterSet = new Set(allCharacters);
            const uniqueCharacters = [...characterSet];                 // ["c", "o", "l"]

            const pattern = `(${uniqueCharacters.join("|")})`;          // c|o|l
            const r = new RegExp(pattern, "ig");                         // /(c|o|l)/ig

            if ($(this).html().match(r)) {
                // console.log('this html match r is:' + ' ' + r);
                var matches = $(this).html().match(r);
                
                // loop through them
                $.each(matches, function () {
                    occurrences.push(i);
                    console.log(occurrences);
                });
                // wrap each found search term with our `found` span to highlight it 
                $(this).html($(this).html().replace(r, '<span class="found">$1</span>'));
            }
        });

        let lengthOccurrences = occurrences.length;
        console.log('Number of occurrences is:' + ' ' + lengthOccurrences);

        let currViewMatch = Number(document.querySelector('#current').textContent);
        console.log('Number of current viewed match is:' + ' ' + currViewMatch);
        
        // if we are currently viewing a match, increment so we move to the next one
        currViewMatch = currViewMatch > 0 ? currViewMatch + 1 : 0;
        // if the incremented number is higher than the number of matches, reset it to 0
        currViewMatch = currViewMatch > lengthOccurrences ? 1 : currViewMatch;
        // if this is the first click and we found matches, set current to the first match
        currViewMatch = currViewMatch == 0 && lengthOccurrences > 0 ? 1 : currViewMatch;

        let insertNbrOcc = lengthOccurrences > 0 ? ' of ' + lengthOccurrences : ' matches found in document';
         // set number of matches found
        let count = document.querySelector('#count');
        count.textContent = insertNbrOcc;
        // console.log(count);

        // set  number of currently viewed match
        let nbrViewMatch = document.querySelector('#current');
        nbrViewMatch.textContent = currViewMatch;
        // console.log(insertTxtViewMatch);

        if(currViewMatch != 0){            
            // open the section holding the currently viewed match using the indexes we stored earlier
            $('.timeline-compendium__content').eq(occurrences[currViewMatch - 1]).collapse('show');
            $('.timeline-type .timeline-type__content').eq(occurrences[currViewMatch - 1]).collapse('show');
        } 
        
        
    });
});
.found {
    background-color: yellow;
}

#labels {
    margin-left: 15px;
    font-size: 16px;
}
.timeline-compendium {
    margin-left: 2rem;
}

.timeline-type__header {
    width: 400px;
    height: 50px;
    background-color: rgb(46, 177, 100);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    border: 1px solid white;
}
.timeline-type__header:hover {
    color: white;
    background-color: rgb(35, 119, 70);
}

#tab-content {
    border: 1px solid red;
}
input[type=text] {
    width: 80%;
    padding: 12px 20px;
    margin: 8px 0;
    box-sizing: border-box;
}
/* input[type=text]:focus {
    outline: 3px solid rgb(87, 163, 214);
} */
input#findWord {
    background-color: rgb(248, 211, 3);
    /* Green */
    border: none;
    color: black;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
}

.form-control.success input {
    border-color: #2ecc71;
}

.form-control.error input {
    border-color: #e74c3c;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
  integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
  crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
  integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
  crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
  integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
  crossorigin="anonymous"></script>
        <!-- HTML CODE -->
<div class="container">
        <div class="row">
            <div class="col-sm-12">
                <!-- <form id="searchForm" name="searchForm"> -->
                    <label for="searchedWord">Search</label>
                    <div>
                        <input type="text" id="searchedWord" placeholder="search.." aria-labelledby="searchedWord"/>
                        <button type="submit" id="findWord" value="Find">Find</button>
                    </div>
                <!-- </form> -->
            </div>
            <div class="col-sm-6">
                <div id="labels">
                    <span id="current"></span>
                    <span id="count"></span>
                    <span id="message"></span>
                </div>
            </div>
        </div>
        <div class="row">
           <div class="col">
            <section class="timeline-compendium">
                <a class="btn timeline-compendium__header" data-toggle="collapse" href="#introduction" role="button"
                    aria-expanded="true" aria-controls="introduction">
                    <div class="row align-items-center">
                        <div class="col-auto">Foreword</div>
                        <div class="col"><span></span></div>
                        <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip" title="Collapse/expand"
                                data-delay="400" aria-hidden="true" data-original-title="Collapse/expand"></em><span
                                class="sr-only">Collapse/expand
                                this item</span></div>
                    </div>
                </a>
                <div class="timeline-compendium__content collapse" id="introduction">
                    <div class="timeline-type">
                        <a data-toggle="collapse" href="#foreword" role="button" aria-expanded="false" aria-controls="foreword">
                            <div class="row no-gutters align-items-center">
                                <div class="col">
                                    <div class="timeline-type__header timeline-type__header--title">
                                        <div class="row align-items-center">
                                            <div class="col-auto timeline-type__chapter">Foreword</div>
                                            <div class="col timeline-type__title">Foreword</div>
                                            <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip"
                                                    title="Collapse/expand" data-delay="400" aria-hidden="true"></em><span
                                                    class="sr-only">Collapse/expand this
                                                    item</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </a>
                        <div class="timeline-type__content collapse" id="foreword">
                            <ul class="reports-list">
                                <li>
                                    <a href="#" target="_blank" class="reports-list-item reports-list-item--compendium">
                                        <div class="col-auto reports-list-item__chapter reports-list-item__chapter--pdf">
                                            <em class="icon-file-pdf" data-toggle="tooltip" title="Summary" data-delay="400"
                                                aria-hidden="true"></em>Foreword
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            Foreword cool
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>
            <!-- section 2 -->
            <section class="timeline-compendium">
                <a class="btn timeline-compendium__header collapsed" data-toggle="collapse" href="#titleA" role="button"
                    aria-expanded="false" aria-controls="titleA">
                    <div class="row align-items-center">
                        <div class="col-auto">Title A</div>
                        <div class="col"><span>SUMMARY</span></div>
                        <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip" title="Collapse/expand"
                                data-delay="400" aria-hidden="true" data-original-title="Collapse/expand"></em><span
                                class="sr-only">Collapse/expand
                                this item</span></div>
                    </div>
                </a>
                <div class="timeline-compendium__content collapse" id="titleA">
                    <div class="timeline-type"><a class="accordion" data-toggle="collapse" href="#summary" role="button"
                            aria-expanded="false" aria-controls="summary" class="collapsed">
                            <div class="row no-gutters align-items-center">
                                <div class="col">
                                    <div class="timeline-type__header timeline-type__header--title">
                                        <div class="row align-items-center">
                                            <div class="col-auto timeline-type__chapter">A</div>
                                            <div class="col timeline-type__title">Summary</div>
                                            <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip"
                                                    title="Collapse/expand" data-delay="400" aria-hidden="true"></em><span
                                                    class="sr-only">Collapse/expand
                                                    this item</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </a>
                        <div class="timeline-type__content collapse" id="summary">
                            <ul class="reports-list">
                                <li><a href="/en/secgen/courtsecretariat/Decisions/sommaire_en.pdf?d=wd815d51ad20c480292bc796688fd10d2&amp;csf=1&amp;e=XIu0Q9"
                                        target="_blank" class="reports-list-item reports-list-item--compendium">
                                        <div class="col-auto reports-list-item__chapter reports-list-item__chapter--pdf">
                                            <em class="icon-file-pdf" data-toggle="tooltip" title="Summary" data-delay="400"
                                                aria-hidden="true"></em>A
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            Summary not cool
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>
            <!-- section 3 -->
            <section class="timeline-compendium"><a class="btn timeline-compendium__header collapsed" data-toggle="collapse"
                    href="#titleB" role="button" aria-expanded="false" aria-controls="titleB">
                    <div class="row align-items-center">
                        <div class="col-auto">Title B</div>
                        <div class="col"><span>The Institution, the Court, operational procedures, the Members</span>
                        </div>
                        <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip" title="Collapse/expand"
                                data-delay="400" aria-hidden="true"></em><span class="sr-only">Collapse/expand
                                this item</span></div>
                    </div>
                </a>
            
                <div class="timeline-compendium__content collapse" id="titleB">
                    <div class="timeline-type"><a data-toggle="collapse" href="#chapterB0" role="button" aria-expanded="false"
                            aria-controls="chapterB0" class="collapsed">
                            <div class="row no-gutters align-items-center">
                                <div class="col">
                                    <div class="timeline-type__header timeline-type__header--title">
                                        <div class="row align-items-center">
                                            <div class="col-auto timeline-type__chapter">Chapter B 0</div>
                                            <div class="col timeline-type__title">Treaties on European Union</div>
                                            <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip"
                                                    title="Collapse/expand" data-delay="400" aria-hidden="true"></em><span
                                                    class="sr-only">Collapse/expand
                                                    this item</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </a>
                        <div class="timeline-type__content collapse" id="chapterB0">
                            <ul class="reports-list">
                                <li><a class="reports-list-item reports-list-item--compendium">
                                        <div class="col reports-list-item__chapter">B 0</div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--nolink">
                                            Treaties on European Union
            
                                        </div>
                                    </a>
                                </li>
                                <li><a href="/en/secgen/courtsecretariat/Decisions/b01.pdf?d=wa9cc5281eeb347718865a52bf6c67efb&amp;csf=1&amp;e=zyPEtD"
                                        target="_blank" class="reports-list-item reports-list-item--compendium">
                                        <div class="col reports-list-item__chapter reports-list-item__chapter--pdf"><em
                                                class="icon-file-pdf" data-toggle="tooltip"
                                                title="Status of the Court / Revision of Article 4 of the EEC Treaty"
                                                data-delay="400" aria-hidden="true"></em>B 0.1
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            Status of the Court / Revision of Article 4 of the EEC Treaty cool
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                                <li><a href="/en/secgen/courtsecretariat/Decisions/b02.pdf?d=w93c3d23dbdc04bcda16c5be9151c183a&amp;csf=1&amp;e=yaoQwr"
                                        target="_blank" class="reports-list-item reports-list-item--compendium">
                                        <div class="col reports-list-item__chapter reports-list-item__chapter--pdf"><em
                                                class="icon-file-pdf" data-toggle="tooltip"
                                                title="Obligations deriving from the Treaty on European Union" data-delay="400"
                                                aria-hidden="true"></em>B 0.2
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            Obligations deriving from the Treaty on European Union
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                                <li><a href="/en/secgen/courtsecretariat/Decisions/b03.pdf?d=w56410e2b1b9f4ee2af9278081fc1d2c6&amp;csf=1&amp;e=BXz2wy"
                                        target="_blank" class="reports-list-item reports-list-item--compendium">
                                        <div class="col reports-list-item__chapter reports-list-item__chapter--pdf"><em
                                                class="icon-file-pdf" data-toggle="tooltip" title="The Court's name"
                                                data-delay="400" aria-hidden="true"></em>B 0.3
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            The Court's name
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="timeline-type"><a data-toggle="collapse" href="#chapterB1" role="button" aria-expanded="false"
                            aria-controls="chapterB1" class="collapsed">
                            <div class="row no-gutters align-items-center">
                                <div class="col">
                                    <div class="timeline-type__header timeline-type__header--title">
                                        <div class="row align-items-center">
                                            <div class="col-auto timeline-type__chapter">Chapter B 1</div>
                                            <div class="col timeline-type__title">The Court's operational procedures
                                            </div>
                                            <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip"
                                                    title="Collapse/expand" data-delay="400" aria-hidden="true"></em><span
                                                    class="sr-only">Collapse/expand
                                                    this item</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </a>
                        <div class="timeline-type__content collapse" id="chapterB1">
                            <ul class="reports-list">
                                <li><a class="reports-list-item reports-list-item--compendium">
                                        <div class="col-auto reports-list-item__chapter">B 1.0</div>
                                        <div class="col reports-list-item__title reports-list-item__title--nolink">The
                                            Court's structure
                                        </div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="timeline-type"><a data-toggle="collapse" href="#chapterB2" role="button" aria-expanded="false"
                            aria-controls="chapterB2" class="collapsed">
                            <div class="row no-gutters align-items-center">
                                <div class="col">
                                    <div class="timeline-type__header timeline-type__header--title">
                                        <div class="row align-items-center">
                                            <div class="col-auto timeline-type__chapter">Chapter B 2</div>
                                            <div class="col timeline-type__title">Members of the Court
                                            </div>
                                            <div class="col-auto"><em class="icon-arrow-down" data-toggle="tooltip"
                                                    title="Collapse/expand" data-delay="400" aria-hidden="true"></em><span
                                                    class="sr-only">Collapse/expand
                                                    this item</span>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </a>
                        <div class="timeline-type__content collapse" id="chapterB2">
                            <ul class="reports-list">
                                <li><a class="reports-list-item reports-list-item--compendium">
                                        <div class="col-auto reports-list-item__chapter">B 2.1</div>
                                        <div class="col reports-list-item__title reports-list-item__title--nolink">Code
                                            of conduct for the members and former members of the Court
                                        </div>
                                    </a>
                                </li>
                                <li><a href="#" class="reports-list-item reports-list-item--compendium">
                                        <div class="col reports-list-item__chapter reports-list-item__chapter--pdf"><em
                                                class="icon-file-pdf" data-toggle="tooltip"
                                                title="Code of conduct for the Members and former Members of the Court"
                                                data-delay="400" aria-hidden="true"></em>B 2.1.1
                                        </div>
                                        <div class="col-auto reports-list-item__title reports-list-item__title--compendium">
                                            Code of conduct for the Members and former Members of the Court - Cool 
            
                                        </div>
                                        <div class="reports-list-item__url"><em class="icon-url" data-toggle="tooltip" title="Link"
                                                data-delay="400" aria-hidden="true"></em></div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>
           </div>
        </div>
    </div>
onweb
  • 75
  • 7

1 Answers1

1

(This was too long for a comment, maybe already helps you solve the issue)


You call $(this).html().match(r); to find matching words. Of course this will match occurences in the HTML. If you search for example "class" or "section". The HTML itself is matched there.

You should loop through HTML elements which are text nodes and call your .match(r) on each of them. Otherwise it will find tags, attributes and values in the attributes as well.

Taken from this answer: How do I select text nodes with jQuery:
$(elem).contents().filter(function() { return this.nodeType == Node.TEXT_NODE; });


In the code which replaces matches, you write $(this).html($(this).html().replace( ... - you can change this to $(this).html($(this).text().replace( ... if you only go through the text nodes and be safe there is no HTML there.

Peter Krebs
  • 3,831
  • 2
  • 15
  • 29