Zack Herbert
Zack Herbert

Reputation: 960

Search for word and highlight with jquery

I have written a javaScript file in jQuery that provides a search function. I am trying to figure out how to highlight the word aswell. Bellow is the code.

Filter.js:

(function ($) {
  // custom css expression for a case-insensitive contains()
  jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});


function listFilter(header, list, title) { 
   // header is any element, list is an unordered list, title is any element
   // create and add the filter form to the header
   // create a button for collapse/expand to the title

var form = $("<form>").attr({"class":"filterform","action":"#"}),
    button = $("<input>").attr({"class":"rest", "type":"submit", "value":"Collapse All", "id":"switch"}),
    input = $("<input>").attr({"class":"filterinput","type":"text", "placeholder":"Search"});

$(form).append(input).appendTo(header); //add form to header
$(title).append(button); //add button to title

 //on click function for collapse/expand all
$("#switch").click(function(){
    if($(this).val() == "Collapse All"){
        $(".filterinput").val("");
        $(this).val("Expand All");
        $("div.content div.markdown").parent().parentsUntil(list).hide();
        $(list).find("span.path").parentsUntil(list).show();
        $(list).find("ul.endpoints").css("display", "none");
    }
    else{
        $(".filterinput").val("");
        $(this).val("Collapse All");
        $("div.content div.markdown").parent().parentsUntil(list).hide();
        $(list).find("span.path").parentsUntil(list).show();
    }
});

$(input)
  .change( function () {
    var filter = $(this).val();
    if(filter) {
      // this finds a single string literal in div.markdown,
      // and hides the ones not containing the input while showing the ones that do
        $(list).find("div.content div.markdown:not(:Contains(" + filter + "))").parent().parentsUntil(list).hide();
        $(list).find("div.content div.markdown:Contains(" + filter + ")").parent().parentsUntil(list).show();
    } 
    else {
        $("div.content div.markdown").parent().parentsUntil(list).hide();
        $(list).find("span.path").parentsUntil(list).show();
        $(list).find("ul.endpoints").css("display", "none");
    }
    return false;
  })
.keyup( function () {
    // fire the above change event after every letter
    $(this).change();
});
}
   //ondomready
   setTimeout(function () {
    listFilter($("#header"), $("#resources"), $("#api_info"));
   }, 250);
}(jQuery));

The html that I would like to manipulate is being dynamically created by another JS file so I need to manipulate the DOM after it has been completely rendered.. The html that I will be focusing on gets rendered as bellow, specifially the words in (div class="markdown").

Index.html:

<div class="content" id="connectivitypacks_get_connectivitypacks_content">
    <h4>Description</h4>
    <div class="markdown"><p>Response will return details for the connectivity packs based on the ID.</p>
        <h2 id="keywords">Keywords</h2>
        <p> foo, bar, helloWorld, java</p>
    </div>
</div>

Upvotes: 4

Views: 9514

Answers (2)

dude
dude

Reputation: 6086

Have a look at mark.js. It can highlight such search terms in a specific context. In your example the JavaScript would look like:

var searchTerm = $("#theInput").val();

// Search for the search term in your context
$("div.markdown").mark(searchTerm, {
    "element": "span",
    "className": "highlight"
});

and the CSS part:

span.highlight{
    background: yellow;
}

Upvotes: 1

Persijn
Persijn

Reputation: 14990

Here is an example that used your markdown.

  1. Create a regex with that word your searching for.
  2. Get the html of your .markdown
  3. replace the word with <span class="marker">"+ word +"</span>. So this creates a span tag around the word your searching for.
  4. Create css to style the word as needed.

function highlight(word) {
  var element = $('.markdown');
  var rgxp = new RegExp(word, 'g');
  var repl = '<span class="marker">' + word + '</span>';
  element.html(element.html().replace(word, repl));

}

highlight('details');
.marker {
  background-color: yellow;
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content" id="connectivitypacks_get_connectivitypacks_content">
  <h4>Description</h4>
  <div class="markdown">
    <p>Response will return details for the connectivity packs based on the ID.</p>
    <h2 id="keywords">Keywords</h2>
    <p>foo, bar, helloWorld, java</p>
  </div>
</div>

Upvotes: 4

Related Questions