سؤال

In our application we are displaying the menus dynamically. We have the menu object(menuitems in below code) populated with all the menu items (read from an xml). The home page then generates the menus by usinng ui:repeat. Insdie ui:repeat there are p:commandlink. Below is the code

   <h:form id="mainMenu">
    <h:panelGroup id="MMPanel" layout="block" styleClass="left_menu">
        <ui:repeat var="node" value="#{menuitems.level1menus}">
            <p:commandLink immediate="true" styleClass="menu" 
                action="#{menuitems.onLevel1MenuChange(node.id)}"
                update=":pageTitle :menuLevel2 :menuLevel3" title="#{node.name}" 

                rendered="#{menuitems.selectedLevel1.id!=node.id}" onclick="menuSelect(this)">
                <span class="icon icon_#{node.name}"></span>
                <span class="text">#{node.name}</span>
</p:commandLink>

                <p:commandLink immediate="true" styleClass="menu activelink" 
                action="#{menuitems.onLevel1MenuChange(node.id)}"
                update=":pageTitle :menuLevel2 :menuLevel3" title="#{node.name}"

                rendered="#{menuitems.selectedLevel1.id==node.id}"  onclick="menuSelect(this)">
                <span class="icon icon_#{node.name}"></span>
                <span class="text">#{node.name}</span>
    </p:commandLink>

        </ui:repeat>
        </h:panelGroup>         
    </h:form>

The menuitems bean is at Session level. There are two diffeent p:commandlink inside ui:repeat. The only difference between the 2 is in the styleclass and rendered attribute. This is done to identify the default menu item when the user logs for the first time and give it an extra css of "activeLink". The java script called on onclick is given below (in case it is required)

    function menuSelect(selectOne){
        $(".left_menu>a").removeClass("activelink");
        $(selectOne).addClass("activelink");
        removeAllChannels();
    }
    function removeAllChannels(){
            $.atmosphere.unsubscribe();
      }

The removeAllChannels is to remove primepush autorefresh channels we have.

The issue i am facing is this. All the links are getting rendered correctly and in Firebug i see all of them have the same html. But the one which is generated with the extra css "activeLink" (through rendered condition -- menuitems.selectedLevel1.id==node.id) is not working. Nothing happens when i click this default link. All other links work fine. So when i click on a different link, it takes me to the required page. But when i click back on the menu which was default, nothing happens I added a Custom phase listener and saw that all the lifecyle stages are called when this link is clicked but the action method is not. I went through the links this and this but could not figure out the issue. Please help. Do tell me if something is not clear

هل كانت مفيدة؟

المحلول

As part of safeguard against tampered/hacked requests, the JSF component's rendered attribute is re-evaluated during processing the form submit. In case of a command link/button, if it evaluates false, then its action won't be queued/invoked. This matches the symptoms you're seeing.

This can in turn happen if the managed bean #{menuitems} is request scoped and/or when the properties behind #{menuitems.level1menus} or #{menuitems.selectedLevel1} are incompatibly changed during the postback request.

Putting the bean in the view scope and ensuring that the getters do not do any business job should fix this problem.

See also:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top