Searching Body Text with textRange: Building on the Script and the VBScript Alternative

Once you have the basic script for performing text searches within the text of web pages, you may want to extend the functionality of this and add a button that will find the next occurrence of the word you have searched for. This will improve the usability of the whatever web page you add this to.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 17
June 30, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Initially, you may as well add the second button to the main web page (findingText.htm).  Add the following block of code directly beneath the first button, using the appropriate table tags to nestle it next to the original button:

button id=buttonNext title="Click to find the next match" onclick="searchNext()">Find Next...</button>

Now open the behaviour.js file and you can add the corresponding searchNext() function.  Before doing this however, you need to know a little bit more about how the findText method works.  When it finds a match for the word that has been searched for, it reduces the textRange object so that it just encompasses the matched word.  What you need to do is move the text range forward by one word and then expand the textRange once more so that it covers the remaining body text.

Add the new searchNext function below the textSearch function in the behaviour file:

function searchNext() {
  if (searchWord=="") {
    window.alert ("No Search value entered");
    return false
  }
  range.move("word", 1);
  range.moveEnd("word", 1000);
  match = range.findText(searchWord,0,2);
  if (match != false) {
    range.select();
  } else {
  window.alert ("Couldn't find any more instances of '" + searchWord + "'");
  }
}

As this function also needs to make use of the searchWord, range and match variables, these need to be defined as global variables by declaring them outside of a function.  Add them to the top of the file:

var strDialogValue
var range
var match

Now both of the functions can make use of the variables and share their values.  The second function is very similar to the first except that instead of just returning false in the initial if statement, it also sends an alert to the user if no search word has been entered (if, for example, the user has clicked the find button, but then clicked cancel and then clicked the find next button.)  It also uses the move method to move the range forward by one word, and uses the moveEnd method to move the end of the range forward by 1000 words.  As there are less than one thousand words in the body of the page, this will definitely include the rest of the text.  If no further matches are found, an alert is sent advising of this.

This should now be a fully working script, but it can still produce errors if it is not used correctly.  If someone clicks on the find next button without having first clicked on the find button and entered a search word, the page errors.  As it is possible for this to happen, is bound to happen and you should therefore incorporate into your script something that will detect whether this has happened and cater for it accordingly without producing errors.

Add a Flag

Fortunately, this is fairly easy.  All you need to do is add a flag to the first function that is set when that function is called (when the find button is clicked.)  If the second button is clicked and that flag has not been set, you can produce an alert that tells the user to click the find button first and enter a search term, thus preventing the error.  First add another global variable to the top of the page:

var button1clicked

Now, in the first function (textSearch), set the flag to 1 at the beginning of the function:

button1clicked = 1

This tells the script that the find button has definitely been clicked.  Now a simple if statement at the top of the second function to test the value of the flag variable quickly lets the script accordingly if the first button has not been clicked:

if (button1clicked != 1) {
    window.alert ("Please enter a search value first");
    return false
  }

Like we added an if statement in the first article to ensure that the page did not error when no value was passed back to a variable that was expecting one, this statement simply checks that button1clicked does equal 1, but if not, alerts the user.

Finally, if a user clicks the x button at the top of the dialog box instead of clicking the cancel button an alert informs the user that ‘undefined’ couldn’t be found, which is rather silly as undefined was not entered as a search term.  This happens because in this case, as when the user searches for a word that is not found in the body text, match does equal false and the appropriate alert is fired.  It would be better all round if nothing happened when the x button was clicked, just like when the cancel button is clicked.  Change the first if statement in the first function to this:

if (searchWord=="") {
  return false
  } else if (searchWord==null) {
  return false
}

Now test it.  If you search for a word that is not present in the text, you still get the "couldn’t find ‘word’" message, and if you click the x button or the cancel button on the search dialog, nothing happens and no errors occur.  Similarly, the second if statement of the second function can also be modified in the same way so that if a user opens the search dialog window (thus setting button1clicked to 1) but then closes it without entering a search word and then clicks the find next button, an error message more appropriate is displayed:

if (searchWord=="") {
  window.alert ("No Search value entered");
  return false
} else if (searchWord==null) {
  window.alert("No search value entered");
  return false
}

The script should now be able to handle anything a user throws at it.

The VBScript

As promised, I will now give you the VBScript variation of the whole script.  Some may question what the point of using VBScript actually is when the JavaScript version does everything that is needed from it?  I’m including this s o that people can choose whichever version they use depending on whichever language they prefer.   Additionally, as VBScript is basically a cut-down version of Visual Basic, learning VBScript is an excellent primer for those wishing to progress to application programming with full VB or even VB.NET.  Those that don’t want to know should look away now.

The VBScript file in its entirety then is as follows.  I won’t go through the code step by step because you should already be able to tell what is going on in the file:

dim searchWord
dim range
dim match
dim button1clicked

sub buttonSearch_onclick()
  button1clicked = 1
  set range = document.body.createTextRange()
  searchWord=window.showModalDialog("Searchwindow.htm",
   null,"dialogWidth:300px;dialogHeight:200px;status:no;help:no;")
  if searchWord="" then
    exit sub
  end if

match = range.findText(searchWord,0,2)
if match <> false then
  range.select()
else
  MsgBox "Couldn't find " & searchWord,vbExclamation,"No Match"
end if
end sub

sub buttonNext_onclick()
  if searchWord="" then
    MsgBox "No search value entered",vbCritical, "No Search Word"
    exit sub
  end if
  if button1clicked <> 1 then
    MsgBox "Please enter a search value first", vbCritical, "No Search Word"
    exit sub
  end if
  range.move "word", 1
  range.moveEnd "word", 1000
  match = range.findText(searchWord,0,2)
if match <> false then
  range.select()
else
  MsgBox "Couldn't find any more instances of " & searchWord,vbExclamation,"No Further Matches"
end if
end sub

Initially, the global variables are defined using the dim keyword instead of the var keyword.  This is standard practice in VBScript.  Next up, although VBScript does support the use of functions, this script has made use of subs instead.

VBScript Continued

The main difference between subs and functions is that functions return values whereas subs do not.  The set keyword is used to set the value of the range variable equal to the textRange we have defined.

Another difference is the way in which alerts are defined.  The MsgBox function is used in place of the alert method and you’ll see that this gives you greater control over the general working of the alert.  Several of the MsgBox elements have been set as vbExclamation and several as vbCritical.  Not only does this change the icon that appears on the alert, it also changes the sound that is associated with it (provided the users’ sound settings cater for this.)  Also, instead of specifying a return of false following a search term not being entered, you can simply exit the subroutine.  Syntactically, these are the main differences between the two scripts.  The search window does not need to be changed in anyway; the JavaScript ModalDialog window will happily pass the required value back to the VBScript file without causing any problems.  You may also have noticed that some of the additional error handling if statements have been left out as the some of the user actions do not cause errors with the VBScript in the same way as they do with JavaScript.

Before this will work properly, you need to adjust the main HTML page that calls the script.  Firstly, the file referenced in the script src attribute needs to be changed to behaviour.vbs or the JavaScript file will still be called, secondly, you need to remove the onclick event handlers from the button code.  The subs in the VBScript file have the onclick events tacked on to the end of the button names in the first line of the sub.

As a point of interest; once a word has been found and highlighted, it is easy to use the range to replace the word searched for as well.  Theoretically, another button could be added to the example web page that called a textReplace() function.  The code this contained could produce a second dialog window which asked for a word to replace the highlighted word with.

It is then simply a case of setting range.text equal to the new word variable.  While it is difficult to think of the point in using the replace method in this example, I’m sure there are cases when it would be useful, a simple script-based spell checking function added to form text area’s is one possibility. 

As I mentioned in the first article, both of these scripts will work only on IE browsers.  The JavaScript version may work on IE on other platforms such as the MAC (I don’t know as I haven’t tested it), but the VBScript will only work on MS platforms.  The most popular alternative browser to IE at the moment is FireFox, a browser that uses the Gecko rendering engine to draw the various elements that make up web pages in the browser.  This is also used by Netscape and Mozilla browsers so having a script that will be compatible with Gecko will clear up any compatibility issues between all major browsers.  Provided you have some kind of detection model in place that can refer different browsers to different areas of your site, you can have the IE only script of choice running on one section, and the Gecko based script residing on another section.  A gecko compatible script is the subject of discussion in article three.

blog comments powered by Disqus
CODE EXAMPLES ARTICLES

- Bipartite Graphs
- Connectivity in Graphs
- The Ford-Fulkerson Algorithm
- Critical Paths
- The Bellman-Ford and Roy-Floyd Algorithms
- Shortest Path Algorithms in Graphs
- Minimum Spanning Tree
- Articulation Edges and Vertexes
- Circles and Connectivity in Graphs
- Depth-First Search in Graphs
- Breadth-First Search in Graphs
- The Prufer Code and the Floyd-Warshall Algor...
- An Insight into Graphs
- Coding a Custom Object with WSC
- Creating a Custom Object with WSC

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 10 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials