facewindu
facewindu

Reputation: 715

render richfaces popupPanel after bean method is finished

I have a simple problem where I want to display a popup if something went wrong in my managed bean. The bean holds a list of exceptions that can be raised, with getter/setter methods.

The xhtml looks like this

      <rich:panel>
    <h:form>
        <a4j:commandButton value="Compute Mission"
            action="#{missionHandler.generateMissionFeasability}"
            render="popupPanel">
        </a4j:commandButton>
    </h:form>
   </rich:panel>
   <rich:popupPanel id="popupPanel" modal="true" autosized="true"
    resizeable="false" moveable="false" rendered="#{not empty    missionHandler.exceptions}">
    <f:facet name="header">
        <h:outputText value="Exceptions raised during the processing    " />
    </f:facet>
    <f:facet name="controls">
        <h:outputLink value="#"
            onclick="#{rich:component('popupPanel')}.hide();return false;">
        </h:outputLink>
    </f:facet>
    </rich:popupPanel>

As you see I have a command button that should call generateMissionFeasibility method in the bean. The method will (among other things) add exception in the exceptions list.

I would like to check the list (if it's empty or not) to display the popup

The code above doesn't work because I think the popup is rendered before the end of the method in the bean, and the list is empty at the beginning.

Upvotes: 1

Views: 7794

Answers (2)

kolossus
kolossus

Reputation: 20691

The code doesn't work because the first time the view is about to be rendered, missionHandler.exceptions will be empty, which means popupPanel never makes it to the browser. Subsequent requests to reRender popupPanel will fail as the component is nowhere to be found in the DOM.

For a component to be ajax-updated, it must already be in the DOM in the browser, this is the way ajax works. So the solution is to wrap the content of the popup panel in a component that will always be rendered.

That aside, even if you got the rendering correct, your popup will only be placed in the DOM. You actually need to call show() on the popup to get it to showup

To achieve what you want however, a better alternative will be to

  1. Conditionally display the popup using javascript. If the condition is met, the show() function is called for the popup. Otherwise, an empty, do-nothing javascript function will be called.

    <a4j:commandButton value="Compute Mission" action="#missionHandler.generateMissionFeasability}"
        oncomplete="#{not empty missionHandler.exceptions ? #{rich:component('popupPanel')}.show()" : doNothing()}" render="popupPanel">
    </a4j:commandButton>
    

    For the doNothing js:

    <script> function doNothing(){} <script/>
    
  2. Take the rendering condition out of the modal panel

EDIT: Additionally, the show attribute on the popup component can be based on the same EL condition as the oncomplete attribute

Upvotes: 1

Andrey
Andrey

Reputation: 6766

One way to make popup panel be shown once rendered is to change

rendered="#{not empty missionHandler.exceptions}"

to

show="#{not empty missionHandler.exceptions}"

Upvotes: 3

Related Questions