Last Updated: February 25, 2016
·
10.4K
· toymachiner62

JSF Save Scroll Position When Ajaxily Add/Deleting Rows From Datatable

When adding or deleting rows ajaxily from a JSF datatable, you have to rerender the entire table rather than just rerendering a specify row.

The downfall to this is that if you have scrollable datatable, you lose your scroll position.

For Example

Lets say that you have a datatable that shows 20 rows and anything over 20 rows you will have to scroll down to see those rows. Lets say we have a delete button for every row and if you scroll down and delete row 49 for example (ajaxily of course), you have to rerender the datatable and the scroll position is all the way at the top again.

I recently had to come up with a solution to this problem and it actually turned out to be much easier than i anticipated.

The Trick

The key is to store the scroll position in a javascript variable and then when the add or delete button action is completed, set the scroll position via javascript.

Code

You can see that i'm using an a4j:commandButton (only beacuse i'm forced to make updates to a richfaces app on JSF 1.2 otherwise i'd use an h:commandButton with f:ajax tag or better yet, a primefaces datatable with a p:commandButton)

JSF datatable

<h:dataTable value="#{blah.blah}" var="#{blah}" id="table">
    <h:column>
    <a4j:commandButton value="del"
        onclick="confirm('Are you sure you want to delete this attribute?')"
        onmousedown="saveScrollPosition();"
        oncomplete="setScrollPosition();"
        reRender="table"
        actionListener="#{backing.deleteRow}" immediate="true"/>
    </h:column>
</h:dataTable>

Javascript

var scrollPosition;

function saveScrollPosition() {
    scrollPosition = $('#table').scrollTop();
}

function setScrollPosition() {
    $('#table').scrollTop(scrollPosition);
}

That's it. A little js, a little magic, and a little happier client. Cheers.