I'd like to implement infinite scroll page in JSF. So I tried it.
My goal
Today's goal is following simple web page by using JSF.
PrimeFaces Extensions Waypoint component
PrimeFaces Extensions Showcase has good examples.
http://fractalsoft.net/primeext-showcase-mojarra/views/waypoint.jsf
I show my implement result at first.
Run my web application, there are many panel components like this.
When your scroll reached the bottom of web page, then JavaScript event is executed.
The dialog shows 'すたーと', the Japanese word means start.
What is start? Of course, JavaScript function starts.
JavaScript starts to read new panel data from Backing Bean through RemoteCommand component.
After reading adding panel data, then another JavaScript function executes.
'えんど' means end.
It works! Ten panels are added.
If you scroll down again, the same processing run.
I repeated this until around 500 panels.
Code
Here is my Backing Bean of this sample. It's very simple.
package jp.co.hoge.pfsample.ext.waypoint;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import lombok.Getter;
import lombok.Setter;
@Named(value = "wayPointPanelBean")
@ViewScoped
public class WayPointPanelBean implements Serializable{
@Getter @Setter
private List<String> strList;
private int strListMax = 0;
@PostConstruct
public void init(){
strList = new ArrayList<>();
for(int i = 1; i <= 50; i++){
strList.add(Integer.toString(i));
}
}
public void loadMorePanel(){
strListMax = strList.size();
for(int i = strListMax + 1; i <= strListMax + 10; i++){
strList.add(Integer.toString(i));
}
}
}
Facelets is following.
<?xml version='1.0' encoding='UTF-8' ?>
<html lang="ja"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:head>
<title>Waypoint</title>
</h:head>
<h:body>
<h:form prependId="true">
<p:dataGrid id="dgPanel" var="pnl" value="#{wayPointPanelBean.strList}">
<p:panel id="pnl" header="#{pnl}">Name:hogehoge#{pnl}</p:panel>
</p:dataGrid>
<p:remoteCommand id="remote" name="loadMore" update="dgPanel" process="@this"
actionListener="#{wayPointPanelBean.loadMorePanel()}"
oncomplete="handleLoadEnd();">
</p:remoteCommand>
<pe:waypoint id="way" offset="function(){return $.waypoints('viewportHeight') - $(this).outerHeight()}" widgetVar="widgetWay">
<pe:javascript event="reached" execute="handleLoadStart(ext);" />
</pe:waypoint>
<script type="text/javascript">
function handleLoadStart(ext){
if(ext.direction === "down"){
alert("すたーと");
PF('widgetWay').remove();
loadMore();
}
}
function handleLoadEnd(){
alert("えんど");
PF('widgetWay').register();
}
</script>
</h:form>
</h:body>
</html>
This is very similar code to Showcase one.
I'm not familiar with jQuery, so the offset attribute is pretty difficult for me at first.
For understanding, I read jQuery Waypoint plugin document.
http://imakewebthings.com/jquery-waypoints/#docs
Finally I figured what offset defines in this code. And I understood it.
Environment
- Windows 8 Pro 64bit
- JDK 8
- NetBeans 7.4
- GlassFish 4.0
- PrimeFaces 4.0
- PrimeFaces Extensions 1.1.0