JSF Salvar posição de rolagem ao adicionar / excluir linhas de forma automática da tabela de dados

Ao adicionar ou excluir linhas automaticamente de uma tabela de dados JSF, você deve renderizar novamente a tabela inteira em vez de apenas renderizar novamente uma linha específica.

A desvantagem disso é que, se você tiver uma tabela de dados rolável, perderá sua posição de rolagem.

Por exemplo

Digamos que você tenha uma tabela de dados que mostra 20 linhas e qualquer coisa acima de 20 linhas, você terá que rolar para baixo para ver essas linhas. Digamos que tenhamos um botão de exclusão para cada linha e se você rolar para baixo e excluir a linha 49, por exemplo (provavelmente, é claro), terá que renderizar novamente a tabela de dados e a posição de rolagem estará no topo novamente.

Recentemente, tive que encontrar uma solução para esse problema e, na verdade, acabou sendo muito mais fácil do que eu esperava.

O truque

A chave é armazenar a posição de rolagem em uma variável javascript e, em seguida, quando a ação do botão adicionar ou excluir for concluída, definir a posição de rolagem via javascript.

Código

Você pode ver que estou usando um a4j: commandButton (só porque sou forçado a fazer atualizações em um aplicativo richfaces no JSF 1.2, caso contrário, eu usaria um h: commandButton com a tag f: ajax ou melhor ainda, uma tabela de dados primefaces com ap: commandButton)

Tabela de dados JSF

<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);
}

É isso aí. Um pouco de js, um pouco de magia e um cliente um pouco mais feliz. Felicidades.