- Getting Started
- Creating the Accordion Object
- Panel Functionality and Data Display
Creating the Accordion Object
The first object that needs to be created for the accordion component is the Accordion object. The Accordion object will handle parsing the XML as well as creating and controlling a variable number of panel objects. Accordions consist of multiple panels that stack on top of each other and expand and collapse to reveal hidden content. We will create a panel object that uses the prototype structure we discussed in Chapter 5, "Object-Oriented JavaScript." This will allow us to create multiple panel objects. Before we move onto the details of creating the panels, however, we will finish creating the Accordion object. Creating the Accordion object and initializing the properties is trivial, but there is an important sequence of events that needs to happen—otherwise, the object will not initialize properly. First, we must instantiate the object so that we can use its other methods. In order to trigger the initialize method, we must declare the method before we call it. The code snippet in Listing 10.5 shows an example of how we can accomplish this.
Listing 10.5. Accordion Instantiation and Initialization (Accordion.js)
Accordion = {}; Accordion.initialize = function() { panels = new Array(); expandedPanel = 0; } Accordion.initialize();
Calling the initialize method before declaring it will cause an error because the method does not exist in memory at this point and is not accessible. Notice that we have two properties in the initialize method: A new panels array is created and the expandedPanel number is set to 0. The panels array is simply an array of panel objects that the Accordion object will contain after the panels have been created. These panels will be added to the array in the display method and then be accessible to the other methods in the Accordion object. The expandedPanel number is used to determine which panel is expanded by default when the accordion is rendered. This is the property that will be set when we get the results of the XML file's expanded attribute.
To render the accordion, we will create a display method. This is the method we are using as the callback function for the Ajax request in the HTML file we created at the beginning of the chapter. The first thing we need to do in the display method is to check the ready state of the Ajax object. If the ready state returns "OK", we will continue with the method; if we do not receive "OK" as the value, we can add a number of branches to handle the different scenarios. For the example, I simply created a try-catch to display a generic message for failed requests.
When we receive a successful message, we need to create an accordion div element to act as the parent container for all the panels. When we have our accordion div element created, we need to iterate through the panels from the response by targeting the panel node element by name in the response XML. After we have an array of panel data from the response, we can use the length property of the panel array to iterate through the array. While iterating through the panel array, we need to get the title and content data for each panel. We will find the panel element with an expanded attribute that is set to true and use its iteration number to set the expandedPanel variable. The expandedPanel number will be useful for matching purposes because it will represent the unique ID of each panel object. When we have all the data from the XML targeted to local variables, we can push a new panel object into the panels array we instantiated in the accordion's initialize method. When creating the new panel we will pass it the iteration number as a unique ID, along with the title and content strings.
Now that we have the panel objects created, we can append the panel HTML elements to the accordion. We will accomplish this by using the appendChild method in the Utilities object and passing the accordion div element and each panel display method. The panel display method will pass all the HTML elements that are created inside the panel object and append them to the accordion. When we have completed iterating through the panels array and have appended them to the accordion, we will be able to append the accordion to the document body. Appending the accordion to the document body will render the accordion in the web page. Take a look at Listing 10.6 to see the display method in its entirety.
Listing 10.6. The Accordion's display Method (Accordion.js)
Accordion.display = function() { try { if(Ajax.checkReadyState('loading') == "OK") { var accordion = Utilities.createElement("div", {id:'accordion'}); var p = Ajax.getResponse().getElementsByTagName('panel'); for(var i=0; i<p.length; i++) { var title = Ajax.getResponse().getElementsByTagName('title')[i].firstChild.data; var content= Ajax.getResponse().getElementsByTagName('content')[i].firstChild.data; if(p[i].getAttribute('expanded')) { expandedPanel = i; } panels.push( new Panel(i, title, content) ); Utilities.appendChild(accordion, panels[i].display()); } Utilities.appendChild(document.body, accordion); Accordion.toggle(expandedPanel); } } catch(err) { document.write(err); } }
As you can see, there is a toggle method that I did not mention, which is called at the end of the display method. This is the reason we created the panel array and the expandPanel number variables. When the toggle method is called, it iterates through panel array and checks to see whether there is a panel ID that matches the ID parameter. When it finds a match, it expands that panel by ID; when it does not match, it collapses that panel. The expand/collapse panel methods are in the panel object, which we will create in the next section. Listing 10.7 shows the entire code for the accordion's toggle method.
Listing 10.7. The Accordion's toggle Method (Accordion.js)
Accordion.toggle = function(id) { for(var i=0; i<panels.length; i++) { if(panels[i].id == id) { panels[i].expand(); } else { panels[i].collapse(); } } }
As mentioned, the toggle method takes an element ID as a parameter and iterates through the panels array. When it discovers a matching ID, it expands that particular panel; otherwise, it collapses it.
Now that we have the Accordion object created, we can now focus on creating the panels. Another way to handle the accordion panels' toggle method is to allow multiple panels to be open at one time. To do this, you need to create a method that does not collapse other panels that are open. You also need to check whether the current panel that is being clicked is already expanded (if so, it should be closed). This keeps the expand/collapse nature of the panel intact.