99maas 99maas - 5 months ago 188
Ajax Question

Primefaces commandButton is not showing dialog after ajax form refresh

I need your help and guidance on fixing the issue of showing the

dialog
after refreshing the form by using ajax. I am having a
dataTable
that it is showing a number of requests and onclick of the
commandButton
view, a
dialog
will be shown that contains some information. And onclose of the
dialog
, the form will be refreshed and the dataTable will get the updated information from the database. However for the first time, the dialog will be shown and the form will be refreshed by closing the
dialog
.

If I tried to click again on the view
commandButton
on the second time, the
commandButton
will not show any dialog and will not seem to do an action. Even the log it is not showing anything.

Here is my xhtml:

<h:form id="Requests">
<p:dataTable id="PendingRequests" var="hr" value="#{hrd.pendingRequests}"
filteredValue="#{hrd.filteredPendingRequests}">
<p:column headerText="Req. Date" sortBy="#{hr.requestDate}"
filterMatchMode="contains" filterBy="#{hr.requestDate}">
<h:outputText value="#{hr.requestDate}" />
</p:column>
<p:column>
<f:facet name="header">View</f:facet>
<p:commandButton id="submitbutton" update=":Requests:#{hr.dialogueName} "
oncomplete="PF('#{hr.certificateDialogue}').show()" icon="ui-icon-search"
title="View">
<f:setPropertyActionListener value="#{hr}" target="#{hrd.selectedRequest}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog id="CertificateDialog" header="Cert1" widgetVar="CertificateDialog">
<p:ajax event="close" update=":Requests" listener="#{hrd.UpdateDatatable}" />
</p:dialog>
</h:form>


This method will be called onclose of the
dialog
.The UpdateDatatable method code is:

listPendingRequests.clear();
listPendingRequests = new ArrayList<PendingRequests>();
PreparedStatement ps = null;
String sql = "";

try {
con = DBConn.getInstance().getConnection("jdbc/hr");

// SQL Statement
ps = con.prepareStatement(sql);
ResultSet result = ps.executeQuery();
while (result.next()) {
PendingRequests pendingList = new PendingRequests();

requestDate = result.getString("REQ_DT");

pendingList.setRequestDate(requestDate);

listPendingRequests.add(pendingList);

RequestContext.getCurrentInstance().update("Requests");
}
} catch (Exception e) {
System.err.print(e);
e.printStackTrace();
}

Answer

Dialogs have a special treatment in HTML DOM and JavaScript. You should never be ajax-updating any of the dialog's parents while still in the same view. Otherwise you potentially end up with duplicate dialogs and conflicts in JS. Moreover, the strong recommendation is to give each dialog its own form as in <p:dialog><h:form> to avoid confusion and misuse by starters, but as you'd like to use ajax close event on it, you can't get around to use <h:form><p:dialog> instead. However, you placed other stuff in the very same form and you're even ajax-updating it. This is not right.

Tie the form to the dialog itself and don't put other stuff on it. In other words, split the current form.

<h:form id="requests">
    <p:dataTable ...>
        ...
    </p:dataTable>
</h:form>
<h:form>
    <p:dialog ...>
        <p:ajax event="close" ... update=":requests" />
    </p:dialog>
</h:form>