[英]jsf input validation inside ajax4jsf actionlistener method
我正在学习JSF + Seam Framework + AJAX4JSF并构建一个应用程序。 我的应用程序有一个称为条形码的输入字段,用户可以对其进行扫描/输入。 输入条形码后,我将使用ajax4jsf进行ajax调用以调用侦听器方法。 侦听器方法应验证输入的条形码。 它根据数据库验证条形码,如果无效,则返回FacesMessage。 如果条形码有效,则它将使用条形码更新数据库并返回JSF。 应该调用ajax4jsf中提到的render块来渲染页面,并且应该执行oncomplete中提到的javascript方法。
我的代码如下。
JSF代码:
<html ....
xmlns:a="http://richfaces.org/a4j"
xmlns:p="http://primefaces.org/ui">
//javascript function
function renderPlate(data) {
......
}
<h:form id="myForm">
<h:outputText value="Scan barcode:" />
<h:inputText id="inputBarcode" value="#{myBean.inputBarcode}">
<a:ajax event="change" render="plateGrid" listener="#{myBean.addBarcodedItemToCheckout}" oncomplete="renderPlate()"/>
</h:inputText>
</h:form>
<a:outputPanel id="plateGrid">
<h:messages id="messages" style="color:red;margin:8px;" autoUpdate="true"/>
....
</a:outputPanel>
我的煤豆:
@Scope(ScopeType.CONVERSATION)
@Name("plateMakerBean")
@Stateless
public class PlateMakerAction {//implements PlateMaker {
private String inputBarcode;
public void addBarcodedItemToPlate() {
boolean invalidBarcode = false;
List<Item> items = em.createQuery("select m from Item i where barcode= #{inputBarcode}").getResultList();
if(items == null || items.size() == 0) {
invalidBarcode = true;
}
if(invalidBarcode == true) {
FacesMessages.instance().add("Barcode is not a valid barcode.");
}
}
}
我面临的问题/问题是这样的:
当我返回FacesMessages时,oncomplete中提到的javascript方法仍在执行。 有什么方法可以在Ajax actionlistener方法中进行验证并避免调用oncomplete方法?
我们可以在ajax动作侦听器方法中进行输入验证吗? 这是正确的做法吗? 我正在经历一些stackoverflow问题,有些建议我们应该改用jsf自定义验证器? 定制验证器是唯一验证输入值的唯一方法,它具有一些业务逻辑来验证输入值? 我尝试添加自定义验证器,当我这样做时,自定义验证器将被执行并显示错误。 但是,a:ajax actionlistener没有得到调用,这是我期望的。 但是,提到的要在render(plateGrid)中渲染的部分未渲染。 但是,即使客户验证程序返回验证错误,也会调用oncomplete(renderData)中提到的javascript代码。 我的JSF代码带有自定义验证器,我的客户验证器方法如下:
带有定制验证器的JSF代码
<h:form id="myForm">
<h:outputText value="Scan barcode:" />
<h:inputText id="inputBarcode" value="#{myBean.inputBarcode}" immediate="true">
<f:validator validatorId="barcodeValidator" />
<a:ajax event="change" render="plateGrid" listener="#{myBean.addBarcodedItemToCheckout}" oncomplete="renderPlate()"/>
</h:inputText>
</h:form>
<a:outputPanel id="plateGrid">
<h:messages id="messages" style="color:red;margin:8px;" autoUpdate="true"/>
....
</a:outputPanel>
我的自定义验证器:
@Name("barcodeValidator")
@Scope(ScopeType.CONVERSATION)
@org.jboss.seam.annotations.faces.Validator
@BypassInterceptors
public class BarcodeValidator implements Validator, Serializable {
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if(value != null) {
String barcode = value.toString();
if(barcode.equals("M0"))
throw new ValidatorException(new FacesMessage("Invalid Barcode"));
}
}
}
任何帮助和建议,将不胜感激。
可以在完成之前检查验证。创建一个不显示任何内容的ajax4jsf命令按钮可能是一个好主意,如下所示:
<div style="display:none">
<a:commandButton data="#{albumManager.validationSuccess}"
value="#{messages['album.store']}"
actionListener="#{albumManager.addAlbum(album)}"
id="storebutton"
reRender="treePanel, mainArea, menu"
oncomplete = "if(data)$('albumModalPanel').component.hide()" styleClass="album"/>
</div>
读取条形码后,创建一个js函数并使用jQuery单击该按钮
<h:inputText id="inputBarcode" value="#{myBean.inputBarcode}" immediate="true" onchange="onChangeBarcode();">
function onChangeBarcode()
{
jQuery("storebutton").click();
}
希望对您有所帮助。 有关更多信息,请访问richfaces +接缝样本(相册)
你可以这样做...
<h:inputText id="inputBarcode" value="#{myBean.inputBarcode}">
<a:ajax event="change" render="plateGrid"
listener="#{myBean.addBarcodedItemToCheckout}"
oncomplete="if(!#{myBean.invalidBarcode}){renderPlate()}"/>
</h:inputText>
不过,使用JSF验证程序将是执行此操作的“正确”方法
顺便说一句:您的PlateMakerAction组件使用@Stateless和@Scope(ScopeType.CONVERSATION)进行注释,这是错误的,除非您真的希望它成为无状态的,否则您应该放弃@Stateless注释,我对此表示怀疑
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.