Getter for a property set thru f:setPropertyActionListener not being called in primefaces Dialog - jsf

I have a a button that is setting a property to a backing bean to be used in Primefaces Dialog.
p:commandButton value="Options" onclick="optionsDialog.show();">
`<f:setPropertyActionListener value="#{item}" target="#{bean.tempItem}" />
</p:commandButton>
I can see that setter is called here.
<p:dialog header="Options" widgetVar="OptionsDialog" dynamic="true" modal="true"
width="400" height="250">
<h:outputText value="#{bean.tempItem.value}"/>
</p:dialog>
Here the getter is never called.

That's because the dialog's content is not been updated before you show it. You need to update it by update attribute of the command button. Reference the (relative) client ID of the dialog in there. You also need to replace onclick by oncomplete because the onclick fires before the action is performed and oncomplete fires after the action is performed.
<p:commandButton ... update="dialogId" oncomplete="optionsDialog.show();">
...
<p:dialog id="dialogId" ...>
You've by the way also a lowercase/uppercase typo in the dialog widget name. But that would cause the dialog to not show up at all, which is a different problem.

Related

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?
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.

how can I call bean method on button click in jsf

I have a jsf component with action
<h:form>
<a4j:commandButton value="click" action="#{myBean.method()}" />
</h:form>
the problem is that bean's method "method" was called only once at first click,
how can I fix it that it will be called at every click on

Primefaces process attribute in reseting form inputs

I have a form inside a modal dialog and after closing (hiding in fact) one I wanted to reset all inputs that user might have changed. I though about something like as follow:
<p:dialog widgetVar="myDialog">
<h:form id="formId">
<!-- ... -->
<p:commandButton value="Cancel" onclick="myDialog.hide();"
update="formId">
<p:resetInput target="formId" />
</p:commandButton>
</h:form>
</p:dialog>
But the result was not that I expected. After a while of searching I found a solution that was to add process="#this" attribute to the <p:commandButton>. And my question is why it is necessary? What is really happening in backgroud that this process is desired. I don't really get the idea of process attribute at all.
I have done some work with dialog boxes and the way I did to make the form null is, when clicking the button to open dialog box, I ran a method in backing bean which cleared my pojo so my form had empty values.
In your case it could be something like this:
<h:form id="form-button">
<p:commandButton id="AddButton" value="open dialog box"
update=":form" action="#{myBean.myMethodToSetPojoNull}" immediate="true"
oncomplete="PF('myDialog').show()" />
</h:form>
When clicking this button, the called method will set to null all the fields and your dialog box will be empty. Getting back to your question of why process=#this is neccessary much better explained answer is here
What is the function of #this exactly?
You can also reset input after submitting through this method:
<p:commandButton value="Reset Non-Ajax"
actionListener="#{pprBean.reset}" immediate="true" ajax="false">
<p:resetInput target="panel" />
</p:commandButton>
If you don't add process="#this" then by default attribute value will be set to process="#form" which means all the elements in the form are processed. In command buttons process="#this" is mandatory to execute the corresponding actions associated with that button.
You can directly refer the answer from Balusc in this link
What is the function of #this exactly?

which event is fired after the action event?

I want to display the header of the modal popup with the value chatBean.selectedUser. The thing that happens is that onclick event is fired before action event so the page is not refreshed when the onclick event is fired. Hence I cannot get the header of modal pop up as the value contained in chatBean.selectedUser. Is there anyway that I can display the header of modal popup with the value chatbean.selectedUser after that the page is submitted?
Here is the relevant part of the view:
<h:form>
<p:selectOneMenu value="#{chatBean.selectedUser}" id="select">
<f:selectItems value="#{chatBean.friendList}" var="users" itemLabel="#{users.firstName}" itemValue="#{users.firstName}"/>
</p:selectOneMenu>
<p:commandButton id="basic" value="Basic" onclick="dlg.show()" type="button" action="#{chatBean.refresh}"></p:commandButton>
<p:dialog id="modalDialog" header="#{chatBean.selectedUser}" widgetVar="dlg" modal="true" height="100">
<h:outputText value="This is a Modal Dialog." />
<h:inputText></h:inputText>
</p:dialog>
</h:form>
You should show the dialog only when the action is completed, not before. Use the oncomplete attribute instead.
<p:commandButton ... oncomplete="dlg.show()" />
Don't forget to explicitly update the dialog's content before opening it. I don't see that anywhere in your code. Perhaps you're using RequestContext#update() or something, but normally you'd use update attribute for this.
<p:commandButton ... update="modelDialog" oncomplete="dlg.show()" />
Also, the type="button" is strange. This way the action wouldn't be invoked at all, but perhaps that's just a careless leftover of experimentation. Remove it.

Primefaces how to update content in a dialog and keep the dialog centered?

I have a dialog that contains no content on page load and I'm dynamically setting the content of a dialog box based on the link that a user clicks on.
<p:dialog widgetVar="dlg" modal="true" id="dialog">
<p:panel id="fullArticle">
<h:outputText value="#{content.newsArticle}" escape="false" />
</p:panel>
</p:dialog>
...
...
<p:commandLink value="Read more" actionListener="#{content.getFullArticle}" onclick='dlg.show();' update=":fullArticle">
<f:attribute name="contentId" value="#{news.contentId}" />
</p:commandLink>
The problem i'm having is that when you click the "Read More" link, it shows the dialog, but the dialog is not centered on the page. If i change the udpate attribute on the commandLink to update=":dialog", the dialog flashes as if it's opening and then closing right away.
How can I update the dialog and have it be centered with dynamic content?
The onclick is executed before the ajax request. You need to open the dialog in oncomplete instead. This will be executed after the ajax request and update. The <p:dialog> is namely by default hidden unless its visible attribute evaluates true.
<p:commandLink value="Read more" actionListener="#{content.getFullArticle}"
update=":dialog" oncomplete="dlg.show()">
Unrelated to the concrete problem, are you aware that you can pass fullworthy objects as method arguments since EL 2.2? This makes the <f:attribute> and actionListener "hack" superfluous:
<p:commandLink value="Read more" action="#{content.getFullArticle(news)}"
update=":dialog" oncomplete="dlg.show()" />
I had the same problem.
Updating the dialog makes it disappear and reappear (and forget its position).
To solve it, I created a wrapper tag around the dialog content.
<p:commandLink update=":playerViewDialogHeader,:playerViewDialogContent"
oncomplete='playerViewDialogJS.show()' value='#{item.name}' />
<p:dialog id='playerViewDialog' widgetVar='playerViewDialogJS'>
<f:facet name="header">
<h:outputText id="playerViewDialogHeader" value="#{playerController.objectView.name}" />
</f:facet>
<h:form id='playerViewDialogContent'>
<!-- CONTENT GOES HERE -->
</h:form>
</p:dialog>

Resources