Personal tools

Apr 11, 2010

Change navigation behaviour with jQuery: collective.navigationtoggle

A requirement from one of our customer lead us to develop a very tiny Plone add-ons... After all jQuery make all the dirty work!

Navigation collapsedOne of the navigation portlet in the main site of our customer is done like the one you see on the left.

The element with arrow icon is unique and very important, but is not the element itself that links to an important document. The real useful information for end users are elements inside the section with this special icon (the subelements).

If facts the different icon itself is not enough so the customer asked us to develop an expand/collapse feature to make possible to users to not be forced to visit the not-important-section, then choose one of the subelements. For user experience the first click is only a waste of time (it's matter of usability) as the general element you see in the navigation is only a way to keep together and categorize the real infos.

Question: how many not-important-section you have in your Plone sites? Folder that only show folder_listing view or useless welcome pages?

Navigation expandedHowever: what we developed in the first version of this site was a very simple (and not configurable) expand/collapse feature, you'll see on the right.

This was a Plone 2.1 site and what you see wasn't a real Plone navigation portlet. Important subelements were all loaded with the page and a simple Javascript script make them visible/invisible.

As we recently migrated this site to Plone 3, the question was: can we reproduce the same effect keeping the Plone real navigation... and this time make the feature more reusable?

Some of you can say at this point that there are already other dynamic Javascript/AJAX navigation system for Plone (for example, I well remember collective.portlet.explore) but the problem here is different... we don't want to make all navigation(s) entries expansible/collapsible but only one (or few).
Another important fact: this is the site of an italian public company, so it must follow the Stanca Act accessibility requirements (so very restrictive in matter of client side scripts technology) and a complete Javascript UI is not a good choice.

The role of jQuery

Instead of developing some new funny navigation system, our work was focused on making the most possible client side (whit an eye on graceful degradation like the Law say).

We used jQuery to obtain a cross-browser, configurable and simple plugin for Plone that make possible to chose on which navigation elements apply the expand/collapse feature. All this client side!

Welcome to collective.navigationtoggle.

The only server side component is a simple view that query the Plone catalog to show all element inside a given folder, and return all information needed by jQuery to generate navigation sub-elements on the fly (quite simple, isn't it?).

The view return only a JSON data structure, so the HTML is generated client side. How? The code create new navigation elements cloning existing ones from the navigation itself (using parents of the trigger element), then filling them using response data.

Is this way is possible that even a non-standard Plone navigation could works normally with this product (not so sure of this... to be honest some assumption are done, like the main element structure of the navigation that must be composed of UL and LI elements).

Cache

Two different problem there: prevent browser from caching server response for a too long time, but also prevent that if a user begin to click 10.000 times onto the navigation element this will send to the server one non cached request for every click.

The first problem is quite simple playing a little bit with HTTP header sent by the server, and adding timestamps with the client side request.

For the second problem we rely on jQuery.data() fantastic method, caching the generated HTML and preventing that expand/collapse actions will ask the server for the same data.

Configuration

Right now we have a real well-know problem to solve, so the product is targeted on developers. To configure it you must provide a tiny Javascript with line(s) of code like this:

jq.collective_navigationtoggle.toggle_elements.push("/foo1/foo2");

This is a simple Javascript array stored in the jQuery plugin namespace. Data provided must be the final part of the href attribute of links inside navigations portlet. This link will no more move the user to the target page but will be gifted with the expand/collapse feature.
All the magic left is done by the power of jQuery.

Plone 4 and jQuery 1.4

The product works on Plone 4 also... no problems with jQuery 1.4 (delivered with the next version of our favorite CMS, while Plone 3.3 still rely on jQuery 1.3), in facts dropping jQuery 1.3 support can reduce the Javascript code size and complexity (jQuery 1.4 has new fantastic features... take a look!).

However a real and pretty integration like with the Plone 3 theme right now is not available in Plone 4 also. Maybe in future I can work on this (Plone 4 Sunburst is not using anymore the IMG tag, instead it generate icon usin CSS classes). If you are interested and wanna help, you are welcome!

comments powered by Disqus