我在页面底部有一个联系人表单,其中包含必需和已验证的表单字段。如果验证失败,如何将滚动位置返回到页面底部?
我希望这个页面在禁用Javascript的情况下工作,所以没有AJAX解决方案。我有这样的东西:
<a id="contact"></a>
<h:form id="cform">
<h5>Contact!</h5>
<h:outputLabel for="name">Name:
<h:message id="nameMsg" for="name" />
</h:outputLabel>
<h:inputText id="name" value="#{bean.name}" required="true" requiredMessage="Please enter name!" />
<h:outputLabel for="email">Email:
<h:message id="emailMsg" for="email" />
</h:outputLabel>
<h:inputText id="email" value="#{bean.email}" required="true" requiredMessage="Email is required!">
<f:validator validatorId="myValidator" />
</h:inputText>
<h:outputLabel for="comment">Comment:
<h:message id="commentMsg" for="comment" />
</h:outputLabel>
<h:inputTextarea id="comment" value="#{bean.comment}" required="true" requiredMessage="Please enter a comment!"/>
<h:commandButton action="#{bean.go}" id="send" value="send" />
</h:form>
我曾想过在bean端进行验证,并手动重定向到适当的锚点,但这似乎违背了最初使用JSF的目的。我想有一个简单的方法可以做到这一点,但我在谷歌上搜索解决方案时遇到了困难,因为我可能没有正确地表达问题。有人吗?
您可以使用<f:event type="postValidate">
在验证阶段之后立即拥有侦听器挂钩。您可以使用FacesContext#isValidationFailed()
检查验证是否失败。您可以使用Flash#setKeepMessages()
让faces消息在重定向后继续存在(即,默认情况下它们是请求范围的!)。您可以使用ExternalContext#redirect()
在非操作方法中执行重定向。
所以,总结一下,这应该做:
<h:form id="cform">
...
<f:event type="postValidate" listener="#{bean.postValidate}" />
</h:form>
带有:
public void postValidate() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.isValidationFailed()) {
context.getExternalContext().getFlash().setKeepMessages(true);
context.getExternalContext().redirect("contact.xhtml#cform");
}
}
或者,如果它们是错误,我们可以使用f:ajax-onerror=来做一些事情:
<p:commandButton **>
<f:ajax onerror="window.scrollTo(0, 0);" />
</p:commandButton>
您不需要显式的锚点标记,表单的id就可以了。
您可以让Faces在表单操作Url的末尾呈现id。
例如。
您的主页内容显示在此处。。。。
<form id="contact-form" action="/MyView.jsf#contact-form" method="post">
这将导致浏览器在表单提交后滚动到该表单。
它也显示在Url中。
您可能可以实现一个自定义的表单呈现器来实现这一点。