2014-01-25 111 views
2

JSF 2.2,PrimeFaces 3.5。PrimeFaces對話框僅在第一次出現時進行驗證

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類似的回答問題沒有幫助我)每個答案都非常感謝。

謝謝大家。

回答

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"> 

幫我驗證的每次點擊輸入字段,並且不只是一次。

衷心希望這會幫助別人。

乾杯!

+0

如果您正確回答自己的問題,仍然可以接受您接受的答案。它不會給你任何聲望,但它會將答案標記爲解決方案。如果他們陷入同樣的​​問題,它將幫助其他人更快地找到答案。 – Manuel

+0

Thx解釋。標記爲正確的答案。 – amenoire

1

我有同樣的問題:在我的<p:commandButton>中有一個update="@form"update="yourFormName"阻止了驗證錯誤發生時保持對話框。

這可能是由於包含更新表單命令重新生成整個對話框但不觸發dialogWidgetVar.show() js命令的事實。

我通過在對話框中嵌套<p:fragment autoUpdate="true">解決了這個問題。然後,您可以刪除觸發命令按鈕中的update關鍵字,因爲片段內的每個組件都將被更新。結果是,當客戶端收到Ajax響應時,<p:dialog></p:dialog>標記未被替換。我的工作的代碼如下:優異的PrimeFaces Beginner's Guide書K.希瓦普拉薩德雷迪(年底Packt出版)中,p內被描述

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

這種技術。 54:使用片段組件進行部分處理和渲染。

希望這可以幫助他人。

+0

不錯,我喜歡這個解決方案。 – amenoire

相關問題