Creating a Utilities Object


The samples that we build throughout the rest of this book will rely heavily on specific DOM-related methods. These methods will simplify common JavaScript functions, create any HTML element that we need, and be reused to avoid the duplication of common code throughout our applications.

Before we create any methods, we must first instantiate the Utilities object as follows:

Utilities = {};


This object is based on the Singleton pattern, which we will discuss in Chapter 14, "Singleton Pattern." Creating methods in this object is simple: First use the name of the object, followed by the name of the method. Take a look at the following example:

Utilities.createElement = function() {}


The methods that currently exist in the Utilities object are extremely reusable and will be used heavily throughout the rest of the book samples. We will start by adding two methods: one that includes JavaScript files named includeJS (see Listing 9.1), and another named includeCSS, which includes CSS files (see Listing 9.2). Each method includes the corresponding array of files in any document by accepting an array of file paths.

Listing 9.1. Including JavaScript Files (Utilities.js)

Utilities.includeJS = function(filepaths) {     for(var i=0; i<filepaths.length; i++)     {         document.write('<script type="text/javascript" src="/books/1/87/1/html/2/'+filepaths[i]+'"></script>');     } }

Listing 9.2. Including CSS Files (Utilities.js)

Utilities.includeCSS = function(filepaths) {     for(var i=0; i<filepaths.length; i++)     {         document.      write('<link href="'+filepaths[i]+'" rel="stylesheet" type="text/css" />');     } }

These methods are simple but they save a lot of typing, or copying and pasting, and make our HTML page more manageable. They also save time and prevent errors if a change needs to be made to the include statement because we will have to make the change only in the method rather than in multiple tags that would reside in the HTML file. The following is an example of how we could use these methods in a web page:

[View full width]

var cssFiles = new Array("pathto/css/file.css", "pathto/another/css/file.css"); Utilities .includeCSS(cssFiles); var jsFiles = new Array("pathto/javascript/file.js", "pathto/another/javascript/file.js"); Utilities.includeJS(jsFiles);


The next method, named getElement, is even simpler than the previous two. This method returns an element by ID by accepting a string parameter and using JavaScript's intrinsic getElementById method. Ultimately, this method is just a shorthand version of the intrinsic method and allows us to make changes to the method only if we need to do so in the future.

Utilities.getElement = function(i) { return document.getElementById(i); }


Debugging is one of the largest complaints when it comes to JavaScript aside from the debugger tools that I mentioned in Chapter 8, "Debugging." This next method has saved me a lot of grief and will hopefully do the same for you. It is conveniently named debug and takes any value as a parameter and writes it to a debug tag that you must specify anywhere in your HTML (see Listing 9.3), specifically during development and testing. This method also gives us an example of how to use the getElement method, which we just covered.

Listing 9.3. Debugging with the Utilities Object (Utilities.js)

Utilities.debug = function(val) {     this.getElement('debug').innerHTML += val +"</br>"; } <!-- A Sample Debug Element --> <div "></div>

In Chapter 18, "Interaction Patterns", we will learn about interaction patterns and GUI-related code that can be used in your Ajax applications. The next method, named toggle (see Listing 9.4), is one that will get a lot of use in chapters to come. This method takes an ID of a DOM element and checks to see whether the element's display style is equal to an empty string or to the string value of 'none'. If it is empty, it sets it to 'none'; if it is 'none', it sets it to an empty string. This code toggles the visibility of any DOM element by ID at anytime, from any object.

Listing 9.4. Toggle Element Visibility (Utilities.js)

Utilities.toggle = function(id) {     this.getElement(id).style.display = (this.getElement(id).style.display == '') ? 'none' : ''; }

The next method that we will examine is one that creates a DOM element that can later be written to the document body. I have conveniently named this method createElement (see Listing 9.5). The createElement method takes two parameters: a string that represents the HTML element type that you want to create, and an object.

Listing 9.5. Creating Elements with the Utilities Object (Utilities.js)

Utilities.createElement = function(e, obj) {      var element = document.createElement(e);      for(prop in obj)      {          element[prop] = obj[prop];      }      return element; }

The createElement method dynamically creates elements that can be used to display data in the page. It can create any HTML elementa few examples are div, span, img, a, li, and so onbased on the string that is passed as the first parameter. What makes this method even more extraordinary is the fact that it can accept properties as JSON and append them along with their values to the element. This method appends properties to DOM elements by iterating through the properties in the JSON parameter and creating properties on the DOM element. The following is an example of how to use this method:

[View full width]

var title = Utilities.createElement("div", {id:'title', className:'title', innerHTML :'title'});


This method might have created an HTML element, but the createElement method cannot write this element to the page on its own. This is why we need to create the next method, named appendChild (see Listing 9.6).

Listing 9.6. Appending Child Elements to the Document (Utilities.js)

Utilities.appendChild = function() {     if(this.appendChild.arguments.length > 1)      {          var a = this.appendChild.arguments[0];          for(i=1; i<this.appendChild.arguments.length; i++)          {              if(arguments[i])              {                 a.appendChild(this.appendChild.arguments[i]);              }          }          return a;      }      else      {          return null;      } }

This method handles appending HTML elements to one another and, ultimately, the current document by appending elements to the document body. It uses JavaScript's intrinsic arguments property, which is an array that contains all the input parameters for the current method. This arguments array can then be iterated to provide each parameter that was passed to the method. This property allows developers to create methods that can change based on the parameters. The following is an example of how we could write the previously created title div to the document body:

[View full width]

<html> <head> <title>Sample</title> <script type="text/javascript" src="/books/1/87/1/html/2/../javascript/Utilities.js"></script> <script type="text/javascript"> function init() { var title = Utilities.createElement("div", {id:'title', className:'title', innerHTML :'title'}); Utilities.appendChild(document.body, title); } </script> </head> <body onload="javascript:init();"> </body> </html>


As you can see, we must wait to create the element and append it to the document until the body of the document has completely loaded. If we do not wait until the document has fully loaded, the element that we are appending to will most likely not exist when this code is executed and will throw an error that cause the code to fail. Therefore it is important to be patient. After it has loaded, we can write the element and append it however we please. Remember, this is a very simple example to show you how to use these methods. It might seem like a lot of overhead just for writing the word title to a web page (and it obviously is), but imagine adding a stylesheet to the page to handle formatting the elements that you are writing, or appending other elements to the title element before appending it to the body. The possibilities are endless and can become extremely efficient when we create objects to manage rendering components. All we need to do is pass the newly created element content from an Ajax request that returns dynamic XML based on data in a database. And don't forget, this will all happen without a page refresh.

The next method is named removeChildren and it does just that. It takes an element as a parameter, and checks to see if the parameter is null; if so, it returns nothing. If the value is not null, we enter a while loop based on the hasChildNodes method. This creates a loop while the element has childNodes. In this loop we perform a removeChild on the element and pass its firstChild as the parameter. In the end the element is stripped of all its children and the method has accomplished its goal. Listing 9.7 shows the complete removeChildren method.

Listing 9.7. Removing Children from Their Parents (Utilities.js)

Utilities.removeChildren = function(node) {     if(node == null)      {         return;      }      while(node.hasChildNodes())      {          node.removeChild(node.firstChild);      } }

The next two methods are useful for adding listeners for events based on how the browser happens to handle them, since the browsers cannot seem to get along. The first method will be named addListener and the second removeListener. Both methods take the same three parameters; an object, an event name, and a listener. The obj parameter represents the element in which you want to assign the listener to, such as the document object. The eventName parameter represents the event to register the listener to, which could consist of anything from a mousemove event to a click event. The last parameter listener is the custom method that you want to be called each time the event is fired. This is the actual method doing the listening. The only difference between the two methods is that one adds and one removes listeners. Listing 9.8 shows both methods as they appear in the Utilities object.

Listing 9.8. Adding and Removing Listeners (Utilities.js)

Utilities.addListener = function(obj, eventName, listener) {      if (obj.attachEvent)      {         obj.attachEvent("on"+eventName, listener);      }      else if(obj.addEventListener)      {         obj.addEventListener(eventName, listener, false);      }      else      {          return false;      }      return true; } Utilities.removeListener = function(obj, eventName, listener) {      if(obj.detachEvent)      {         obj.detachEvent("on"+eventName, listener);      }      else if(obj.removeEventListener)      {          obj.removeEventListener(eventName, listener, false);      }      else      {          return false;      }      return true; }

Each method checks to see what browser the user is using. If it is IE, we add the "on" string to the beginning of the eventName when we attachEvent of detachEvent in order to reference the event name as IE expects it. If the user is in another browser, the method uses the addEventListener and removeEventListener events and the parameters are passed to these methods as is.

The last method in the Utilities object is a visual one. The object is called changeOpac and it changes the opacity of an element in any browser by simply passing a number and an element ID to the method. Listing 9.9 shows this method and how it handles changing all the different browser opacities.

Listing 9.9. Changing the Opacity of an Element (Utilities.js)

Utilities.changeOpac = function(opacity, id) {      var object = Utils.ge(id).style;      object.opacity = (opacity / 100);      object.MozOpacity = (opacity / 100);      object.KhtmlOpacity = (opacity / 100);      object.filter = "alpha(opacity=" + opacity + ")"; } 



Ajax for Web Application Developers
Ajax for Web Application Developers
ISBN: 0672329123
EAN: 2147483647
Year: 2007
Pages: 129
Authors: Kris Hadlock

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net