问题
I have a contact form at the bottom of a page with required and validated form fields. If validation fails, how can I get the scroll position back to the bottom of the page?
I want this page to work with Javascript disabled, so no AJAX solutions. I have something like this:
<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>
I thought about doing validations on the bean side and doing manual redirects to the appropriate anchor, but that seems to defeat the purpose of using JSF to begin with. I assume there is an easy way to do this, but I'm having trouble Googling a solution because I'm probably not wording the question right. Any one?
回答1:
You can use <f:event type="postValidate"> to have a listener hook right after the validations phase. You can use FacesContext#isValidationFailed() to check if validation has failed or not. You can use Flash#setKeepMessages() to let the faces messages survive a redirect (they're namely by default request scoped!). You can use ExternalContext#redirect() to perform a redirect in a non-action method.
So, summarized, this should do:
<h:form id="cform">
...
<f:event type="postValidate" listener="#{bean.postValidate}" />
</h:form>
with:
public void postValidate() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.isValidationFailed()) {
context.getExternalContext().getFlash().setKeepMessages(true);
context.getExternalContext().redirect("contact.xhtml#cform");
}
}
回答2:
Or we can use f:ajax onerror= for do something if they are an errors :
<p:commandButton **>
<f:ajax onerror="window.scrollTo(0, 0);" />
</p:commandButton>
回答3:
You don't need an explicit anchor tag for this, the id of the form will do.
You could make Faces render the id at the end of the form action Url.
Eg.
... Your main page content goes here ....
<form id="contact-form" action="/MyView.jsf#contact-form" method="post">
This will cause the browser to scroll to the form after it is submitted.
It shows in the Url too.
You could probably implement a custom Form renderer to do this.
来源:https://stackoverflow.com/questions/12378974/scrolling-to-anchor-or-page-bottom-after-jsf-form-validation-fail