JSF表单验证失败后滚动到锚点或页面底部



我在页面底部有一个联系人表单,其中包含必需和已验证的表单字段。如果验证失败,如何将滚动位置返回到页面底部?

我希望这个页面在禁用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中。

您可能可以实现一个自定义的表单呈现器来实现这一点。

最新更新