This post shows how to implement an infinite scroll in AEM classic and touch UI using a jQuery Plugin jScroll. For more information about the jQuery Plugin jScroll please visit http://jscroll.com
PRE-REQUISITES
Create an initial Maven Project with the basic archetype. If you haven’t set up Maven yet or don’t know how to create an archetype, follow the steps under the “Setup Maven” section of this guide:
https://helpx.adobe.com/experience-manager/using/creating-sightly-component.html
Let’s explain this code a bit:
List<PageInfo>: PageInfo is a POJO with these attributes: private String path, private String imgPath, private String imgExtension, getters, and setters.
TYPE: is a constant private final String TYPE = “cq:Page”, in order to filter by Pages.
BASE_LIMIT: is constant private final String BASE_LIMIT = “5”
p.limit: the number of items returned.
Path.flat: allow us to filter by only the first step of child pages.
p.offset: Mostly used in pagination, is the offset for paging.
As you can see this method calls another two methods, one named getPropertyValue which gets the property that contains the main path from the resource node, and the other one named getListPageInfo(), which returns a list of PageInfo charged with the image and the path.
Here is the implementation of both:
Obs:
PROPERTY_NAME is the name of the property called “name” of the dialog which has a path field. And the other method:
Finally we have the startPage method which allows us to know the position of the pagination:
Let’s now create the clientlibs. This folder should have a clientLibraryFolder type and must have a categories type to include in the component:
Its properties:
In this folder we include the js files for the infinite scroll, in this case we also include the jquery.jscroll.js, but it could be jquery.jscroll.min.js instead. If you take a look to the picture above, we also have to create an extra file called scripts.js inside the clientlibs folder which contains the following code
We should be initializing the jscroll for all the content inside the div that contains the class “mylist”.
We are now able to write the Sightly code in the HTML component to use infinite scroll:
Finally, we have to create the dialog in order to obtain the path where the images are. In this case, we create one dialog for the classic version and another dialog for touch UI.
Here is the structure:
And the most important properties:
Create an initial Maven Project with the basic archetype. If you haven’t set up Maven yet or don’t know how to create an archetype, follow the steps under the “Setup Maven” section of this guide:
https://helpx.adobe.com/experience-manager/using/creating-sightly-component.html
Back-end
First, we have to create a service that extends from WCMUse. Using this service, we will get all the children that contain images and display all the images within the path of a selected page. In order to empower this, you are going to create two different solutions only by changing only one line of code. The first solution will give you only the first level of children pages (not the children of children) and the other solution will return you all the children pages of the path given.
This service has a method to obtain the first pages to be shown, starting in the actual page and another method to get the next pages for the infinite scroll.
This method returns the page of the actual paginated index, as well as the pages to show at that time, but not all existing pages.
This is important because it improves the performance since the page is loaded on demand.
The method used to obtain the pages searches the children's pages from the start page of the path used using the query builder. Then the result of the query is processed and it builds a list of the pages that have images.
The method would look like this:
First, we have to create a service that extends from WCMUse. Using this service, we will get all the children that contain images and display all the images within the path of a selected page. In order to empower this, you are going to create two different solutions only by changing only one line of code. The first solution will give you only the first level of children pages (not the children of children) and the other solution will return you all the children pages of the path given.
This service has a method to obtain the first pages to be shown, starting in the actual page and another method to get the next pages for the infinite scroll.
This method returns the page of the actual paginated index, as well as the pages to show at that time, but not all existing pages.
This is important because it improves the performance since the page is loaded on demand.
The method used to obtain the pages searches the children's pages from the start page of the path used using the query builder. Then the result of the query is processed and it builds a list of the pages that have images.
The method would look like this:
public List getPages(){
//getting the property value which contains the main path, from the resource node
String path = getPropertyValue();
Map<String, String> predicates = new HashMap<String,String>();
predicates.put("path", path);
predicates.put("type", TYPE);
//uncomment the line below in order to get only the first level of child pages.
//predicates.put("path.flat", "true");
predicates.put("p.limit", BASE_LIMIT);//limita la cantidad de resultados
predicates.put("1_property", "@jcr:content/image");//Only pages with Images
predicates.put("p.offset", this.startPage.toString());
PredicateGroup predGroup = PredicateGroup.create(predicates);
ResourceResolver resolver = this.getResourceResolver();
session = resolver.adaptTo(Session.class);
builder = resolver.adaptTo(QueryBuilder.class);
query = builder.createQuery(predGroup, session);
return getListPageInfo();
}
Let’s explain this code a bit:
List<PageInfo>: PageInfo is a POJO with these attributes: private String path, private String imgPath, private String imgExtension, getters, and setters.
TYPE: is a constant private final String TYPE = “cq:Page”, in order to filter by Pages.
BASE_LIMIT: is constant private final String BASE_LIMIT = “5”
p.limit: the number of items returned.
Path.flat: allow us to filter by only the first step of child pages.
p.offset: Mostly used in pagination, is the offset for paging.
As you can see this method calls another two methods, one named getPropertyValue which gets the property that contains the main path from the resource node, and the other one named getListPageInfo(), which returns a list of PageInfo charged with the image and the path.
Here is the implementation of both:
private String getPropertyValue() {
Resource parResource = getCurrentPage().getContentResource(PARENT_NODE);
Resource rootResource = parResource.getChild(CHILD_NODE);
return (String) rootResource.getValueMap().get(PROPERTY_NAME);
}
PROPERTY_NAME is the name of the property called “name” of the dialog which has a path field. And the other method:
private List getListPageInfo() {
List listPage = new ArrayList();
try {
if (query.getResult() != null) {
for (Hit hit: query.getResult().getHits()) {
PageInfo pageInfo = new PageInfo();
Page page = this.getPageManager().getPage(hit.getPath());
Resource r = page.getContentResource("image");
if (r != null) {
Image image = new Image(r);
pageInfo.setImgPath((String) image.getFileReference());
pageInfo.setImgExtension((String) image.getExtension());
}
pageInfo.setPath(hit.getPath());
listPage.add(pageInfo);
}
}
} catch (RepositoryException e) {
e.printStackTrace();
}
return listPage;
}
Finally we have the startPage method which allows us to know the position of the pagination:
public int getStartPage() {
return startPage + Integer.parseInt(BASE_LIMIT);
}
Front-endLet’s now create the clientlibs. This folder should have a clientLibraryFolder type and must have a categories type to include in the component:
Its properties:
In this folder we include the js files for the infinite scroll, in this case we also include the jquery.jscroll.js, but it could be jquery.jscroll.min.js instead. If you take a look to the picture above, we also have to create an extra file called scripts.js inside the clientlibs folder which contains the following code
$(document).ready(function () {
$('.scroll').jscroll({
contentSelector: '.mylist'
});
})
We are now able to write the Sightly code in the HTML component to use infinite scroll:
Let's explain this code
data-sly-use.data: The first div includes the bundle which has the logic for the pagination.
data-sly-list: It allows us to have a list loaded with the method getPages inside the bundle.
data-sly-test: Only shows the HTML inside that div section if the conditions are both true.
Inside the hyperlink, we are getting the path of the current node, in order to send the server the last position of the pagination by the method named startPage.
In this code, you can see how the infinite scroll calls the methods. When scrolling the page, the method startPage is called and jScroll automatically loads content into the page via AJAX.
To make this component more visible to the user, we add some style so now, we have to create a style.css file inside the clientlibs folder.
data-sly-use.data: The first div includes the bundle which has the logic for the pagination.
data-sly-list: It allows us to have a list loaded with the method getPages inside the bundle.
data-sly-test: Only shows the HTML inside that div section if the conditions are both true.
Inside the hyperlink, we are getting the path of the current node, in order to send the server the last position of the pagination by the method named startPage.
In this code, you can see how the infinite scroll calls the methods. When scrolling the page, the method startPage is called and jScroll automatically loads content into the page via AJAX.
To make this component more visible to the user, we add some style so now, we have to create a style.css file inside the clientlibs folder.
.scroll {
border: 1px solid #aaa;
padding: 5px 10px;
height: 500px;
overflow-y: scroll;
margin: 20px 0;
background: #ffc;
}
Here is the structure:
And the most important properties:
For Touch UI:
For classic:
Here are some result screenshots
Touch UI solution:
Here are some result screenshots
Touch UI solution:
Classic solution:
No comments:
Post a Comment
If you have any doubts or questions, please let us know.