p:commandbutton action doesn't work inside p:dialog

commandbutton, dialog, jsf, primefaces

Solution

The dialog, when used with an `appendToBody/appendTo="@Body"` must have its own form.

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

Because, when the dialog is generated into HTML output, it's by JavaScript relocated to the end of HTML `<body>` which causes it to not be sitting in any form anymore. The generated HTML DOM tree ends up to look like this (use webbrowser's dev tools to see it):

<body>
    ...
    <form id="createAppUserForm">
        ...
    </form>
    ...
    <div id="newRoleDialogId" class="ui-dialog ...">
        ...
    </div>
</body>

The `appendToBody="true"` plays a role in here. The end of body ensures easy and best cross browser compatibility of displaying a modal dialog by JavaScript.

The same is true by the way for a `p:overlayPanel` with an `appendTo...`

But also make sure there is, before 'moving' the `p:dialog`, there is not a nested `h:form`. So prevent

<h:form>
   ...

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

   ...
</h:form>

Since although it ends up like

 <body>
    ...
    <form id="createAppUserForm">
        ...
    </form>
    ...
    <div id="newRoleDialogId" class="ui-dialog ...">
        <form>
           ...
        </form>
    </div>
</body>

it is initially invalid html

See also:

- How to show details of current row from p:dataTable in a p:dialog and update after save

- Creating master-detail table and dialog, how to reuse same dialog for create and edit

- How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?

Problem

I have a p:dialog and there is a panel inside it. The problem is "Save" button's action method is not working. It doesn't even calls the method. I can reach the method def. with ctrl+lm so there is no problem with method name. ``` <h:body> <h:form id="createAppUserForm" prependId="false"> .... <p:dialog id="newRoleDialogId" header="Add New Role" resizable="true" draggable="true" widgetVar="newRoleDetailsDialog" appendToBody="true" > <p:panel id="newRoleDialogPanel"> <p:panelGrid id="newRoleDialogPanelGrid" columns="2" style="width: 100%" styleClass="panelGridWithoutBorder"> <h:outputText value="Role Name :"/> <p:inputText value="#{createAppUserController.selectedRole.name}"/> <h:outputText value="Role Desc :"/> <p:inputText value="#{createAppUserController.selectedRole.description}"/> </p:panelGrid> <center> <p:commandButton value="Save" update="roleListDataTable newRoleDialogPanelGrid growlCreateAppUser" oncomplete="if (!args.validationFailed) newRoleDetailsDialog.hide()" action="#{createAppUserController.saveNewRole()}"/> <p:commandButton value="Cancel" immediate="true" onclick="newRoleDetailsDialog.hide()" /> </center> </p:panel> </p:dialog> </h:form> </h:body> ```

Original source

Related problems