Many users requested two things, which I tried to incorporate into the design:
- the ability to list all the words from a given range of pages
- the ability to search for a specific word
<word book="1" chapter="3" page="42">awesomenitude</word>
In the basic PHP (no-Javascript) version of the page, the user's query is sent via form to a PHP script, which spits back the results. This is hijaxed with Javascript.
The XML basically never changes, so I made a cache system - the first time a user searches, the XML is downloaded and stored in a local Javascript object for quicker access. Since the XML is already present and parsed, subsequent searches are lightning fast. This allows the Javascript version to be much more slick - results are returned every time a key is pressed in the search box (rather like Google's new instant search, but less annoying).
The one problem with the hijax version is: what to do with an empty search box? I had been using indexOf to test for matches, because it is simple and provided all the utility I needed. But under such a system, if a user enters something and then deletes it, the script will try to match a blank string - and a blank string is a match for everything. This means that the entire 2700-word database would come crashing into view.
Obviously this is not too hard to code around, but many users did actually request that functionality. I did want to include the option, but not force it upon people who didn't need it. For a while, I tinkered with the idea of a placeholder - a blank string would yield no results, and a special character such as # would function to return all words. But I think you'll agree, this is hardly intuitive.
Then it hit me - MS-DOS! Ahh, how I miss doing things by the command-line (says he, now that he doesn't actually have to anymore). I remembered the magic asterisk, and how much fun it was (seriously - this was what my life was like as a child) to use.
So I made a regular expression-powered search:
//grab user input and store it in searchTerm var searchTerm = document.getElementById("searchbox").value; //replace any asterisks (*) with the regex wildcard (.*) searchTerm = searchTerm.replace(/\*/g, ".*"); //make a new regular expression var newSearchTerm = new RegExp(searchTerm, "gi"); //get a nodeList of word tags from the XML, and search them var words = xmlDoc.getElementsByTagName("word"); for (var i = 0; i < words.length; i++) { if (newSearchTerm.test(words[i].firstChild.nodeValue)) { //add it to the list of matching results } }
A bonus of this is that the asterisk can be used for much more powerful searches, not just listing all the word, but all the words beginning with a, or ending with ly, or whatever. Groovetastic.
For anyone interested in testing js regular expressions, I wrote a little utility (that I am reasonably sure works perfectly - let me know if you find bugs!).
No comments:
Post a Comment