AJAX In Action [244]
Refactoring
499
method just calls the submit() method of the native HTML form, which causes a traditional form submission. In this scenario, the component assumes that there is an appropriate action attribute of the form and that the result of the action returns an appropriate page with search results.
Now let’s look at the Ajax implementation of searching:
doAjaxSearch: function() {
this.showLoadingImage(); b
Show loading image
var searchUrl = this.appendToUrl( this.xmlURL,
'q',
this.lookupField.value); c
Formulate URL
new XSLTHelper(searchUrl, d
Perform XSLT processing
this.xsltURL).loadView(
this.options.resultsContainerId);
this.updateBookmark (); e
Update bookmark
},
The doAjaxSearch() method performs the same steps that the first iteration of our script did, but it puts each step into a method to perform each responsibility. At this point, you might object and say that this method has four responsibilities. Well, actually it just has one: searching. However, the responsibility of searching has four parts, each a responsibility on its own. So let’s look at each in turn: b Show the loading image—The search is started by calling the method to show the
“busy loading” image. The image used is determined by the options object: showLoadingImage: function() {
var newImg = document.createElement('img');
newImg.setAttribute('src', this.options.loadingImage );
document.getElementById(
this.options.resultsContainerId).appendChild(newImg);
},
c Formulate the search URL— The search URL is built using the xmlURL attribute that was passed in at construction time with a q= parameter appended to it with the value currently contained in the lookup field. The appending is performed by a method that checks the URL for the existence of a previous querystring to make sure the correct parameter separators are used:
appendToUrl: function(url, name, value) {
var separator = '?';
if (url.indexOf(separator) > 0; )
separator = '&';
return url + separator + name + '=' + value;
},
Licensed to jonathan zheng 500 CHAPTER 12 Live search using XSLT d Do the XSLT processing and update the UI— Because we had the presence of mind to factor out the task of client-side XSLT processing, this seemingly heavy-duty responsibility is achieved within a single line of code: new XSLTHelper(searchUrl, this.xsltURL).loadView(this.options.resultsContainerId); e Update the bookmark— Once the user has initiated a search, the bookmark should be updated as well. This responsibility is performed via the updateBookmark() method: updateBookmark: function() { var container = document.getElementById( this.options.bookmarkContainerId); var bookmarkURL = this.appendToUrl( this.pageURL, 'q', this.lookupField.value ); if ( container ) container.innerHTML = '' + this.options.bookmarkText + ' } This method gets the container element and the text for the bookmark from the options object. The URL for the generated bookmark is the value passed into the constructor as the pageURL argument. The q= parameter with the value of the current search are appended to that URL. The innerHTML property of the container is updated with all of these values to produce the appropriate URL. If a bookmark is stored and used to hit our page, the user is returned to our page with a q=someValue parameter. But what initiates the search to produce the result? Recall that the final line of the constructor called this.initialize();. We’ve not peeked at what that actually does yet, so we should do so now. As you’ve probably guessed, the initialize() method is there to support our bookmarking feature. The implementation is as follows: initialize: function() { var currentQuery = document.location.search; var qIndex = currentQuery.indexOf('q='); if ( qIndex != -1 ) { this.lookupField.value = currentQuery.substring( qIndex + 2 ); this.doSearch(); } }, Licensed to jonathan zheng Summary 501 The initialize() method takes the current location of the document and looks for a parameter