Table wont scroll to row I need!

Hi guys.

I have a problem which is driving me mad. Please help. Basically, I cannot get a table to scroll to a known index/item.

It can be roughly summarised as follows.

  1. I create an IndexedContainer, and add 2000 items to it.
  2. I attach the container to the table
  3. I manually scroll half way down the table.
  4. I detach the container from the table - table.setContainerDataSource(null)
  5. I remove all items from the container - container.removeAllItems()
  6. I add 2000 new items to the container.
  7. I reattach the container to the table - table.setContainerDataSource(container)

For some reason, the table ‘auto-scrolls’ to approximately (not exactly) the position it was before. I am showing completely new data here, and want to show data from the first row. I have tried table.setCurrentPageFirstItemIndex(0), but that doesnt work! I can see the scrollbar at the top following the container reattachment, but then jumping immediately to roughly where it was when manually scrolled.

Same issue in all browser I have tried, running Vaadin 7.1.15 (although I have ALWAYS had this issue, it was just never important until now!)

Either I am doing something fundamentally wrong when reloading a table with data (these are report results), or vaadin is caching some scroll value in the table that appears to persist between a container detachment/attachment.

HELP!

Cheers,
Lee.

Hi!
maybe this workaround works ?
I got the same mistery like you with Vaadin 7.0.2 and 7.2.4 it’s seems like Vaadin remember getValue or something like this.

 //automatically select first row in table
                Collection<?> c = Hc.getItemIds();
                if (c.size()>0) {                    
                    Long id = (Long) Hc.getIdByIndex(0);
                      listTable.select(id);
                }

Thanks for your input, but it doesnt really help. I don’t want to select the row, just scroll the table to the beginning.

For what its worth, even if I use your suggestion and select the row first, I have LIMITED success. If I havent scrolled far in the previous contents, its OK after the reload - the first index is selected, the scrollbar is at the top, and everything is displayed fine. If however I have scrolled further down in the previous contents - say line 1000 of 2000, it is NOT OK after the reload - the first index is selected, the scrollbar is at the top, but the table contents appear empty (no rows are displayed) UNTIL I THEN MANUALLY NUDGE THE SCROLLBAR (then the contents appear correctly…:frowning: )

For what its worth, I have tried keeping the container attached to the table as I repopulate it, but I get the same issues.

Any other ideas, anyone?

Ok.

Here is a small runnable example that shows the exact problem. Im kinda hoping someone will take the time out to try this (a dev would be great ;)) and suggest what I have to do to make the table scroll to the top. It seems such a simple thing to want to do!

Press reload to fill the table with 2000 rows. Scroll half way down. Press reload again to fill the table with 2000 rows of new data (in our live environment, usually VERY different data). You will notice that the scrollbar maintains its position. This is unwanted behaviour for us, we simply want to reset it to the top so that row 0 shows. How do we do this?? :slight_smile: Neither of the two lines I try (and are recommended) do the job.

Note I have kept the way we create & reload the table exactly as is done in our code. We detach containers before doing the mass replace for performance reasons (our tables generally have many listeners), but the problem exists even if you comment out the setContainerDataSource() calls in the reload() method.

import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

@PreserveOnRefresh
public class IngEstateUI extends UI
{    
    // Create the container that will hold the table data
    private IndexedContainer container;
    private String containerPropertyIds = new String[7]
;
    
    private Table table;
    private int reloadCount = 0;
    
    @Override
    public void init(VaadinRequest vaadinRequest)
    {            
        // create empty table to begin with
        table = new Table();

        table.setHeight("100%");
        table.setWidth("100%");        
        table.setImmediate(true);
        table.setSelectable(true);
        table.setMultiSelect(false);
        table.setNullSelectionAllowed(false);                  
        table.setSortEnabled(false);
                
        // container that will hold the data, and be attached to the table
        container = new IndexedContainer();
                
        // Set the name/types of each column
        for (int i = 0; i < 3; i++)
        {
            containerPropertyIds[i]
 = new String("Col " + i);
            container.addContainerProperty(containerPropertyIds[i]
, String.class, null);            
        }
                
        table.setContainerDataSource(container);
        
        VerticalLayout vl = new VerticalLayout();
        vl.setSizeFull();
        vl.setMargin(true);
        vl.setSpacing(true);                
        vl.addComponent(table);
        
        Button button = new Button("Reload", new Button.ClickListener()
        {            
            @Override
            public void buttonClick(ClickEvent event)
            {
                reload();                
            }
        });
        
        button.setSizeUndefined();        
        vl.addComponent(button);

        vl.setExpandRatio(table, 1);
        vl.setComponentAlignment(button, Alignment.MIDDLE_RIGHT);
        
        setContent(vl);
    }
    
    private void reload()
    {
        reloadCount++;
        
        // detach container source then empty
        table.setContainerDataSource(null);
        container.removeAllItems();
        
        Property p;
        
        for (int i = 0; i < 2000; i++)
        {
            Object itemId = container.addItem();
            Item item = container.getItem(itemId);
            
            for (int j = 0; j < 3; j++)
            {
                p = item.getItemProperty(containerPropertyIds[j]
);
                p.setValue("Reload " + reloadCount + ": Row " + i + ", Col " + j);
            }            
        }
        
        // reattach container source
        table.setContainerDataSource(container);
        
        // now how do we get it to scroll to beginning? None of the below work...
        // table.setCurrentPageFirstItemIndex(0);        
        // table.setCurrentPageFirstItemId(container.firstItemId());
    }
}
[/i]
[/i]

Yep it seems to keep the table “scroll position”, i found no way to discard it.
What’s working is to replace the table before you fill i again :

table = new Table();
vl.replaceComponent(oldTable, table);

But that will force you to register your multiple listeners again.

Regards

Thanks Sebastien - that’s already been filed away as the final ‘hack’ we will grudingly implement if nobody can come up with anything cleaner.

Would any vaadin dev like to step up to the plate and suggest something, or at least confirm this is an issue?

Bump.

Have you tried any of the following after you reconfigured the table ?

            table.refreshRowCache();
            table.markAsDirty();

The fact that Table is not discarding the scroll position when you remove the data source is a bug. If you file a ticket about the issue in the issue tracker it might get fixed some day. Most devs only read the forums occasionally and these kinds of issues are easily missed among all the other messages.

I have filed a ticket with Vaadin on this issue as we are seeing simliar behavor with trying to scroll to certain rows.
-Dan

http://dev.vaadin.com/ticket/14475

Same problem still persisting in vaadin 6, could the same fix be applied in vaadin 6 as it was for vaadin 7?