amphibient
amphibient

Reputation: 31212

View scoped managed bean's @PostConstruct reinvoked after closing p:dialog

I have a popup defined within my XHTML which gets shown conditionally depending on what selections the user makes in the main screen rendered by default:

<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto">
    <h:form id="commentForm">

        <h:outputLabel for="comment" value="Comment:"/>

        <p:inputTextarea id="comment" title="Comment" 
                rows="6" cols="33"
                value="#{managedBean.activeItem.comment}"
                required="true">
            <f:ajax render="comment"/>
        </p:inputTextarea>

        <h:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();">
            <f:ajax render="commentSubmit"/>
        </h:commandButton>

    </h:form>
</p:dialog>

The problem is that, once this dialog/popup is closed, the container (JBoss) or the framework (JSF/Primefaces), not sure which, thinks that the whole view has been closed and therefore on the next request that triggers an appearance of this popup, it re-invokes the backing bean's @PostConstruct method. The backing bean is @ViewScoped. I really don't want it to do that, instead, I want it to treat the dialog/popup as a div in the page whose closure does not affect the view state.

The first time the dialog is brought up, the @PostConstruct is not invoked as the initial view from rendering the page, which called the @PostConstruct, is still active. However, on the second appearance, it is reinvoked, which leads me to believe it is because it was closed after the first time, which either the container of the framework or both mistake as needing to reload the bean.

What can I do to prevent the backing bean from going into the @PostConstruct after this dialog has been closed?

Upvotes: 0

Views: 845

Answers (1)

Kishor Prakash
Kishor Prakash

Reputation: 8151

I know what the problem is..
You are using h:commandButton to submit the form and to close the dialog.
Lets look at your code:

<h:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();">
    <f:ajax render="commentSubmit"/>
</h:commandButton>

In the above code As soon as you clikc Submit button:
1. Your action will get triggred to call ManagedBean method managedBean.proceed.
2. since you have bound onclick JS event, your dialog gets closed.

After your action="#{managedBean.proceed} comes back it has to update the button with id commentSubmit since you have used render="commentSubmit".
But by the time your action="#{managedBean.proceed} comes back to render="commentSubmit" the disloag in which your button commentSubmit is placed is closed. so this might the reason for re initializing the ManagedBean.

To Avoid this you ca use Primefaces p:commandButton which has oncomplete attribute which is helpfull in this scenario.

<p:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" update="commentSubmit" oncomplete="PF('commentDialog').hide();" />

So in the above case p:dialog will close after the action is completed.

Upvotes: 1

Related Questions