|
|
|
01/20/2006
In this screencast, the view that let people change the elements order has been extended in order to be able to drop them on the navigation portlet, and therefore move elements in other folders. The interesting part of this approach is about publishing: as seen in the animation, when "Link 1" is dragged from its workspace to a section of the portal, it is automatically published, and follows the right workflow transition. This one step publishing process should be very useful to avoid the intermediate screen where we choose a publishing place. Another eye-candy effect has been added when a drop cannot be performed: the small ajax floating layer pulsates and turns red: it's angry ;) Feed readers, there's a flash animation in this entry, you should use your browser in order to see it
01/19/2006
My french book about Python is out now !
I would like to thank Stéfane and Stephan Richter for the great forewords they provided for this book. Like Stéfane previously said, a dedicated site has been made to cover errata, news around the book, and all usual stuff. French readers, a contest is running in order to win a book, try to answer to those very hard questions :)
01/11/2006
In this round, the objective is to add a feature in ordered folders in CPS, that let the user drag elements and drop them within the same page, to change the elements order. Here's the result: Macromedia Flash Plugin required This is quite simple, even though the javascript part gets a bit longer and tougher to create than the previous rounds, but more interesting because we are going to add server-side code that can be reused later on in Zope 3. Zope 3 style server-sideDoing this feature in Zope 3, would involve coding some kind of Ajax view that would know how to deal with the current context (ie: the ordered folder) and a directive in the zcml, in order to hook the view with a method associated to the current folder. Thanks to Five, we can use this path within Zope 2. The view which is quite simple, introduces a method that simply gets the id of the element that is beeing dragged and the id of the element that receives the drop. It returns the new order, so the javascript side can play with the DOM to reorder the list:
from Products.Five import BrowserView
class AjaxFolderView(BrowserView):
def moveElement(self, from_id, to_id):
if (not from_id.startswith('draggable') or
not to_id.startswith('droppable')):
return ''
from_id = from_id[len('draggable'):]
to_id = to_id[len('droppable'):]
if from_id == to_id:
return ''
proxy_folder = self.context
to_position = proxy_folder.getObjectPosition(to_id)
proxy_folder.moveObjectToPosition(from_id, to_position)
return ':'.join([id for id in proxy_folder.objectIds()
if not id.startswith('.')])
This view derives from Five's BrowserView, in order to be able to hook it in the zcml. The zcml just associates the IOrderedContainer interface:
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="cpsdefault"
>
<browser:page
for="OFS.interfaces.IOrderedContainer"
name="ajaxMoveElement"
class=".browser.ajaxfolderview.AjaxFolderView"
attribute="moveElement"
permission="zope.Public"/> <!-- TODO: secure the method -->
</configure>
That's it ! The server-side infrastructure provides now a method in all ordered folders that can be used asynchronously by any ajax toolkit. Client-sideThe client side can be found here in a branch of CPSDefault: client side
01/06/2006
Sometimes images are betters than explanations... Here's a small flash movie that shows the use of scriptaculous cinematics in CPSWiki, wich allows the user to work on the wiki through Ajax. The resolution might not be displaying well on the blog,
so you can also download the movie here if you want a better experience:
Posted by Tarek Ziadé @ 01/06/2006 05:45 PM.
-
Categories:
AJAX,
cps,
rich_client,
zope,
zope3
-
0 comments
01/05/2006
I really enjoy the graceful degradation approach. It's a pleasure to enhance CPS user interfaces that way. Last time the edit form for simple document was ajaxified in order to give the user a fast way to get feedback when she changes the data. The next challenging step on these form is to enable file uploads so complex documents will be ajaxified as well. The iframe technique is the only technique i've hurd of for this task. Some guys over the Ruby ML also explained me how to do it with a bit of Flash in the form but this is a dependency we don't want. Anyway, this enhancement will be exposed in round #3 or #4. Round #2 is about a quick and lazy todo, yet powerfull feature: autocompletion. This is just great: with Scriptaculous there's absolutely nothing to code :). The well-thaught Ajax.Autocompleter class knows automatically how to grab an input field and link it to a server-side or a client-side data provider. The class deals with all the hard work, automatically showing and hiding the panel that contains the choices. Every command you would think of to select an element from the list (keyboard, mouse) just works as expected. I won't expose how all this works, just take a look at this demo and enjoy their work. Client-side data or server-side data ?Like said previously, a decision has to be made when this kind of widgets are used: where does the data that feeds the popup panel live ? That's a topic you can talk about for hours with Paul Everitt, who is a preacher of the full client-side approach. In his demos, Paul loads data at startup and play with it on the form through javascript. It's very impressive, as the whole screen can be repainted without calling the server ever. If I were working at BuzzwordMakers Corp., I would call this approach the Lazy Ajax Painting (LAP). But too much LAPing can deteriorate the user experience: the lag involved can be really bad, and she might try to refresh the page over and over again, because it seems locked or some similar feeling. Furthermore, the retrieved data is dead: if someone else changes it on the server it won't change on her client browser, unless an expensive observer that recheck datas once a while is settled. On the other hand, too much asynchronous server calls can drawn everything as well... But autocompletion means the output is beeing filtered out at least by the first character, so the amount of data is not so bad. For example, if the widget is used to select some people over a LDAP directory that contains 5k users, the first data packet will be composed of an average of 200 entries at most. The second character put this number down to 8 entries or so. In case of a big directory, a smart approach would be to block the autocompletion feature until the user has typed a few characters. Anyway, this is the same scale than regular queries over directories, so a full server-side data provider is probably the way to go in most case. If needed, the widget can combine both ways, and decide which one to use depending on the amount of data. CPSAutoCompletionString widgetBack to CPS: I've created a new widget called CPSAutoCompletionString that is just a simple String widget with an extra piece of javascript. It adds a class initialization and roughly renders someting that looks like this:
<input type="text" name="field" id="field" value="cool value"/>
<div id="field_choices"/>
<script type="text/javascript" language="javascript">
new Ajax.Autocompleter("field", "field_choices", "server_method", {});'>
</script>
The input will use the div, feeded with value asynchronously retrieved with the server_method. That's it. cough cough. (Some may argue it's even shorter in Ruby on Rails, but it looks short enough to me ;) ) Now the cool part: the server method has been kept totally out of the widget code in order to let the developer code it as he wants. A Zope 3 view can be done, or a raw Zope 2 skin as well. The server side has to send a <UL> tag with all entries in it. Since this javascript code works with the raw responseText, we don't need to implement a special transport protocol (json, rpc, ..) The result is just used to fill the div. Example of Zope 2 skin: ##parameters= # I wish I had Five installed so I would do a view here :') return '<ul class="cpsskinsMenu"><li>one</li><li>two</li><li>three</li></ul>' There's no filtering in this example, but it's really simple to send the current input in order to filter entries, and I'm still working on it. ConclusionCPSAutoCompletionString has been integrated for CPS 3.4.0 but won't be used in any CPS forms yet, as this will be done later on. You can already use it though, in your custom CPSSchemas layouts, or through CPSTypeMaker. CPS Developpers, if you give it a try, let me know !
Posted by Tarek Ziadé @ 01/05/2006 10:41 PM.
-
Categories:
AJAX,
cps,
rich_client,
zope,
zope3
-
2 comments
Last modified:
01/25/2005 06:15 PM
|
Nuxeo Bloggers: Log in! Search Nuxeo Blogs
About this blog
Tarek Ziadé Nuxeo Bloggers
Photos and Pictures
|
|
Nuxeo -
Indesko -
Nuxeo 5 Project
All content is copyrighted by their author. CPSSkins is Copyright © 2003-2006 by Jean-Marc Orliaguet. | CPS is Copyright © 2002-2006 by Nuxeo SAS. |