Primefaces RequestContext scrollTo does not work

2019-07-03 03:33发布

问题:

Primefaces v3.5

Trying to use RequestContext.getContext().scrollTo("") to scroll to my form programmatically at the end of an ajax request.

XHTML snippets:

<h:form id="genericMessagesForm">
                    <p:messages id="genericMessages" />
                </h:form>
<p:commandButton id="testButton" 
            value="Test" process="#{cc.attrs.itemName}Final, @this"
                actionListener="#{myBean.methodCalledByAjax()}" />

Bean:

public void methodCalledByAjax() {
    List<String> updateTargets = new ArrayList<String>();
                updateTargets.add("currentRecordForm");
                updateTargets.add("genericMessagesForm");
                RequestContext.getCurrentInstance().update(updateTargets);
                RequestContext.getCurrentInstance().scrollTo("genericMessagesForm");
}

Update does work.

ScrollTo does NOT work (same ID!).

No server errors thrown.

No javascript console errors thrown.

Browsers tried: Firefox (latest), Chrome (latest), IE8.

回答1:

Did you look in the documentation? Here's a cite from the RequestContext#scrollTo() javadoc:

scrollTo

public abstract void scrollTo(String clientId)

Scroll to a component after ajax request is completed.

Parameters:

clientId - Client side identifier of the component.

Look, it says client ID, not component ID. It makes also sense, the scrolling job is ultimately done by JavaScript via document.getElementById() and friends. That works only with a client ID.

For starters who haven't memorized the whole NamingContainer thing, an easy way to figure the right client ID is by looking at the JSF-generated HTML output via rightclick, View Source in webbrowser.

For a

<h:form id="genericMessagesForm">
    <p:messages id="genericMessages" />
</h:form>

that's thus something like

<form id="genericMessagesForm" ...>
    <div id="genericMessagesForm:genericMessages" ...>
        ...
    </div>
</form>

So, fix the call accordingly:

requestContext.scrollTo("genericMessagesForm:genericMessages");

By the way, if the form contains solely the <p:messages>, then you can alternatively also just get rid of the whole form altogether. The <p:messages> is not an EditableValueHolder nor ActionSource component and does therefore not require to be placed in an UIForm component. This way you can keep using your initial attempt.

See also:

  • How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"