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!
One 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?
However: 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.
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?
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).
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.
All the magic left is done by the power of jQuery.
Plone 4 and jQuery 1.4
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!