I am trying to move a p:dialog
out of a h:form
, because I have read that this is the preferred way (however I'd like to understand the reason, because my p:dialog
inside a form
works well in my application).
The only difficulty is that the dialog title needs to be updated dynamically. The dialog is shown when a button in a p:dataTable
is clicked.
Here is my old xhtml (before the changes), that's working fine:
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsForm" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<h:form id="viewPersonsForm">
<p:dialog modal="true" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
</h:form>
And here is the new xhtml, with eventBean#setSelectedEvent() that is not invoked.
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="jQuery('#viewPersonsDlgId .ui-dialog-title').text('#{eventBean.selectedEvent.name}');viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" >
...
</p:dialog>
So, again, why in the second scenario eventBean#setSelectedEvent() is not invoked? And, if possible, why the first scenario is not optimal?
It is not restricted to use p:dialog
inside a h:form
since it can work in some cases, but most of the time you will find yourself struggling with some unexpected behaviour with that, here are some explanations :
Why not to place p:dialog
inside h:form
1
Why not to place p:dialog
inside h:form
2
The problem in your case is that jQuery method in oncomplete
is called before the value is set with f:setPropertyActionListener
. To avoid this use the same solution as you used in your first case. So :
<p:dataTable var="event" value="#{eventBean.lazyModel}" selection="#{eventBean.selectedEvent}" />
...
<p:column headerText="#{msgs.Persons}">
<p:commandButton value="#{msgs.ViewPersons}" update=":viewPersonsDlgId" oncomplete="viewPersonsDlg.show()">
<f:setPropertyActionListener value="#{event}" target="#{eventBean.selectedEvent}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog modal="true" id="viewPersonsDlgId" widgetVar="viewPersonsDlg" dynamic="true" header="#{eventBean.selectedEvent.name}" >
...
</p:dialog>
No need to use jQuery here.
I had the same problem (pf 3.5):
<p:tabView id="cashFlowTabContainer" style="width:100%" activeIndex="0"
widgetVar="cashFlowTabContainerVar">
<p:tab title="#{labels['cashflow_incoming']}">
<p:outputPanel id="incomingPanel">
<p:dataTable value="#{cashFlowController.incomingCashFlows}"
var="cashFlow">
<p:column headerText="#{labels.cashflow_actions}">
<p:commandButton value="Edit"
action="# {cashFlowController.editIncoming}" update="@form" oncomplete="editInputVar.show();">
<f:setPropertyActionListener value="#{cashFlow}"
target="#{cashFlowController.selectedIncoming}" />
</p:commandButton>
</p:column>
and this was my dialog:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel>
<h:panelGrid columns="2" cellpadding="5">
...
<h:outputText value="#{labels.cashflow_description}:" />
<h:inputText
value="#{cashFlowController.selectedIncoming.description}" />
So... This way the setter was NEVER called. Then I noticed that if I emptied the dialog the setter was called.
So I solved it by putting a "rendered" statement on the panel:
<p:dialog id="editInput" header="Dynamic Dialog"
widgetVar="editInputVar" resizable="false" draggable="false"
modal="true">
<p:panel **rendered="#{cashFlowController.selectedIncoming != null}"**>
<h:panelGrid columns="2" cellpadding="5">
I guess there's a null pointer that is not logged anywhere... anyway this way it works :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With