jsfrichfaceselajax4jsf

JSF / EL evaluates onClick during rendering of page. Why?


Recently I ran into a problem with one of my . I have a separate xhtml containing conditionally rendered icons/links to show different kinds of popups. This xhtml is basically a container for specific kinds of popups that I can include on different pages. The rendered conditions (and a passed ui:parameter) make sure only the relevant icons/links get shown depending on where this xhtml is included. This prevents me of having to write lots of different ui:includes on each page.

For some popups it's necessary to prepare some data, which is done via the onclick attribute of an a4j:commandLink. Then, the oncomplete will show the actual popup like so:

<a4j:commandLink render="clientGroupMemberInfoPopup" rendered="#{assignmentDO.clientGroupMember}"
                 onclick="#{clientInfoBean.registerGmClientGroupMember(assignmentDO.gmClientGroupMemberDO)}"
                 oncomplete="RichFaces.ui.PopupPanel.showPopupPanel('ClientInfo')">
    <h:graphicImage value="/img/icons/icon_info_sm.png" rendered="#{!printFriendly}"/>
</a4j:commandLink>

The corresponding bean:

@ManagedBean
@ViewScoped
public class ClientInfoBean {

    @EJB
    private ClientService clientService;

    @Getter
    @Setter
    private ClientContextDO clientContextDO;

    @Getter
    @Setter
    private GmClientGroupMemberDO gmClientGroupMemberDO;

    @Getter
    @Setter
    private Long clientId;

    public void registerGmClientGroupMember(final GmClientGroupMemberDO aGroupMember) {
        gmClientGroupMemberDO = aGroupMember;
        clientContextDO = clientService.findByClientId(gmClientGroupMemberDO.getClientId());
    }

}

In this case above the rendered condition of the a4j:commandLink evaluates to true. However... the onclick is evaluated every single time, on every page this xhtml is included, once the rendered condition evaluates to true. Even when the page is still loading and nobody has clicked on anything yet!

Why? And what's the best way to prevent this? There's some relatively heavy db-stuff being done to prepare all the info necessary for the popup. I only want this stuff done the moment someone actually clicks on the link for the popup, not during page rendering phases.


Solution

  • There IS a duplicate of this question, I'm sure but I cannot find it. I'll remove this answer when BalusC flags it as such.

    The onclick is for executing javascript, not accessing a server-side method. So the EL in it is evaluated as a value expression, not a method expression. So the output is considered as javascript. Consequently it is just evaluated at render time and re-evaluated when clicked.

    The solution is to change the onclick to action

    <a4j:commandLink render="clientGroupMemberInfoPopup" rendered="#{assignmentDO.clientGroupMember}"
                     action="#{clientInfoBean.registerGmClientGroupMember(assignmentDO.gmClientGroupMemberDO)}"
                     oncomplete="RichFaces.ui.PopupPanel.showPopupPanel('ClientInfo')">
        <h:graphicImage value="/img/icons/icon_info_sm.png" rendered="#{!printFriendly}"/>
    </a4j:commandLink>