Hugoware

The product of a web developer with a little too much caffeine

More jQuery Magic – Search Highlighting

with 9 comments

So at first glance, which browser do you think we’re using in the screenshot below? FireFox? Chrome? IE8?

whatbrowser

It’s actually IE6 and all that search highlighting is done via jQuery!

oh-snap

Now most modern browsers do some sort of highlighting now when you do a “Find On Page” search so this may not be the most incredible jQuery trick you see in your life — but at the very least it’s the most impressive jQuery trick on this page.

Highlighting The Page

If you’re interested in following along, you can view the demo/source code at this page.

In order to search the page we’re going to need to a couple things…

  1. Check for user input.
  2. Use the search phrase and find matching text.
  3. Replace our matches with the new highlighted text.

Let’s jump in.

Checking For Input

jQuery makes it easy to work with events that we’re previously… well… a pain. The .keyup() function allows you to supply a delegate to monitor for changes to your search field. Below is the code you’ll find in the example.

//snip ...

self.input.keyup(function(e) {
	if (self.search) { clearTimeout(self.search); }
	
	//start a timer to perform the search. On browsers like
	//Chrome, Javascript works fine -- other less performant
	//browsers like IE6 have a hard time doing this
	self.search = setTimeout(self.performSearch, 300);
	
});

//snip...

As you can see by the comment, we don’t do the search each time the key goes down. IE6, bless it’s heart, tries it’s best to keep up but it’s a losing battle. Instead, we use a short time out to check for when the search begins. In many ways this is a lot better anyways. It’s fairly transparent to the user and saves undue strain on the browser.

Search And Find

Once we’re ready to search, we need to check the user’s input and format it as required.

//snip...

//create a search string
var phrase = self.input.val().replace(/^\s+|\s+$/g, "");					
phrase = phrase.replace(/\s+/g, "|");

//make sure there are a couple letters
if (phrase.length < 3) { return; }			

//append the rest of the expression
phrase = &#91;"\\b(", phrase, ")"&#93;.join("");

//snip...
&#91;/sourcecode&#93;

If you've read some of my blog before you know that <a href="https://somewebguy.wordpress.com/2009/06/04/complete-control-over-your-webforms-output/">I really like Regular Expressions.... a lot...</a> In this part we use our expressions to format our search phrase. Specifically, we're trimming it down and replacing spaces with "or". This makes sure that any phrase in the box is matched.

You may want to change this depending on your needs, for example, require all values to match, etc...

<h3>Find, Replace, Repeat</h3>

Once we have a valid search phrase, now it's time to actually replace the values on the page. You'll notice that I target specific types of elements since you don't want to search the entire document. Unlike a built in browser search option, this function actually makes changes to the markup. If you we're to highlight a value inside a <code>textarea</code> then you're going to end up with markup instead of a yellow block.

It's worth noting that this version only works with elements that don't have additional markup within them. Links, bold text, spans, etc... they are going to be wiped out by this. I'm working on another version that respects child elements, but for now - be warned.

The code below shows what we're doing to make this change.


//snip...

//find and replace with highlight tags
$("h1, h3, p").each(function(i, v) {

	//replace any matches
	var block = $(v);
	block.html(
		block.text().replace(
			new RegExp(phrase, "gi"), 
			function(match) {
				return ["<span class='highlight'>", match, "</span>"].join("");
			}));
	
});



//snip...

In this example I’m limiting my changes to a couple header tags and paragraphs. This helps me avoid things like my search bar at the top of the page. You could also create a class named .search and use that as a target.

The code starts by removing any existing highlighting classes from the element and then follows up by replacing any matches with a highlight tag.

Practical Uses… (tell me if you think of one)

I’ll admit that this was written just to see what it would look like. Most browsers already have a search on page feature that can be used to achieve the same effect. However, there are a few places that something like this may be handy.

AJAX Search Field
Have a page that searches other pages on the site and shows them as an list below the search field? Why not search the page they are on at the same time and highlight possible results?

Client Side Highlighting
Showing lists of data? Why not highlight matching values when a user hovers over certain buttons and filter options? Give them a preview of things to come?

Highlighting? How About Formatting?
Why just highlight text? Why not use this as dynamic formatting for text? Give users a preview of a change they are getting ready to make when they roll over a button?

Think this could be useful? Who knows! But it just goes to show just how much you can do with just a little bit of jQuery!

Advertisements

Written by hugoware

June 25, 2009 at 11:43 pm

9 Responses

Subscribe to comments with RSS.

  1. […] More here: More jQuery Magic – Search Highlighting […]

  2. More jQuery Magic – Search Highlighting « Yet Another WebDev Blog…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

    DotNetShoutout

    June 26, 2009 at 6:31 am

  3. Dear Friends,

    I hope you are doing well. I have launched a web site http://www.codegain.com and it is basically aimed C#,JAVA,VB.NET,ASP.NET,AJAX,Sql Server,Oracle,WPF,WCF and etc resources, programming help, articles, code snippet, video demonstrations and problems solving support. I would like to invite you as an author and a supporter. Looking forward to hearing from you and hope you will join with us soon.

    Please forward this email to all of your friends who are related IT. Send to us your feed about site also.

    Thank you
    RRaveen
    Founder CodeGain.com

    RRaveen

    July 2, 2009 at 9:58 am

  4. […] have read some of my earlier jQuery posts about mimicking Vista style password boxes or creating search highlighting for web pages and noticed that it doesn’t take that much code to transform the functionality of your […]

  5. hello,
    i am making a news reading site for fun, the address is included. the site is very beta right now. i really like this highlight function, but the results are destroying my google ajax api. there’s a live version up now, although if i figure it out hopefully it won’t be there by the time you look at this.

    thanks for your work,
    matthew

    matthew

    December 15, 2009 at 3:18 pm

  6. Hi
    Trying to use your code here. Works fine. Thank you.

    After the highlighting (in h1, p, td) I loose the links (a href). h1 marked as a link are unlinked. The same with other links in td’s.
    Any idea what I could do to keep my links?

    Werner

    Werner

    December 21, 2010 at 10:39 am

  7. Answer myself.
    Part of the solution is not to include td to search. That removes links and class if in a .

    Werner

    Werner

    December 21, 2010 at 11:04 am

  8. Thanks Man! Previously coming to your website I couldn’t find any legitimate material or tutorials on how to do this.

    Brian Bellino

    February 10, 2011 at 9:49 pm

  9. Practical use: I’m working on a Titanium app that requires a way to emulate the browser’s search, so I have to build it into the app. Thanks for the post.

    dosboy

    April 12, 2011 at 4:14 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: