jQuery
Mar 11, 2010
Careful with that ajax, Eugene
Ajax calls are an invaluable and powerful tool to deploy pleasant user interfaces, but some attention must be paid to avoid bad surprises.
In these days it happened to me to work on a couple of custom Plone edit forms using ajax calls to simplify user data entry.
At a first glance, the user experience was great, but under the hood the whole machinery was hiding potential problems, the reason being that in both cases the ajax calls used in the form were relative to the document path, even when if the document was in the factory!
This means that every time the ajax call was invoked, additional security checks were performed and in the case of the documents inside the factory other this lead to an unwanted creation of temporary documents!
The security checks and the portal factory abuse increased the response time and could potentially raise conflict errors.
During the development phase the problem is hardly noticeable, but on a production server it will probably make the form unusable, especially if you complex security checks are needed.
The solution was simply to call the views with another context (in those cases the container).
Lesson learned: be careful to the context of your ajax call
Dec 14, 2009
collective.flowplayer_toolbar: adding accessibility in an unobtrusive way
The way I used to make Flowplayer use inside Plone a little more accessible, this time without branching the collective.flowplayer product!
First of all: some terms
After finishing this article I understand that people not familiar with this argument and software can be confused, so:
- Flowplayer (in capitalized form) is a Flash player for audio/video files, indipendent from the Plone technology.
- collective.flowplayer is a Plone products that use Flowplayer and give this player well integrated in Plone CMS
- collective.flowplayer 1.x is an old release family, that use Flowplayer 2.x
- collective.flowplayer 3.x is the last release family, that use Flowplayer 3
Introduction to main characters
Flowplayer is one of the most promising Flash audio/video player available right now, and we can use it in a simple way inside Plone site thanks the collective.flowplayer, a well know product that replaced the use of p4a.video in recent Plone experiences.
Flowplayer is good, and open source, but not the most accessible available player. Our work with collective.flowplayer accessibility begin when the available release was the 1.0.x version.
As noted above, Flowplayer version used in this old release was the old 2.x, so many of the most recent and cool features were missing; on the other hand, the current 3.x family is heavily integrated with jQuery Javascript framework.
Not less important, the Flowplayer team is the one who released the jQuery Tools, the javascript addon for jQuery recently integrated in Plone 4 thanks to plone.app.jquery.
Fixing collective.flowplayer 1.x
The main accessibility problem of Flowplayer is its flash controlbar. Practical tests show that is not easy to handle video controls using the keyboard.
Our customer, the same that ask for accessible videos in Plone and also like Flowplayer very much, provide us a static HTML example of Flowplayer that use Javascript controlbar, simply usable with keyboard. The problem was that this example supports Flowplayer 3.2, the current version of the Flash player, but not the version used in the Plone addon.
Also the example provide a patched version of the controlbar plugin for Flowplayer. This custom version add some missing HTML attributes and WAI-ARIA support.
After looking on the web we found that even if Flowplayer 2 was backward compared to the new branch, it provides some limited APIs, usable through Javascript.
Our target was to replicate all the feature seen in the Flowplayer 3 demo in the Flowplayer 2 environment... of course this was not so easy! However after some work we find a way to provide those features:
- a play/pause button
- a stop button (not required, but was simple to do)
- a timer display
The only feature "impossible" to obtain (directly) was the progressbar... to be honest, some additional Javascript could also realize this (we have the duration of the video, we have the current execution time, we know how to perform arithmetic division... why not draw ourself? :-) but was enough.
What we really don't like was this: we found no (simple) way to write a Plone addon that work with collective.flowplayer 1.0, adding to it our new features.
We don't waste more time: we made a branch of the original collective.flowplayer 1.x, providing our new feature.
Thank you! Thank you! We have collective.flowplayer 3.x!
After a few weeks collective.flowplayer 3.x was released (I think that the developers team skipped the 2.x version for aligning the Plone product's version to the Flowplayer one).
So we came back to the original example give to us (the customer project was happy finished using our branch) just for test the new feature available and to understand is in future a new, better approach is possible.
The API's of the latest Flowplayer versions are more complete and powerful, heavily filled with the jQuery power.
This time we were able to develop something that could live and enhance the original collective.flowplayer, releasing only a new product: collective.flowplayer_toolbar.
The final result really better than the old approach; without embarrassment I can say that we did a few line of codes! The most part of the work of our new controlbar came from Flowplayer features and one more time from the great jQuery library.
You want see the "core" of this product?
/**
* Javascript code for adding accessible toolbar to flowplayer players in the page
*/
jq(document).ready(function(event) {
$f("*").each(function() {
this.onLoad(function(event) {
this.getPlugin("controls").hide();
var p = jq(this.getParent());
var p_width = p.width();
var time_width = (p_width<400?99:129);
var hulu_id = "hulu-"+ (jq(".hulu").length+1);
p.after('<div id="'+hulu_id+'" style="width:'+p_width+'px" class="hulu">\n'
+'<a class="play" href="javascript:;" role="button">Play</a>\n'
+'<div class="track" style="width:'+(p_width-46-46-time_width)+'px">\n'
+' <div class="buffer"></div>\n'
+' <div class="progress"></div>\n'
+' <div class="playhead"></div>\n'
+'</div>\n'
+'<div class="time" style="width:'+time_width+'px"></div>\n'
+'<a class="mute" href="javascript:;" role="button">Mute</a>\n'
+'</div>\n');
this.controls(hulu_id);
// Now I'll fix all other positions of the new toolbar
jq("#"+hulu_id+" a.mute").css('left', p_width-46);
jq("#"+hulu_id+" div.time").css('left', p_width-46-time_width);
});
});
});
The rest of the egg simply use a limited version of the original CSS of the demo page in Flowplayer site, the patched controlbar plugin (but you can use the original one without problems)... nothing more!
The jQuery presence make real the injection our new feature on existings Flowplayer instance in the page (for example, this is also working properly for our redturtle.video product). No need to patch/branch collective.flowplayer, also no need to override some views or resource of it.
Conclusion
This work can be also a proof-of-concept for future Flowplayer integration with additional features. The player supports many additional plugins (Yuri point my attention to the Caption Flash plugin...).
Oct 04, 2009
Hidden Javascript Jewels inside Plone!
The basic Plone installation rely on some little javascript sources that can be very useful.
Right now Plone is filled with a lot of jQuery javascript script for obtain UI effects. Every time you need an effect that Plone has, you must before ask to you: I'm sure that I only need to write down some good HTML, and nothing more?
Please not that even if this page try to integrate the same examples reported, you can't really see them working due to CSS issue. Use Firebug "Inspect element" feature to see how the javascript is changing the DOM.
Expand/collapse like "history" does
The javascript jem responsible of this is collapsiblesections.js.
It's javascript docstring says:
/* - collapsiblesections.js - */
/*
* This is the code for the collapsibles. It uses the following markup:
*
* <dl class="collapsible">
* <dt class="collapsibleHeader">
* A Title
* </dt>
* <dd class="collapsibleContent">
* <!-- Here can be any content you want -->
* </dd>
* </dl>
*
* When the collapsible is toggled, then the dl will get an additional class
* which switches between 'collapsedBlockCollapsible' and
* 'expandedBlockCollapsible'. You can use this to style it accordingly, for
* example:
*
* .expandedBlockCollapsible .collapsibleContent {
* display: block;
* }
*
* .collapsedBlockCollapsible .collapsibleContent {
* display: none;
* }
*
* If you add the 'collapsedOnLoad' class to the dl, then it will get
* collapsed on page load, this is done, so the content is accessible even when
* javascript is disabled.
*
* If you add the 'inline' class to the dl, then it will toggle between
* 'collapsedInlineCollapsible' and 'expandedInlineCollapsible' instead of
* 'collapsedBlockCollapsible' and 'expandedBlockCollapsible'.
*
*/
This piece fo code can be great for obtain the same sexy expand/collapse feature that you see all around Plone UI.
For example, I can use here this code:
<dl class="collapsible collapsedOnLoad">
<dt class="collapsibleHeader">
See the RedTurtle Hidden logo
</dt>
<dd class="collapsibleContent">
<img alt="The RedTurtle Logo" src="http://www.redturtle.net/logo.jpg" />
</dd>
</dl>
And what is the results?
- See the RedTurtle Hidden logo
-
Dropdown menus
Wow! Can you believe that the dropdown menus you see in the working area of Plone (like "View", "Add portal content", ...) are only a piece of simple HTML and a magic javascipt does all the work?
The script this time is dropdown.js.
It says:
/* - dropdown.js - */
/*
* This is the code for the dropdown menus. It uses the following markup:
*
* <dl class="actionMenu" id="uniqueIdForThisMenu">
* <dt class="actionMenuHeader">
* <!-- The following a-tag needs to be clicked to dropdown the menu -->
* <a href="some_destination">A Title</a>
* </dt>
* <dd class="actionMenuContent">
* <!-- Here can be any content you want -->
* </dd>
* </dl>
*
* When the menu is toggled, then the dl with the class actionMenu will get an
* additional class which switches between 'activated' and 'deactivated'.
* You can use this to style it accordingly, for example:
*
* .actionMenu.activated {
* display: block;
* }
*
* .actionMenu.deactivated {
* display: none;
* }
*
* When you click somewhere else than the menu, then all open menus will be
* deactivated. When you move your mouse over the a-tag of another menu, then
* that one will be activated and all others deactivated. When you click on a
* link inside the actionMenuContent element, then the menu will be closed and
* the link followed.
*
*/
So you only need to design an HTML dl structure like this:
<dl class="actionMenu" id="myDummyMenuId">
<dt class="actionMenuHeader">
<a href="some_destination">Open the magic dropdown</a>
</dt>
<dd class="actionMenuContent">
<img alt="The RedTurtle Logo" src="http://www.redturtle.net/logo.jpg" />
</dd>
</dl>
Here follow the example usage
Conclusion
There is a lot of Magic behind Plone, but thanks to jQuery and a smart infrastructure you can use this Magic for your needs!

