RichFaces 4 dynamic contextMenu with AJAX

Version 2

    As promised I`ll show how to implement a dynamic contextMenu with RF 4.5 using AJAX re-rendering. Actually there has never been any reason why the re-rendered contextMenu stops working. Therefore the requirement for dynamically rendered menu is, as mentioned, a fix for RF-14023.

    Lets take a closer look at the implementation based on existing showcase example with cars.

    What we currently need to do is:

     

    1. Capture the current (context)menu event in order to remember the actual mouse position and store it somewhere (I`ve decided to choose the RichFaces.ui namespace, but you can create own one) on selectionchange event just before submitting the AJAX request:

    <a4j:ajax execute="@form" event="selectionchange" listener="#{extTableSelectionBean.selectionListener}"
                        onbeforesubmit="if(event.type==#{rich:component('contextMenu')}.options.showEvent){RichFaces.ui.originalEvent=event;}"
    
    

    2. Re-render the contextMenu with id=contextMenu:

    <a4j:ajax
    render="contextMenu"
    
    

    3. The contextMenu contains dynamic part referencing current selection:

    <rich:contextMenu id="contextMenu" target="table" mode="ajax">
                    <rich:menuItem label="View #{extTableSelectionBean.selectionItem.vin}" render="popupContent"
                                   oncomplete="#{rich:component('popup')}.show();"
                                   mode="ajax" icon="/images/icons/open.gif"/>
    </rich:contextMenu>
    
    

    4. After the AJAX response we popup the contextMenu (if applicable) and forget the temporarily saved event:

    <a4j:ajax
        oncomplete="if(RichFaces.ui.originalEvent){#{rich:component('contextMenu')}.show(RichFaces.ui.originalEvent); RichFaces.ui.originalEvent=null;}"/>
    
    

     

    The result should look like:

    RF-14023.png

    The complete code is available here: Context Menu Showcase

     

    The clear difference to similar solution with RF 3 can be described as follows: if the selection change is completed, the contextMenu has been already rendered with current selection data and there is no need to do a round-trip to the server on contextmenu event- the user can click on the selected row as many times as he wants- everything is handled on the client. The only funny side effect is when the contextMenu currently shown updates its content (in a real application this effect can be minimized by locking the screen with modal status panel).

     

    By the way: a likewise solution for PrimeFaces i mentioned previously can be found in the PF forum