I've been dealing with a use case recently where we needed to synchronize two panels in a user interface, where (in the simple version) selecting an object on one side of the screen would also select a corresponding object in a scrolling area on the other side of the screen and scroll in into view. the scrolling panel in this case being a panelGroupLayout / scroll, not a table.
Declarative scrolling is really simple, you can drop a UI element such as commandButton onto the page and then nest, within that, the behavior tag <af:scrollComponentIntoViewBehavior>. This tag is great if you have a long page and want to provide the users with a way to navigate to different sections, however, it needs to be wired to a command component and the user needs to physically invoke the operation.
In this case, everything needed to happen in reaction to a series of complex programmatic events and so, the use of the behavior tag did not cut it. So I did a small amount of testing to see if it was possible to achieve the same result in a hands off fashion from within java code.
It turns out to be pretty simple to do, as with the behavior tag, you need to do two things.
- The target component has to have clientComponent="true" as this scrolling operation all takes place on the client
- You need the full id of the target component. This should include any naming containers such as templates and regions. The safest way to do this is to call getClientId() on the java component itself.
Then you can just invoke this little function. Note that the code does not have any error handling if you get the component ID wrong so feel free to improve it to make it more robust:
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService; import org.apache.myfaces.trinidad.util.Service; private void scrollIntoView(String componentId){ StringBuilder builder = new StringBuilder(); builder.append("var c = AdfPage.PAGE.findComponent('"); builder.append(componentId); builder.append("'); c.scrollIntoView(true,null);"); FacesContext fctx = FacesContext.getCurrentInstance(); ExtendedRenderKitService erks = Service.getRenderKitService(fctx, ExtendedRenderKitService.class); erks.addScript(fctx, builder.toString()); }