To any AEM Developer, I would highly recommend you to go through this article as this pagination component works together with some of the important concepts of AEM like Query Builder, Sling Model, JavaScript Use API and Sightly. In terms of functionality of this component its very similar to what we have in our AEM Community.
Here’s the overview of our pagination component:-
Component will accept two inputs from author, one being title of component and other being path from where it has to read pages. Let’s say the path you have give is /content/geometrixx-media/en now it will select all pages having node type as cq:Page . Type of query you want to perform can be easily changed. Now based on the search result it gets, paginations will be created on page. It uses selector based approach, once you click next page or any number you can notice selector will be added on URL.
Operations performed by each modules:-
1. Sling Model: It adapts the pages as SlingHttprequest thus we can easily retrieve selector parameter.
2. Query Builder: Based on the selector received on step it queries the JCR.
3. JavaScript Use API: With the help of number of results it create pagination links.
4. Sightly: As usual its used as View to render everything to user.
Let’s get started with authoring our component…
1. Use the component name “Sightly Pagination” and drag and drop it onto page
2. Author the two required fields. One is the title displayed on top of page and other being the root page.
3. Once you have submitted that component output can be seen on page
First section
Mid Section
Invalid Selector
Time to take a look at code…
When dialog is submitted request goes to sling model class which adapts itself as SlingHttpServletRequest.class
package com.sightlypagination.core.models;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jcr.Session;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Source;
import org.apache.sling.settings.SlingSettingsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.day.durbo.DurboInput.Node;
@Model(adaptables = SlingHttpServletRequest.class)
public class HelloWorldModel {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
SlingHttpServletRequest request;
private String message;
private String sel = null;
private List < SimplePage > pageList = null;
SimplePage page = null;
private List < String > file;
@Inject
@Source("osgi-services")
PaginationInterface service;
@PostConstruct
protected void init() {
try {
pageList = new ArrayList < SimplePage > ();
Session session = request.getResource().getResourceResolver()
.adaptTo(Session.class);
ValueMap node = request.getResource().getValueMap();
String path = node.get("text", String.class);
if (request != null) {
List < String > selectors = Arrays.asList(request
.getRequestPathInfo().getSelectors());
if (selectors.size() > 0)
this.sel = selectors.get(0);
else
this.sel = "0";
this.file = service.getPaginationData(path, String.valueOf(5),
this.sel);
this.message = service.getMatches();
for (String s: this.file) {
page = new SimplePage();
String title = session.getNode(s + "/jcr:content")
.getProperty("jcr:title").getString();
page.setPath(s);
page.setTitle(title);
pageList.add(page);
}
}
} catch (Exception e) {
logger.info("Exception:" + e.getMessage());
}
}
public List < String > getFiles() {
return this.file;
}
public String getMessage() {
return this.message;
}
public List < SimplePage > getPage() {
return this.pageList;
}
}
Our sling model injects OSGI Service and @PostConstruct method gets called once all the injections are done.
Now this method is very important from implementation point of view. Its checks for the selector which is further passed to our OSGI service which uses Query Builder to get the data. Returned data is put in list with the help of class SimplePage and returned to Sightly File. sightly-pagination.html files displays all the data on the page.
The pagination you are seeing on the page are shown with the help of our sightly-pagination.js which uses JavaScript use API.
"use strict";
use(function() {
try {
// setting the limit
var limit = 5;
var m = parseInt(this.matches);
var offset, p = "",
next, pages;
var selectors = new Array();
var pages = new Array();
selectors = request.getRequestPathInfo().getSelectors();
// Getting Selector
if (selectors.length != 0)
var sel = parseInt(selectors[0]);
else
var sel = 0;
var maxSel = parseInt(m / 5 + 1) - 1;
maxSel = Math.floor(maxSel - 1);
if (maxSel == -1)
maxSel = 0;
log.info("Max Selector " + maxSel);
// Previous Link
if (sel != 0 && sel < m / 5 + 1) {
p = parseInt(sel) - 1;
}
// Next link
if ((sel + 1) * 5 > m) {
next = "";
} else {
next = parseInt(sel) + 1;
}
// Need to find 5 links including adjacent links and current one
var fcount = 0;
var bcount = 0;
var flimit = 2;
var blimit = 2;
if (maxSel - sel >= 2) {
var blimit = 2;
} else {
flimit = parseInt(flimit) +
(parseInt(blimit) - (parseInt(maxSel) - parseInt(sel)));
log.info(flimit);
blimit = maxSel - sel;
}
if (parseInt(sel) - 0 < 2) {
blimit = blimit + flimit - parseInt(sel) - 0;
}
// Front
for (i = sel - 1; i >= 0; i--) {
if (fcount != flimit) {
log.info(fcount);
pages[fcount] = i;
fcount++;
}
}
for (i = parseInt(sel) + 1; i <= maxSel; i++) {
log.info("i=" + i);
if (bcount != blimit) {
pages[bcount + fcount] = i;
bcount++;
}
}
log.info(pages.length)
pages[pages.length] = parseInt(sel);
var list = [];
for (var n = 0; n < pages.length; n++) {
var x = parseInt(pages[n]);
list[n] = x;
// }
}
list.sort(function(a, b) {
return a - b
});
for (var n = 0; n < list.length; n++) {
log.info(list[n])
log.info(isNaN(list[n]));
}
var pageList = new Array();
for (var n = 0; n < list.length; n++) {
var link = [];
var x = parseInt(list[n]) + 1;
link[0] = list[n].toString();
link[1] = x.toString();
list[n] = link;
}
// Check for invalid pagination
var valid = true;
if (parseInt(sel) > parseInt(maxSel))
valid = false;
// Removing single element is it has only one page
if (list.length == 1)
list.pop();
return {
previous: p.toString(),
next: next.toString(),
pages: list,
check: valid
};
} catch (e) {
log.info(e);
}
});
Above shown code creates sectional pagination and “Next” and “Previous” links.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.