= this.itemClickHandler.bindAsEventListener(this); var textValues = this.splitTextValues( suggestion.text, this.lastRequestString.length, (Web hosting asp)

February 4th, 2008

= this.itemClickHandler.bindAsEventListener(this); var textValues = this.splitTextValues( suggestion.text, this.lastRequestString.length, regExp ); var textMatchSpan = document.createElement(”span”); textMatchSpan.id = this.id + “_match_” + n; textMatchSpan.className = this.options.matchClassName; Refactoring 419 textMatchSpan.onmouseover = this.mouseoverHandler.bindAsEventListener(this); textMatchSpan.onclick = this.itemClickHandler.bindAsEventListener(this); textMatchSpan.appendChild( document.createTextNode(textValues.mid) ); suggestionSpan.appendChild( document.createTextNode(textValues.start) ); suggestionSpan.appendChild(textMatchSpan); suggestionSpan.appendChild( document.createTextNode(textValues.end) ); return suggestionSpan; }, This task is starting to look daunting, but don t bail out just yet. This method probably looks more complicated than it is, although it does quite a bit of work. Perhaps it would be best to back up at this point and look at this method in terms of what it is attempting to produce: namely, some HTML for a suggestion. Let s imagine HTML markup for a suggestion that looks something like this: before matching text, and afterNote: If you are looking for cheap and reliable webhost to host and run your mysql application check mysql web server services.

Business web site - var startRegExp = “^”; 418 CHAPTER 10 Type-ahead

February 3rd, 2008

var startRegExp = “^”; 418 CHAPTER 10 Type-ahead suggest if ( this.options.matchAnywhere ) startRegExp = ; var regExp = new RegExp( startRegExp + this.lastRequestString, regExpFlags ); var suggestionSpans = []; for ( var i = 0 ; i < this.suggestions.length ; i++ ) suggestionSpans.push( this.createSuggestionSpan( i, regExp ) ); return suggestionSpans; }, This method first looks at our options object to find the value of the ignoreCase and matchAnywhere properties. This has to be done so that a regular expression can be created with the appropriate parameters that will facilitate the retrieval of the portion of the string in the response that actually matches what the user has typed in. The method then iterates over the suggestions property, which you will recall is an array of objects that have a .text and a .value property. For each sug- gestion in the array, the createSuggestionSpan() method is called with the index of the suggestion and the regular expression created earlier. All the real work is done in createSuggestionSpan(), shown in listing 10.37. Listing 10.37 Creation of a list item span createSuggestionSpan: function( n, regExp ) { var suggestion = this.suggestions[n]; var suggestionSpan = document.createElement("span"); suggestionSpan.className = this.options.suggestionClassName; suggestionSpan.style.width = 100% ; suggestionSpan.style.display = block ; suggestionSpan.id = this.id + "_" + n; suggestionSpan.onmouseover = this.mouseoverHandler.bindAsEventListener(this); suggestionSpan.onclick
We recommend you use shared web hosting services, because many users agree that it is cheap, reliable and customer-satisfying webhost.

tyle(). We just pass it the element, (Web hosting mysql) the

February 3rd, 2008

tyle(). We just pass it the element, the IE name for the attribute, and the Mozilla name for the attribute, and the method returns a value. Our method here gets the values of the left and right borders and margins, sums them up, and returns them. The Rico.getElementsComputedStyle() is known to have issues with some ver- sions of Safari, and so we provide a default return value within a try…catch block. Creating the pop-up contents Now that we have the code to create and position the pop-up, we need to write a method to populate it with actual suggestions before it can be useful. Recall that our ajaxUpdate() method parses the XML from the response into an array of sug- gestion objects. And, if at least one suggestion exists, it calls a method named this.updateSugggestionsDiv(). This method is the transformer of the in-memory collection of suggestions to actual SPAN elements within the pop-up div. Let s look at how that s done now: updateSuggestionsDiv: function() { Remove prior content this.suggestionsDiv.innerHTML = “”; var suggestLines = this.createSuggestionSpans(); Create new for (var i = 0; i < suggestLines.length; i++) content this.suggestionsDiv.appendChild(suggestLines[i]); }, This method is deceptively simple, but there s still lots of work to do, so hang with us. This method simply sets the value of the innerHTML property of the sugges- tionsDiv created earlier to an empty string in order to wipe out any prior con- tent. Then it calls createSuggestionSpans() to create a span for each suggestion in the suggestions array. Finally, it iterates over the created spans and appends them to the div. This is where the real work starts. Let s continue by looking at createSuggestionSpans() in listing 10.36 to see what s involved in creating them. Listing 10.36 Creation of suggestion list items createSuggestionSpans: function() { var regExpFlags = ""; if ( this.options.ignoreCase ) regExpFlags = i ;
Check Tomcat Web Hosting services for best quality webspace to host your web application.

padding: function() { try{ var styleFunc = RicoUtil.getElementsComputedStyle;

February 2nd, 2008

padding: function() { try{ var styleFunc = RicoUtil.getElementsComputedStyle; var lPad = styleFunc( this.suggestionsDiv, “paddingLeft”, “padding-left” ); var rPad = styleFunc( this.suggestionsDiv, “paddingRight”, “padding-right” ); var lBorder = styleFunc( this.suggestionsDiv, “borderLeftWidth”, “border-left-width” ); var rBorder = styleFunc( this.suggestionsDiv, “borderRightWidth”, “border-right-width” ); lPad = isNaN(lPad) ? 0 : lPad; rPad = isNaN(rPad) ? 0 : rPad; lBorder = isNaN(lBorder) ? 0 : lBorder; rBorder = isNaN(rBorder) ? 0 : rBorder; return parseInt(lPad) + parseInt(rPad) + parseInt(lBorder) + parseInt(rBorder); }catch (e){ return 0; } }, Getting the calculated style of an element the actual value of an attribute regardless of how it was set is trickybusiness. To achieve this, IE provides a pro- prietary currentStyle attribute for each element. Mozilla-based browsers use a getComputedStyle() method of the defaultView property of the document to Refactoring 417 calculate this. Each one of these mechanisms expects a different specification for the attribute being queried, as well. The IE currentStyle expects style attributes specified via the JavaScript-like binding (for example, borderRightWidth), whereas the Mozilla getComputedStyle() expects attributes specified with the stylesheet- like syntax (for example, border-right-width). Luckily, Rico provides a method that takes care of all of this for us RicoUtil.getElementsComputedS
Searching for affordable and reliable webhost to host and run your web applications? Go to our java web server services and you will be pleased.

of the text field . The parent in (Hosting web)

February 2nd, 2008

of the text field . The parent in this case really doesn t matter, since the div will be posi- tioned absolutely. Positioning the pop-up Now that our pop-up has been created, at some point it will have to be shown. But before it can be shown, it has to be positioned. When we show the pop-up, we want it to appear just below the text field and to be aligned with the left side of the text field. Let s write the positionSuggestionsDiv method in listing 10.34. Listing 10.34 Positioning the pop-up UI positionSuggestionsDiv: function() { var textPos = RicoUtil.toDocumentPosition(this.textInput); var divStyle = this.suggestionsDiv.style; divStyle.top = (textPos.y + this.textInput.offsetHeight) + “px”; divStyle.left = textPos.x + “px”; if ( this.options.matchTextWidth ) divStyle.width = (this.textInput.offsetWidth this.padding()) + “px”; }, 416 CHAPTER 10 Type-ahead suggest You will recall that in the previous version of this script, we wrote a method to cal- culate the absolute position of the text field. In this refactored version, we are relying on a utility method provided by Rico toDocumentPosition(). All we have to do is to use this method to get our reference point and perform the appropri- ate calculations to get our pop-up below and align on the left with the text field. We then check for the existence of the configuration option matchTextWidth, and if it is true, we also size the width of the div element to match the width of the text input. Note that we adjust the width by the padding value. We do this because, as you recall, we ve allowed the div element to be externally styled through a CSS class. We don t know if the user will have put margins and borders on the compo- nent, which would throw off the visual alignment to the width of the text field. Let s write a padding() method (listing 10.35) to compute the left and right pad- ding values and margins to subtract from the overall width. Listing 10.35 Calculation of left and right padding
We recommend you use shared web hosting services, because many users agree that it is cheap, reliable and customer-satisfying webhost.

vioral divStyle.zIndex = 101; style divStyle.display = “none”;

February 1st, 2008

vioral divStyle.zIndex = 101; style divStyle.display = “none”; this.textInput.parentNode.appendChild Insert into document (this.suggestionsDiv); }, The creation method of the container has four basic responsibilities. First, it has to create the DIV via the document s createElement() API . Second, it has to style the DIV according to the client configuration . Recall that one of our requirements was to make the CSS styling of each component instance individually configurable. We achieve that in this case by setting the div s className attribute according to the suggestDivClassName property of the options object. You will recall that we set the default value of this property to sug- gestDiv within the setOptions method. So if the user doesn t explicitly specify a value for a property, this is what she will get. This is a convenient feature because it allows the client of our component to have a default stylesheet that uses our Refactoring 415 default class names to style all TextSuggest component instances used across the application. Other stylesheets could also be provided (for example, product- or customer-specific stylesheets) that override the definitions of these standard style names. And finally, an individual page can override the value of the suggestDiv- ClassName parameter to provide a page-level or instance-level styling to the com- ponent. Sounds pretty flexible to us. There are certain aspects of the style of the pop-up that are nonnegotiable, annotated as Behavioral style, so we style them explicitly through the style attribute of the element . Note that anything styled programmatically via the style attribute overrides anything specified via a CSS className, typically by a stylesheet. These nonnegotiable aspects are 1) position= absolute because the component must manage the positioning of the div internally, 2) zIndex=101, which we use to make sure the pop-up is on top of everything on the page, and 3) display=”none” because the pop-up has to be hidden from the user s view until the user s keystrokes trigger it. Note that the value of 101 for the zIndex is some- what arbitrary. Finally, the method inserts the div into the document as a sibling
If you are looking for affordable and reliable webhost to host and run your business application visit our ftp web hosting services.

configurability and defaults, Ajax request and response handling,

January 31st, 2008

configurability and defaults, Ajax request and response handling, and the events that tie everything together. All that s left to cover is the graphical part. What we re referring to here, obviously, is the pop-up list of suggestions and all that implies. The tasks left to handle with respect to the UI are as follows: Creation of the suggestion pop-up UI. This entails the creation of the div for the suggestions as well as the span for each suggestion. The positioning of the pop-up. The population of the pop-up with suggestions. The showing and hiding of the suggestions. 414 CHAPTER 10 Type-ahead suggest Creating the suggestion pop-up Let s go back and examine the implementation of the injectSuggestBehavior() method. Recall that this code was more or less the entry point to all the DOM manipulation done by the TextSuggest component: injectSuggestBehavior: function() { // HTML Dom Behavior Injection… this.createSuggestionsDiv(); }, The last line of the injectSuggestBehavior() method calls the createSugges- tionsDiv() method, which creates the outermost containing div of the suggestion pop-up. Since this is the container of all GUI artifacts, it s the logical place to start looking at UI code. The details of the implementation are shown in listing 10.33. Listing 10.33 Creating the suggestion pop-up UI createSuggestionsDiv: function() { this.suggestionsDiv = Create the div document.createElement(”div”); this.suggestionsDiv.className = Style the div this.options.suggestDivClassName; var divStyle = this.suggestionsDiv.style; Add divStyle.position = absolute ; beha
If you are looking for cheap and quality webhost to host and run your website check Jboss Web Hosting services.

Managed web hosting - ); } The onblurHandler and handledSpecialKeys both reference

January 31st, 2008

); } The onblurHandler and handledSpecialKeys both reference a method of the Text- Suggest component that we ve not seen yet setInputFromSelection(). This method does essentially the same thing that our SetText() function did earlier namely, to take the currently selected suggestion; set both the input field and the hidden field with its text and value, respectively; and hide the list of suggestions. The implementation is shown here: Refactoring 413 setInputFromSelection: function() { var hiddenInput = $( this.id + “_hidden” ); var suggestion = this.suggestions[ this.selectedIndex ]; Update visible value this.textInput.value = suggestion.text; Update hidden value hiddenInput.value = suggestion.value; this.hideSuggestions(); } We may have put in a little overtime to accomplish all that s been done today. We created a controller class to handle all of our event management. We used the Prototype library s bindAsEventListener() method to automatically create clo- sures for us and normalize the IE and W3C event models. We implemented our key-up/down handlers to encapsulate the complexities of processing the selection as well as normal text input. We ensured that we initiate only requests for new information. We managed the showing and hiding of the suggestions UI as appro- priate. We updated the DOM programmatically to manage the hidden input value and the invisible text field that prevents form submission when the Enter key is pressed. And we handled the updating of the hidden and visible values of the TextSuggest component. On day 5, we wrap a bow around our refactored compo- nent by implementing all the methods required to create the pop-up, position it, show it, hide it, and manage its mouse events. The once dim light at the end of the tunnel is now clearly in view. 10.5.5 Day 5: the suggestions pop-up UI Now that we re fully plugged in, so to speak, it s time to tie up all the loose ends. To this point, we ve created infrastructure for
We would like to recommend you tested and proved virtual web hosting services, which you will surely find to be of great quality.

handleTextInput: function() { (Fedora web server) var previousRequest = Previous request

January 30th, 2008

handleTextInput: function() { var previousRequest = Previous request value this.lastRequestString; this.lastRequestString = Curren t request value this.textInput.value; if ( this.lastRequestString == “” ) this.hideSuggestions(); else if ( this.lastRequestString != previousRequest ) { Ajax request for data this.sendRequestForSuggestions(); } }, The handleTextInput() method first sets a local variable called previousRequest to the prior value of this.lastRequestString. It then sets the lastRequestString property to the current value of the input field so that it can compare the two to make sure that it s not trying to send a request for the same information that has already been requested. If the request is an empty string, the pop-up list is hid- den. If the request is a valid request for new information, the handleTextInput() method calls the sendRequestForSuggestions() method that we wrote yesterday to call the Ajax-based data source to get some suggestions from the server. If the request is the same as the last one, the request is ignored and no action is taken. Finally, the pieces are starting to come together. The construction, the configura- tion, the Ajax handling, the event handling it s almost as if we know what we re doing. And just in the nick of time; it s already day 4! We have one more method of our controller class to cover the onblur han- dler. The onblur handler is a very simple method that sets the value of the text field from the current selection and hides the suggestion. The implementation is as follows: onblurHandler: function(e) { if ( this.textSuggest.suggestionsDiv.style.display == ) this.textSuggest.setInputFromSelection(); this.textSuggest.hideSuggestions(
Visit our web design programs services for an affordable and reliable webhost to suit all your needs.

Business web hosting - era ) this.textSuggest.hideSuggestions(); if ( !this.handledSpecialKeys(e) ) this.textSuggest.handleTextInput();

January 30th, 2008

era ) this.textSuggest.hideSuggestions(); if ( !this.handledSpecialKeys(e) ) this.textSuggest.handleTextInput(); }, handledSpecialKeys: function(e) { var enterKey = 13; var upArrow = 38; var downArrow = 40; if ( e.keyCode == upArrow || e.keyCode == downArrow ) { return true; } else if ( e.keyCode == enterKey ) { this.textSuggest.setInputFromSelection(); return true; } return false; }, The key-up handler first checks to see if the input field contains any text. If not, it tells the TextSuggest component to hide its pop-up list of suggestions. Next it checks to see if the key pressed was one of the special keys: Up Arrow, Down Arrow, or the Enter key. If either the Up or Down Arrow key was pressed, the method just returns without performing any action, since the arrow keys have already been handled during the key-down processing. However, if the Enter key was pressed, the method tells the TextSuggest component to set its input value based on the currently selected item in the suggestion list. Finally, if the input field has a value and the key pressed was not one of the special keys, the key-up handler tells the TextSuggest component to consider that there is some input to be processed via the textSuggest.handleTextInput() method. This is the method of the TextSuggest component that finally calls the Ajax infrastructure we dili- gently put in place yesterday. The code for handleTextInput() is implemented in listing 10.32. 412 CHAPTER 10 Type-ahead suggest Listing 10.32 Text input handler
In case you need quality webspace to host and run your web applications, try our personal web hosting services.