In the first part of this post I looked at a jQuery based approach for adding tab navigation to Visio's Save as web output and the steps required to implement this. In this post I'm going to go into a little more detail about what the code we added is actually doing.
jQuery - Select and operate
There's a couple of good intro links to jQuery in the previous post, but in essence, what jQuery gives you is a CSS style selector to get hold of particular DOM elements and then a range of functions to manipulate the returned elements.
For example, the following snippet will return all anchor elements that are children of a list item element based on the CSS selectors passed into the jQuery wrapper:
jQuery("li a")
...and this snippet will return all div elements with a class of 'highlight':
jQuery("div.highlight")
Since the jQuery wrapper returns an array of elements (the wrapped set in jQuery parlance), as do a number of other jQuery functions, you can chain them together to perform a series of actions to each element in the array.
For example, the snippet below will firstly return a set of div elements that have a class of 'subtotal'. The fadeIn function will iterate through this wrapped set of elements and animate their opacity up to an original level. The fadeIn function also returns the original wrapped set and passes it on to the addClass function, which in turn will apply a class of 'alert' to each of the elements in the wrapped set:
jQuery("div.subtotal").fadeIn().addClass("alert")
In fact addClass also returns the original wrapped set so there nothing to stop you continuing the chain with further functions - that's quite a lot of functionality for a single line of code.
A final point is that the jQuery wrapper itself can be aliased with a $ symbol. So when you see $("li a") in the code, that's exactly the same as jQuery("li a").
Looking at the code
There are a few changes to makes to the main Save as Web page to enable tab navigation, but the key change is the adding of a new frame (as described in the previous post) to hold the new tab navigation page.
Once you got a frame and set its source property to tabNav.htm you can open up the file in an editor and you'll find that it's split into three basic areas:
- a script tag to hold the JavaScript
- a style tag to hold the CSS styling
- and the body tag that's home to an empty list
The body contains a div tag with an id of tabholder and it's this element that's targeted by the JavaScript as the page loads:
You can use the jQuery ready(fn) method on the document to apply the required functionality. This is roughly equivalent to using the window.onload function in straight JavaScript, the main difference being that while onload waits until the DOM structure and the entire page (including any slow loading images and other resources) has loaded, ready() just waits until the DOM structure has finished being loaded.
So, the function that you pass into the ready() method also contains three parts:
- Add a tab item for each page in the output - This loads the page names dynamically by iterating through an array of pages in a global variable (g_FileList), which is generated as part of Visio's standard output. Each name enclosed by list item tags (<li>) to create a string of list items which is finally added to the existing <ul> list tag within the tabholder div.
- Set the styling for the first tab - The first tab item in the list receives slightly different styling from the other tabs so you can add a 'first' class (defined in the CSS) by using the addClass jQuery function.
- Add a click event to navigate to the respective page - This final part adds a click event to each list item that fires the existing GoToPage function, again defined as part of the standard Visio output.
Once that's done there's just two more things that need to happen: you need to know when the drawing page changes and when it does to make the respective tab item appear active.
To accomplish this you can plug into an existing Visio provided function that gets fired whenever the page changes and that is CurPageUpdate(). Here you just need to add some code to call a style changing function in tabNav.htm. You can see what's going on in the two images below. The CurPageUpdate function is already passed the respective page index so you can use that in the SetActiveTab function, when you add the 'active' CSS class.
What about jQuery's UI plugin?
In closing, I'll just mention that jQuery has a number of very useful plugins that extend the core library. One of these is the UI plugin, which contains a range of UI related functionality, such as drag and drop, and controls or widgets such calendar, accordian and tab controls.
You may be wondering why I didn't make use of the tab widget in this case, and the reason is twofold. Firstly, Visio's Save as Web output is frame based and so doesn't easily suit the plugin's functionality. Secondly, a good deal of the functionality we need is already resident in the existing JavaScript and so we may as well make use of the hard work that's been included.