Continuous or infinite scrolling in the gridlayout

Hello,

I a m developing a new application based on Vaadin. On one of the screens, there is a gridlayout which contains a set of panels (as CssLayout).

By default, I display 3x3 panels, and I would to add a new feature. If the page is scrolled down, a new set of 3x3 panels is added at the end of the gridlayout, and so on…

I took a look around vadin forums, google, … but I think it’s not supported by default.

Is there a workaround to do it ?

I guess the following assumptions…

From the client-code, be able to send a rpc call (when the scroll is enough down) and so from server-side look for next data for new panels, and add theme to the end of the gridlayout.

You’re exactly right - there’s no support for such functionality in vaadin directly, but it’s quite easy to implement. I’ve implemented such feature in a few projects but don’t have the code at hand right now. If I remember right, an extension was enough to do it for the panel component. Just catch the scroll event, check the scroll position and once it’s at the end, send an event to the server.

Do note that you will most likely need some kind of delay before loading the new stuff, since it’s quite easy for the user to generate a huge amount of scroll events with an accelerated touchpad/scrollwheel.

Good news :wink: I discover Vaadin so my questions can be a little bit newbie…

Can you give me more explanation ?

  • By extension, you mean extends the gridlayout ?

  • If I add on live a component to the gridlayout, it will automatically be displayed ? Do I have to enable a specific feature on the layout ?

  • How can I catch the scroll event ? In the java code or in a javascript library ?

  • I guess that it’s possible to accept only a part of the scroll events… in order to not have a big trafficjam.

I read some docs about Vaadin… and I think that I have to create a new widget with a client-side connector and server-side component,

By extension, Teppo means the Vaadin 7 Extension system where you can add functionality to components without creating a new subclass of that component. Please take a look at
the Extension chapter in Book of Vaadin
.

Hi,

I found some code for the Panel scroll end detection. Disclaimer: it should work but is highly experimental, so please handle with care and do some testing. It probably needs some work.

On the client side I have two classes:

package com.example.infinitetable.client.mycomponent;

import com.example.infinitetable.PanelScrollDetector;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.client.ui.VPanel;
import com.vaadin.client.ui.panel.PanelConnector;
import com.vaadin.shared.ui.Connect;

@Connect(PanelScrollDetector.class)
public class PanelScrollDetectorConnector extends AbstractExtensionConnector
implements ScrollHandler {
private VPanel target;
private HandlerRegistration scrollHandler;
private int latestScrollTop;
private int latestScrollLeft;

@Override
protected void extend(ServerConnector target) {
this.target = ((PanelConnector) target).getWidget();
scrollHandler = this.target.addHandler(this, ScrollEvent.getType());
}

@Override
protected void init() {
super.init();
}

@Override
public void onScroll(ScrollEvent event) {

Scheduler.get().scheduleDeferred(new ScheduledCommand() {

@Override
public void execute() {
int newscrollTop = DOM.getElementPropertyInt(
target.contentNode, "scrollTop");
int newscrollLeft = DOM.getElementPropertyInt(
target.contentNode, "scrollLeft");
if (newscrollTop != latestScrollTop
|| newscrollLeft != latestScrollLeft) {
int panelHeight = target.contentNode.getOffsetHeight();
int contentHeight = target.contentNode
.getFirstChildElement().getOffsetHeight();
int maxScrollPoint = contentHeight - panelHeight;
latestScrollTop = newscrollTop;
latestScrollLeft = newscrollLeft;
if (maxScrollPoint == latestScrollTop) {
getRpcProxy(PanelScrollDetectorRpc.class)
.thresholdReached();
}
}
}
});
}

@Override
public void onUnregister() {
super.onUnregister();
if (scrollHandler != null) {
scrollHandler.removeHandler();
}
}
}
package com.example.infinitetable.client.mycomponent;

import com.vaadin.shared.communication.ServerRpc;

public interface PanelScrollDetectorRpc extends ServerRpc {

public void thresholdReached();

}

On the server side there’s just an extension class with an abstract method that will be called when the end is reached:

package com.example.infinitetable;

import com.example.infinitetable.client.mycomponent.PanelScrollDetectorRpc;
import com.vaadin.server.AbstractExtension;
import com.vaadin.ui.Panel;

public abstract class PanelScrollDetector extends AbstractExtension {

public PanelScrollDetector() {
registerRpc(new PanelScrollDetectorRpc() {

@Override
public void thresholdReached() {
endHasBeenReached();
}
});
}

protected void extend(Panel target) {
super.extend(target);
}

public abstract void endHasBeenReached();
}

And to use it, just call:

PanelScrollDetector psd = new PanelScrollDetector() {

@Override
public void endHasBeenReached() {
// Add some components
}
};
psd.extend(yourPanelInstance);

Hope it gets you started.

p.s. sorry for the formatting, seems that pasting here breaks the indents.

Thank you. I will take a look tonight, it will help me a lot.

Hello guys,

I started to use the advices of Teppo.

So I created a separate project as Maven module for this widget.

But I have the following error: Widgetset does not contain implementation for xxx.PanelScrollDetector. Check its component connector’s @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.

I guess that it’s a stupid error from me. In my widget project, I have only 3 Java classes, do I have to add MyWidget.gwt.xml file for inside this widget ? and a web.xml file ?

In my main project, I added the Maven dependendy for this widget.

At first try, I included the 3 Java classes for the widget directly inside my project, and I got the same error message.

Or do I have to add something special in my MyProject.gwt.xml

Any help is welcome :wink:

I took a look tonight and my error was that I didn’t compile the widgetset :wink:

But… it doesn’t work. Probably because I don’t scroll into the panel. I have to find a solution!

If you can, please post the code for your solution. It’s quite difficult to help without knowing what you have exactly done.