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

Reply via email to