字段验证成功后屏蔽UI
Block UI after successful of fields verification
我使用 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
,但我不知道怎么做,也许我错了。对我来说最好的方法是,如果我可以 block/unlock 来自 CDI bean 中 send
方法的页面,但我不知道这是否可能,除此之外 - 这不是必需的。每一种方式都会对我有所帮助。
你可以这样检查验证是否失败
只需将 rendered="#{facesContext.validationFailed}" 附加到您的 blockui 并在提交表单时更新它
我终于找到了解决办法。这些是我执行的步骤:
我在 blockUI 组件中使用了 widgetVar
属性而不是 trigger
:
<p:blockUI block="page" widgetVar="widgetBlock">
Sending of the data...
</p:blockUI>
我在 DataController
bean 中创建了自己的验证方法:
public boolean isValidation(){
if(uploadFile==null || userTable.getName()==null || userTable.getName().trim().equals("")) return false;
else return true;
}
我添加了 onstart
(我调用我的验证方法,如果我得到 true
,我阻止页面)和 oncomplete
(我在这里解锁页面)commandButton 的属性:
<p:commandButton id="buttonSend" value="Send" action="#{dataController.send()}" update="messages"
onstart="if(#{dataController.validation}){PF('widgetBlock').show()}"
oncomplete="PF('widgetBlock').hide()" />
我把 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 />
我也从 inputtext 组件中删除了 require
属性并添加了 <p:ajax>
标签(我删除了这个属性是因为 <p:ajax>
标签不起作用像我想要的那样使用这个属性,看看我的 post here):
<p:inputText id="tableName" value="#{userTable.name}" >
<p:ajax event="keyup" update="buttonSend" />
</p:inputText>
最后,我将字段验证从 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.", ""));
}
}
我使用 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
,但我不知道怎么做,也许我错了。对我来说最好的方法是,如果我可以 block/unlock 来自 CDI bean 中 send
方法的页面,但我不知道这是否可能,除此之外 - 这不是必需的。每一种方式都会对我有所帮助。
你可以这样检查验证是否失败
只需将 rendered="#{facesContext.validationFailed}" 附加到您的 blockui 并在提交表单时更新它
我终于找到了解决办法。这些是我执行的步骤:
我在 blockUI 组件中使用了
widgetVar
属性而不是trigger
:<p:blockUI block="page" widgetVar="widgetBlock"> Sending of the data... </p:blockUI>
我在
DataController
bean 中创建了自己的验证方法:public boolean isValidation(){ if(uploadFile==null || userTable.getName()==null || userTable.getName().trim().equals("")) return false; else return true; }
我添加了
onstart
(我调用我的验证方法,如果我得到true
,我阻止页面)和oncomplete
(我在这里解锁页面)commandButton 的属性:<p:commandButton id="buttonSend" value="Send" action="#{dataController.send()}" update="messages" onstart="if(#{dataController.validation}){PF('widgetBlock').show()}" oncomplete="PF('widgetBlock').hide()" />
我把 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 />
我也从 inputtext 组件中删除了
require
属性并添加了<p:ajax>
标签(我删除了这个属性是因为<p:ajax>
标签不起作用像我想要的那样使用这个属性,看看我的 post here):<p:inputText id="tableName" value="#{userTable.name}" > <p:ajax event="keyup" update="buttonSend" /> </p:inputText>
最后,我将字段验证从 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.", "")); } }