Dear all, *Short intro:* I have started working on my project and will give brief updates each week on the dev list. I'm hosting my project on apache-extras<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/> and also I have setup a live preview of a demo app here http://dragansah.com/contextmenu/ (its on my home pc so it should work pretty much all the time). The demo has link to the source code of every page you see and also the most important files are listed on the right.
I have started working on the RightClickMenu or ContextMenu component and you can see examples in the demo app. * * *A brief overview:* The ContextMenu is done as a mixin and produces a context menu of the component it is applied to. There are two mixins ContextMenu<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenu.java>and ContextMenuAjax<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenuAjax.java>which produces an ajax update of the content once right clicked. Maybe I will merge these two, but then the question is how to give the option of an ajax update. If its through a parameter it may get annoying? The javascript code (contextmenu.js<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/webapp/js/contextmenu.js>) is done using prototype and maybe by the end I will implement a version without using a js framework. I have also implemented support for the tapestry5 grid component (demo here<http://dragansah.com/contextmenu/gridexamples>). It is done using an advice and a ClassTransformWorker on the GridCell component. Comunication between the Advice and the ContextMenu is done using the Enviroment. Here is the explanation given in the demo page. The context menu for the grid is done by pulling data from GridCell<http://tapestry.apache.org/tapestry5/tapestry-core/ref/org/apache/tapestry5/corelib/components/GridCell.html> during rendering and making it available to the ContextMenuAjax<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenuAjax.java> mixin. This is done in GridCellWorker<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/services/GridCellWorker.java> by applying an advice on AbstractPropertyOutput.renderPropertyValue(MarkupWriter writer, String overrideBlockId).<http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.html#renderPropertyValue(org.apache.tapestry5.MarkupWriter, java.lang.String)> The communication between the GridCellWorker<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/services/GridCellWorker.java> and the ContextMenuAjax<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenuAjax.java> mixin is done via the Environment<http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/services/Environment.html> using the GridCellContextList<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/data/GridCellContextList.java> as an environmental object. The ContextMenuAjax<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenuAjax.java> can be configured with a parameter to be used in 3 levels: - *CELL* - one menu per grid cell (td) - *ROW* - one menu per grid row (tr) - *GRID* - one menu for the entire grid Right click an employee to see its salary: So here are some issues for now (please feel free to comment on them). 1. Two mixins: ContextMenu and ContextMenuAjax or merge them in one mixin? 2. Is the concept of advising GridCell (actualy AbstractPropertyOutput<http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/corelib/base/AbstractPropertyOutput.html#renderPropertyValue(org.apache.tapestry5.MarkupWriter, java.lang.String)>) ok? Its clear that we cannot implement support of the t5 grid without an advice or I'm I wrong? 3. Grid support is just ajax for now I will implement, no ajax support next week. 4. The ajax and the no ajax version of the mixin fire a *ContextMenu*event with a context that is set by a t:context parameter in the mixin (may clash with a component's t:context param so I'll rename it) . The grid support version fires a tapestry event with context from 3 parameters: the row object that used to render the grid, PropertyName (name of the property in the TD that is clicked on) and the PropertyValue (value of the property in the TD that is clicked on) You can see the example code here<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/pages/GridExamples.java> . 5. The contextmenu is rendered after the component and there is a bit of a quirk here. Please see ContextMenu.java<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/java/org/apache/tapestry5/contextmenu/mixins/ContextMenu.java> and contextmenu.js<http://code.google.com/a/apache-extras.org/p/right-click-menu-gsoc2011/source/browse/trunk/contextmenu/src/main/webapp/js/contextmenu.js>. The quirk is that the contextmenu forces the render of the conainer's clientId (if it is a t5 ClientElement), and uses it to set a javascript event oncontextmenu on it using the id. If the component is not a t5 ClientElement (t5 Label for example), than this javascript is applied for getting the client element in js: $('contextMenuId').previousSibling. This code assumes that the parent component is only one html element (div or similar), but this is not the case for example the t5 TextField which renders a trailing icon. Luckily the TextField is covered because it is a ClientElement, but for other similar components it wont work, because the menu will be set only on the second element. The shortcoming is clear and I have no idea how to resolve it for now. So that's it for this week. Please give all the ideas you have about the component and possible enhancements. Cheers, Dragan Sahpaski
