PrimeFaces对话框仅在第一次出现时进行验证

时间:2014-01-25 09:38:45

标签: ajax validation jsf primefaces jsf-2.2

JSF 2.2,PrimeFaces 3.5。

home.xhtml包含一个带有嵌套dataTables和添加/编辑/删除按钮的tabview。每个按钮都应该调用带有表单和提交/取消按钮的对话框。

问题是验证只处理一次(见截图),如果按“添加”/“取消”,对话框只会隐藏,不会进行验证。如果我再次尝试重新打开它并输入值并点击“添加” - 它只是跳过验证并呈现响应。所以,基本上,它只是提出初始请求(如果我猜对了)。

enter image description here

控制台输出,用于按“添加”,空值为3次。第一次点击已经按照我想要的方式处理,但接下来只是隐藏对话而没有任何验证:

2014-01-24 17:56:09,590 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1 
2014-01-24 17:56:09,628 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: APPLY_REQUEST_VALUES 2 
2014-01-24 17:56:09,633 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: PROCESS_VALIDATIONS 3 
2014-01-24 17:56:09,645 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6 
2014-01-24 17:56:13,127 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1 
2014-01-24 17:56:13,128 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6 
2014-01-24 17:56:16,557 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1 
2014-01-24 17:56:16,558 DEBUG  [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6 

home.xhtml(对话框位于页面底部):

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:h="http://xmlns.jcp.org/jsf/html"
              xmlns:p="http://primefaces.org/ui"
              xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:ex="http://java.sun.com/jsf/composite/nsobchuk">
    <h:head>
        <title>Home page</title>
        <link rel="stylesheet" href="../css/style.css"/>
    </h:head>

    <h:body>

        <h:form id="logout" class="logout" >
            <h:commandButton action="#{loginBean.logout()}" value="logout"/>
        </h:form>

        <p:tabView id="tab" orientation="left">

            <p:tab title="Users">

                <h:form id="form1">

                    <h:panelGrid columns="9">

                        <p:commandButton type="button" value="Add" onclick="dlg1.show()" />


                        <p:commandButton id="editUser" type="button" value="Edit" onclick="dlg2.show()" disabled="#{homeBean.selectedUser == null}"/>
                        <p:dialog id="editUserDialogerDialog" widgetVar="dlg2" header="Sorry" >
                            <h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
                        </p:dialog>


                        <p:commandButton id="deleteUser" type="button" onclick="confirmation1.show()" value="Delete" disabled="#{homeBean.selectedUser == null}"/>
                        <p:confirmDialog message="Are you sure you want to delete user?" header="Confirmation"
                                         severity="alert" widgetVar="confirmation1">
                            <p:commandButton value="Yes" update=":tab:users" process="@this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
                                             oncomplete="confirmation1.hide()" action="#{homeBean.deleteUser}" />
                            <p:commandButton value="No" onclick="confirmation1.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
                        </p:confirmDialog>

                    </h:panelGrid>

                </h:form>


                <p:dataTable id="users" var="user" value="#{homeBean.users}" 
                             scrollable="true" scrollHeight="250" selectionMode="single"
                             selection="#{homeBean.selectedUser}" rowKey="#{user.userId}"
                             sortMode="single">

                    <p:ajax event="rowSelect" listener="#{homeBean.onUserRowSelect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/> 
                    <p:ajax event="rowUnselect" listener="#{homeBean.onUserRowUnselect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/>

                    <p:column headerText="Login" sortBy="#{user.login}">  
                        <h:outputText value="#{user.login}"/>
                    </p:column>

                    <p:column headerText="Password" sortBy="#{user.password}">  
                        <h:outputText value="#{user.password}"/>
                    </p:column>

                    <p:column headerText="Role" sortBy="#{user.role}">  
                        <h:outputText value="#{user.role}"/>
                    </p:column>

                    <p:column headerText="Name" sortBy="#{user.firstName}">  
                        <h:outputText value="#{user.firstName}"/>
                    </p:column>

                    <p:column headerText="Surname" sortBy="#{user.lastName}">  
                        <h:outputText value="#{user.lastName}"/>
                    </p:column>

                </p:dataTable>

                <ex:exporter target=":tab:users" fileName="Users"/>

            </p:tab>

            <p:tab title="Computers">

                <h:form id="form2">

                    <h:panelGrid columns="9">

                        <p:commandButton type="button" value="Add" onclick="dlg3.show()"/>


                        <p:commandButton id="editComp" type="button" value="Edit" onclick="dlg4.show()" disabled="#{homeBean.selectedComputer == null}"/>
                        <p:dialog id="editCompDialog" widgetVar="dlg4" header="Sorry" >
                            <h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
                        </p:dialog>


                        <p:commandButton id="deleteComp" type="button" onclick="confirmation2.show()" value="Delete" disabled="#{homeBean.selectedComputer == null}"/>
                        <p:confirmDialog message="Are you sure you want to delete this computer?" header="Confirmation"
                                         severity="alert" widgetVar="confirmation2">
                            <p:commandButton value="Yes" update=":tab:computers" process="@this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
                                             oncomplete="confirmation2.hide()" action="#{homeBean.deleteComputer}"/>
                            <p:commandButton value="No" onclick="confirmation2.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
                        </p:confirmDialog>

                    </h:panelGrid>

                </h:form>


                <p:dataTable id="computers" var="computer" value="#{homeBean.computers}" 
                             scrollable="true" scrollHeight="250" selectionMode="single"
                             selection="#{homeBean.selectedComputer}" rowKey="#{computer.computerId}"
                             sortMode="single" >
                    <p:ajax event="rowSelect" listener="#{homeBean.onCompRowSelect}" update=":tab:form2:editComp, :tab:form2:deleteComp"/> 

                    <p:column headerText="Login" sortBy="#{computer.login}">  
                        <h:outputText value="#{computer.login}"/>  
                    </p:column>

                    <p:column headerText="Password" sortBy="#{computer.password}">  
                        <h:outputText value="#{computer.password}"/>  
                    </p:column>

                    <p:column headerText="Name" sortBy="#{computer.computerName}" > 
                        <h:outputText value="#{computer.computerName}"/>  
                    </p:column>

                    <p:column headerText="IP address" sortBy="#{computer.ipAddress}">  
                        <h:outputText value="#{computer.ipAddress}"/>  
                    </p:column>

                </p:dataTable>

                <ex:exporter target=":tab:computers" fileName="Computers"/>

            </p:tab>

            <p:tab title="Applications">


                <h:form id="form3">

                    <h:panelGrid columns="9">

                        <p:commandButton type="button" value="Add" onclick="dlg5.show()"/>




                        <p:commandButton id="editApp" type="button" value="Edit" onclick="dlg6.show()" disabled="#{homeBean.selectedApplication == null}"/>
                        <p:dialog id="editAppDialog" widgetVar="dlg6" header="Sorry" >
                            <h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
                        </p:dialog>


                        <p:commandButton id="deleteApp" type="button" onclick="confirmation3.show()" value="Delete" disabled="#{homeBean.selectedApplication == null}"/>
                        <p:confirmDialog message="Are you sure you want to delete this application?" header="Confirmation"
                                         severity="alert" widgetVar="confirmation3">
                            <p:commandButton value="Yes" update=":tab:applications" process="@this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
                                             oncomplete="confirmation3.hide()" action="#{homeBean.deleteApplication}"/>
                            <p:commandButton value="No" onclick="confirmation3.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
                        </p:confirmDialog>

                    </h:panelGrid>

                </h:form>

                <p:dataTable id="applications" var="app" value="#{homeBean.applications}" 
                             scrollable="true" scrollHeight="250" selectionMode="single"
                             selection="#{homeBean.selectedApplication}" rowKey="#{app.appId}"
                             sortMode="single" >

                    <p:ajax event="rowSelect" listener="#{homeBean.onAppRowSelect}" update=":tab:form3:editApp, :tab:form3:deleteApp"/>

                    <p:column headerText="Name" sortBy="#{app.appName}">  
                        <h:outputText value="#{app.appName}"/>  
                    </p:column>

                    <p:column headerText="Vendor" sortBy="#{app.vendorName}" >  
                        <h:outputText value="#{app.vendorName}"/>  
                    </p:column>

                    <p:column headerText="License required" sortBy="#{app.licenseRequired}">  
                        <h:outputText value="#{app.licenseRequired}"/>  
                    </p:column>

                </p:dataTable>

                <ex:exporter target=":tab:applications" fileName="Applications" />

            </p:tab>

        </p:tabView>


        <p:dialog id="addUserDialog" header="Add Dialog" modal="true" closable="false"
                  widgetVar="dlg1" width="620" >
            <h:form id="dlg1form">
                <h:panelGrid columns="3">

                    <h:outputLabel for="login" value="Login: "/>
                    <p:inputText id="login" required="true"  
                                 label="Login: " maxlength="20" >

                    </p:inputText>
                    <p:message for="login" />

                    <h:outputLabel for="password" value="Password: "/>
                    <p:password id="password" required="true" 
                                feedback="true"  label="Password: " maxlength="32"/>
                    <p:message for="password" />

                    <h:outputLabel for="firstName" value="First Name: "/>
                    <p:inputText id="firstName" 
                                 label="First Name: " maxlength="20"/>
                    <p:message for="firstName"/>

                    <h:outputLabel for="lastName" value="Last Name: "/>
                    <p:inputText id="lastName"
                                 label="Last Name: " maxlength="20"/>
                    <p:message for="lastName"/>

                    <h:outputLabel for="role" value="Role: "/>
                    <p:selectOneMenu id="role" required="true" style="width: 80px;" >
                        <f:selectItem itemLabel="user" itemValue="ROLE_USER" />
                        <f:selectItem itemLabel="admin" itemValue="ROLE_ADMIN" />
                    </p:selectOneMenu>
                    <p:message for="role"/>

                </h:panelGrid>

                <p:commandButton value="Cancel" onclick="dlg1.hide()" update="@form">
                    <p:resetInput target="addUserDialog"  />
                </p:commandButton>

                <p:commandButton value="Add" update="@form" immediate="false"
                                 oncomplete="if (args &amp;&amp; !args.validationFailed) dlg1.hide()" />
            </h:form>
        </p:dialog>



        <p:dialog id="addCompDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
                  widgetVar="dlg3" width="600">

            <h:form id="dlg3form">
                <h:panelGrid columns="3">

                    <h:outputLabel for="pclogin" value="Login: "/>
                    <p:inputText id="pclogin" required="true"  
                                 label="Login: " maxlength="20">
                    </p:inputText>
                    <p:message for="pclogin"/>

                    <h:outputLabel for="pcpassword" value="Password: "/>
                    <p:password id="pcpassword" required="true" 
                                feedback="true"  label="Password: " maxlength="32"/>
                    <p:message for="pcpassword" />

                    <h:outputLabel for="compName" value="Computer Name: "/>
                    <p:inputText id="compName" required="true"
                                 label="Computer Name: " maxlength="20"/>
                    <p:message for="compName"/>

                    <h:outputLabel for="ipaddress" value="IP address: "/>
                    <p:inputText id="ipaddress" required="true"
                                 label="IP address: " maxlength="20"/>
                    <p:message for="ipaddress"/>

                </h:panelGrid>

                <p:commandButton value="Cancel" immediate="true" onclick="dlg3.hide()" process="@this" update="@form">
                    <p:resetInput target="addCompDialog" />
                </p:commandButton>

                <p:commandButton value="Add" update="@form" 
                                 oncomplete="if (args &amp;&amp; !args.validationFailed) dlg3.hide()" />
            </h:form>

        </p:dialog>




        <p:dialog id="addAppDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
                  widgetVar="dlg5" width="600" >

            <h:form id="dlg5form">
                <h:panelGrid columns="3">
                    <h:outputLabel for="appName" value="Name: "/>
                    <p:inputText id="appName" required="true"  
                                 label="Name: "/>
                    <p:message for="appName"/>

                    <h:outputLabel for="vendorName" value="Vendor: "/>
                    <p:inputText id="vendorName" 
                                 label="Vendor: " required="true" />
                    <p:message for="vendorName"/>

                    <h:outputLabel for="appLicense" value="Requires license: "/>
                    <p:selectOneMenu id="appLicense" required="true" style="width: 80px;" >
                        <f:selectItem itemLabel="True" itemValue="#{true}" />
                        <f:selectItem itemLabel="False" itemValue="#{false}" />
                    </p:selectOneMenu>
                    <p:message for="appLicense"/>
                </h:panelGrid>

                <p:commandButton value="Cancel" immediate="true" onclick="dlg5.hide()" update="@form" process="@this">
                    <p:resetInput target="addAppDialog" />
                </p:commandButton>

                <p:commandButton value="Add" update="@form" 
                                 oncomplete="if (args &amp;&amp; !args.validationFailed) dlg5.hide()"/>
            </h:form>

        </p:dialog> 


    </h:body>

</ui:component>

HomeBean:

@Component
@Scope("session")
public class HomeBean extends BaseBean {

    private static final String editUserBtn = "tab:form1:editUser";
    private static final String deleteUserBtn = "tab:form1:deleteUser";
    private static final String editCompBtn = "tab:form2:editComp";
    private static final String deleteCompBtn = "tab:form2:deleteComp";
    private static final String editAppBtn = "tab:form3:editApp";
    private static final String deleteAppBtn = "tab:form3:deleteApp";
    @Autowired
    private HibernateDBManager hibernateDBManager;
    private List<User> users;
    private List<Computer> computers;
    private List<Application> applications;
    private User selectedUser, newUser;
    private Computer selectedComputer, newComputer;
    private Application selectedApplication, newApplication;
    private RequestContext rc;

    @Override
    public void init() {
        setUsers(hibernateDBManager.getAllUsers());
        setComputers(hibernateDBManager.getAllComputers());
        setApplications(hibernateDBManager.getAllApplications());
        newUser = new User();
        newComputer = new Computer();
        newApplication = new Application();
        rc = RequestContext.getCurrentInstance();
    }

    public void addUser() throws NoSuchAlgorithmException {
        if (newUser != null && newUser.getPassword() != null) {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(newUser.getPassword().getBytes());
            String hash = new BigInteger(1, md.digest()).toString(16);
            newUser.setPassword(hash);
            if (hibernateDBManager.insertUser(newUser)) {
                users.add(newUser);
            }
        }
    }

    public void editUser() {
        if (selectedUser != null) {
            hibernateDBManager.updateUser(selectedUser);
            users.set(users.indexOf(selectedUser), selectedUser);
            selectedUser = null;
            rc.update(deleteUserBtn);
            rc.update(editUserBtn);
        }
    }

    public void deleteUser() throws IOException {
        if (selectedUser != null) {
            if (hibernateDBManager.deleteUserById(selectedUser.getUserId()) > 0) {
                users.remove(selectedUser);
                selectedUser = null;
                rc.update(deleteUserBtn);
                rc.update(editUserBtn);
            }
        }
    }

    public void addComputer() {
        if (newComputer != null && hibernateDBManager.insertComputer(newComputer)) {
            computers.add(newComputer);
        }
    }

    public void deleteComputer() {
        if (selectedComputer != null) {
            if (hibernateDBManager.deleteComputerById(selectedComputer.getComputerId()) > 0) {
                computers.remove(selectedComputer);
                selectedComputer = null;
                rc.update(editCompBtn);
                rc.update(deleteCompBtn);
            }
        }
    }

    public void addApplication() {
        if (newApplication != null && hibernateDBManager.insertApplication(newApplication)) {
            applications.add(newApplication);
        }
    }

    public void deleteApplication() {
        if (selectedApplication != null) {
            if (hibernateDBManager.deleteApplicationById(selectedApplication.getAppId()) > 0) {
                applications.remove(selectedApplication);
                selectedApplication = null;
                rc.update(editAppBtn);
                rc.update(deleteAppBtn);
            }
        }
    }

    public void onUserRowSelect(SelectEvent event) {
        setSelectedUser((User) event.getObject());
    }

    public void onUserRowUnselect(UnselectEvent event) {
        setSelectedUser(null);
    }

    public void onCompRowSelect(SelectEvent event) {
        setSelectedComputer((Computer) event.getObject());
    }

    public void onAppRowSelect(SelectEvent event) {
        setSelectedApplication((Application) event.getObject());
    }

    //Getters etc.
    }

每次用户按“添加”时,我都要保持对话框的打开和验证,而不仅仅是一次。任何人都可以帮助我用我的代码实现这一点或指向我的解决方案吗? (类似的回答问题,评级-1对我没有帮助)每个答案都非常感谢。

谢谢大家。

2 个答案:

答案 0 :(得分:3)

好的,伙计们。我自己找到了解决方案。我做的工作是在一个表单中给一个panelGrid元素一个id更新panelGrid而不是整个表单。

因此,“添加”按钮已更改为:

<p:commandButton value="Add" 
    update=":dlg1form:dt, :tab:users"
    action="#{homeBean.addUser}"  
    oncomplete="if (!args.validationFailed) dlg1.hide()" />

和panelGrid,其中包含输入字段:

<h:form id="dlg1form">
    <h:panelGrid columns="3" id="dt">

这有助于我在每次点击时验证输入字段,而不仅仅是一次。

真诚地希望这会对某人有所帮助。

干杯!

答案 1 :(得分:1)

我遇到了同样的问题:在update="@form"内部update="yourFormName"<p:commandButton>阻止了在发生验证错误时保留对话框。

这可能是因为包含update form命令会重新生成整个对话框,但不会触发dialogWidgetVar.show() js命令。

我通过在对话框中嵌套<p:fragment autoUpdate="true">来解决了这个问题。然后,您可以删除触发commandButton中的update关键字,因为片段中的每个组件都将更新。结果是,当客户端收到Ajax响应时,不会替换<p:dialog></p:dialog>标记。我的工作代码如下:

<h:form id="locations_editer_creer">
    <p:dialog id="location_dlg" widgetVar="locationDlg" header="#{msgs.LocationCreerNouvelle}" width="600" dynamic="false" closeOnEscape="true"
                      minimizable="true" maximizable="true" modal="true" >

        <p:fragment autoUpdate="true">

            your form inputs e.g. <p:inputText .../>

            <p:commandButton id="OK" value="OK"
              actionListener="#{locationsControleur.confirmer()}"
              oncomplete="traiteRequeteCreationLoc(xhr, status, args)"
              styleClass="ui-confirmdialog-yes" icon="ui-icon-check"/>

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

这项技术在K. Siva Prasad Reddy(Packt Publishing)的优秀PrimeFaces Beginner's Guide书中有所描述,p。 54:使用Fragment组件进行部分处理和渲染。

希望这可以帮助他人。