1 Reply Latest reply on Jul 13, 2011 9:14 AM by true_mykola

    Dynamic context menu for extendedDataTable

    true_mykola

      Hi! I have a problem with constructing dynamic context menu for my table. I want to build menu which takes its item from database depending on table i watch at the moment and on particular table item. First problem i faced was that i couldn't make context menu appear on right button click at all but then i found this article (http://community.jboss.org/wiki/HowToMakeWorkRightClickSameAsLeftClickOnExtendeddatatableAddingRowSelectionEventOnRightClick) and problem was solved. Now it looks like this:

      <rich:extendedDataTable ...>
        <rich:column></rich:column>
        ...
        <rich:column></rich:column>
        <a4j:support event="onRowMouseDown"
            reRender="btnPanel, out" eventsQueue="myQueue"
            oncomplete="#{rich:component('ctxMenu')}.doShow(event, {})"
            >
          <f:setPropertyActionListener value="#{item}" target="#{MbLabels.activeLabel}"/>
        </a4j:support>
      </rich:extendedDataTable>
      

      Now i can't reach my main goal: construct context menu depending on selected object. When i try to build it with c:forEach:

      <h:form>
        <a4j:outputPanel layout="block" id="out">
          <rich:contextMenu id="ctxMenu" attached="false" submitMode="ajax" disableDefaultMenu="true"
              selectItemClass="selected-menu-item">
            <c:forEach var="ctxItem" items="${MbLabels.menuItems}">
              <rich:menuItem
                  value="${ctxItem.label}"
                  action="${ctxItem.action}"
                  >
              </rich:menuItem>
            </c:forEach>
          </rich:contextMenu>
        </a4j:outputPanel>
      </h:form>
      

      my MbLabels.getMenuItems() never gets called but somehow i get one empty menu item which throws an exception when clicked:

      javax.servlet.ServletException: ${ctxItem.action}: javax.el.PropertyNotFoundException: //D:/workspaces/myProj/WebContent/pages/list_labels.jspx @367,10 action="${ctxItem.action}": Target Unreachable, identifier 'ctxItem' resolved to null

      When i use "binding":

      <h:form>
        <a4j:outputPanel id="out">
          <rich:contextMenu id="ctxMenu" attached="false" submitMode="ajax" disableDefaultMenu="true"
              selectItemClass="selected-menu-item" binding="#{MbLabels.popupMenu}">
          </rich:contextMenu>
        </a4j:outputPanel>
      </h:form>
      

      and construct menu programmatically inside my bean menu is built fine except one thing: the bean where context menu is constructed seems to loose its keepAlive status and becomes a request scoped bean with all consequences. Besides getter method for "popupMenu" is called only once: when the page is loaded for the first time. When i click "Search" or when i do right click on table item, MbLabels is rebuilt (inspite of a4j:keepAlive) but its getPopupMenu() isn't called though i added element which calls it to reRender attribute of a4j:support. I tried it with and without a4j:outputPanel but it didn't help. Situation gets worse when i try to build menu in separate bean (e.g, MbContextMenu, after all it should be built exactly this way) because the needed parameter (what menu to get from DB) doesn't make any sense both if i pass it with f:setPropertyActionListener in a4j:support for right button click or even when i pass it from constructor of main bean (MbLabels). In first case parameter i useless because getPopupMenu() is called only once as i've already said and it happens before any click. And in second case (when i pass parameter from constructor) it doesn't affect menu as well because MbContextMenu is constructed BEFORE MbLabels and its getPopupMenu() is called before it was initialized from MbLabels.

      So, my questions are:

      1) Why menu isn't built when i try to do it by iterating items with c:forEach? What's wrong with my code?

      2) Why does bean loose its keepAlive status if i build menu inside this bean and bind menu to element via "binding" attribute? Is it possible to avoid it?

      3) Why in any of these cases method that gets menu is called only once or isn't called at all?

      4) (Optional, because if questions above are solved this will be solved as well i suppose) How to pass parameter to MbContextMenu correctly?