【问题标题】:Block UI after successful of fields verification字段验证成功后阻止 UI
【发布时间】:2016-03-19 12:16:23
【问题描述】:

我使用 JSF 2.2 和 Primefaces 5.3。我必须创建一个像这样工作的表单:

按下按钮后:

  • 如果填写了所有必填字段,则只要发送数据,页面就会被阻止(由于向数据库发送数据)。
  • 如果未填写必填字段之一,则不会阻止页面。

你能告诉我该怎么做吗?

这是一个 xhtml 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pm="http://primefaces.org/mobile"
      xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
    <h:head></h:head>
    <h:body id="page">

        <f:metadata>
            <f:viewAction action="#{loginController.start()}" />
        </f:metadata>  

        <p:growl id="messages" showDetail="true" />

        <h:form>
            <p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign">                      
                <p:outputLabel for="databaseName" value="Database name:" />
                <p:inputText id="databaseName" required="true" value="#{userDatabase.name}" />
                <p:outputLabel for="databaseFile" value="File:" />
                <p:fileUpload id="databaseFile" required="true" fileLimit="1" update="file messages" fileUploadListener="#{dataController.handleFileUpload}" mode="advanced" dragDropSupport="true" sizeLimit="1000000000" uploadLabel="Upload" cancelLabel="Delete" allowTypes="/(\.|\/)(txt|binetflow)$/" />              
                <h:panelGroup />
                <h:outputText id="fileDescription" value="#{dataController.fileName}" />                        
                <p:commandButton id="buttonSend" value="Send" update="messages" action="#{dataController.send()}" />                        
            </p:panelGrid>

            <p:blockUI block="page" trigger="buttonSend">
                Sending of the data...              
            </p:blockUI>            

        </h:form>

    </h:body>   
</html>

这是一个 CDI bean:

package com.system.controller;

import java.io.Serializable;
import java.util.logging.Logger;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

import com.system.model.UserDatabase;
import com.system.service.DataService;

@Named
@ViewScoped
public class DataController implements Serializable {

    private static final long serialVersionUID = 1383572529241805730L;

    public void handleFileUpload(FileUploadEvent event){
        uploadFile=event.getFile(); 

        FacesMessage message = new FacesMessage("Successful", event.getFile().getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, message);        
    }

    public String getFileName(){

        if(uploadFile==null) return "";
        else return uploadFile.getFileName();               
    }

    public void send(){

        if(uploadFile==null){

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "The file isn't uploaded", "You should upload a file"));
        }
        else{

            //Sending the data to the database... (tha page should be blocked)

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //After successful of sending the data, the page should be unlocked.

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The data has been added.", ""));           
        }
    }

    @Named
    @Produces
    @RequestScoped
    private UserDatabase userDatabase=new UserDatabase();  

    @Inject
    private DataService dataService;

    @Inject
    private Logger log;

    private UploadedFile uploadFile;
}

上面的代码当然可以,但是每次我按下按钮时页面都会被阻止(即使没有填写字段)。我想我应该在p:blockUI 组件中使用widgetVar 而不是trigger,但我不知道怎么做,也许我错了。对我来说最好的方法是如果我可以从 CDI bean 中的 send 方法阻止/解锁页面,但我不知道这是否可能,除此之外 - 这不是必需的。每一种方式都会对我有所帮助。

【问题讨论】:

    标签: forms jsf primefaces blockui


    【解决方案1】:

    我终于找到了解决方案。这些是我执行的步骤:

    1. 我在 blockUI 组件中使用了widgetVar 属性而不是trigger

      <p:blockUI block="page" widgetVar="widgetBlock">
          Sending of the data...          
      </p:blockUI>
      
    2. 我在DataController bean 中创建了自己的验证方法:

      public boolean isValidation(){
      
          if(uploadFile==null || userTable.getName()==null || userTable.getName().trim().equals("")) return false;
          else return true;
      }
      
    3. 我为 commandButton 添加了onstart(我调用我的验证方法,如果我得到true,我会阻止页面)和oncomplete(我解锁页面)属性:

      <p:commandButton id="buttonSend" value="Send" action="#{dataController.send()}" update="messages" 
                       onstart="if(#{dataController.validation}){PF('widgetBlock').show()}" 
                       oncomplete="PF('widgetBlock').hide()" />
      
    4. 我将commandButton id 放到fileupload 组件中的update 属性中。除此之外,我从文件上传中删除了require 属性:

      <p:fileUpload id="file" 
                    fileLimit="1"
                    update="buttonSend fileDescription messages" 
                    fileUploadListener="#{dataController.handleFileUpload}" 
                    mode="advanced" dragDropSupport="true" sizeLimit="1000000000" 
                    uploadLabel="Upload" cancelLabel="Delete" allowTypes="/(\.|\/)(txt|binetflow)$/" />               
      <h:panelGroup />
      
    5. 我也从 inputtext 组件中删除了require 属性并添加了&lt;p:ajax&gt; 标签(我删除了这个属性,因为&lt;p:ajax&gt; 标签不能像我想要的那样使用这个属性,看看我的帖子@987654321 @):

      <p:inputText  id="tableName" value="#{userTable.name}" >
          <p:ajax event="keyup" update="buttonSend" />                    
      </p:inputText>
      
    6. 最后,我将字段验证从 xhtml 页面移到了 DataController bean 中的 send 方法:

      public void send(){             
      
          boolean validation=true;
      
          if(userTable.getName()==null || userTable.getName().trim().equals("")){
      
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "The name field isn't filled", "You should fill this field"));
      
              validation=false;
          }
      
          if(uploadFile==null){
      
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "The file isn't uploaded", "You should upload a file"));
      
              validation=false;
          }       
      
          if(validation){
      
              //Sending the data to the database... (tha page is blocked)
      
              try {
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
      
              //After successful of sending the data, the page is unlocked.
      
              FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The data has been added.", ""));           
          }
      }
      

    【讨论】:

      【解决方案2】:

      你可以像这样检查验证是否失败

      只需将 render="#{facesContext.validationFailed}" 附加到您的 blockui 并在提交表单时更新它

      【讨论】:

      • 我试图实现你的想法,但它不起作用或者我做错了什么。我为 blockUI 组件添加了 idrendered。除此之外,我还在 commandButton 组件中添加了 blockUI 'id' 到 'update' 属性。之后,blockUI 组件根本不起作用。你知道为什么吗?首先,我注意到当我在 Eclipse 中使用内容辅助来渲染 =#{} 时,Eclipse 没有向我显示任何 facesContext 对象。也许我忘了添加一些东西?
      • 内容辅助不适用于表达语言 afaik,您是否放入了“”?在你的评论中你没有他们如果这不起作用你可以尝试在你的blockui中添加一个小部件var并在你的命令按钮的onstart或onclick中像if(#{facesContext.validationFailed()}){widget.hide( );}
      • 当然我把#{}放在我的代码中的“”里面。我在评论中忘记了。不幸的是,第二个想法也不起作用。在我看来,问题是#{facesContext.validationFailed()}。我检查了返回值,在每种情况下我仍然得到false。你知道为什么吗?
      • 顺便说一句:根据您的第二个想法 - 我找到了解决方案,但我也发现了余额问题。我在DataController bean 中创建了自己的验证方法(返回truefalse)并使用它代替facesContext.validationFailed()。对于第一个想法 - 它仍然不起作用,但对于修改后的第二个想法 - 它(几乎)起作用。我在 blockUI 中使用了 widgetVar 而不是 trigger。然后我添加了onstart(我调用我的验证方法,如果我得到true,我会阻止页面)和oncomplete(我解锁页面)commandButton的属性。
      • 最后我在 fileupload 组件中添加了一个update 属性,并将commandButton id 放在那里。现在它起作用了,但根本不起作用。我发现了与此解决方案相关的问题:在我自己的验证方法中 - 我可以检查文件上传组件(如 if(uploadFile==null)),因为我使用 update 属性作为文件上传,正如我之前所说,但我无法检查来自 inputtext 的值组件,因为只要我按下按钮,它就在 bean 中不可用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多