Lazy loading Portlet
This is a solution to develop a portlet with a lazy loading mode. It is useful when you have a lot of portlets in your page and you don`t want to increase the loading time of the page. An interesting point is to save if the user closed or opened the portlet. Like that the next time he comes on the page the portlet will be open or close.
The following example doesn't load the content of the portlet until you click on the link on the portlet (you need JQuery in your portlet or your theme).
This is the code for our controller:
Below, this is the controller class that implements this behaviour:
@Controller @RequestMapping("VIEW") public class LazyLoadingController{ @ModelAttribute("portletIsClosed") public Boolean getPreferences(PortletRequest request) throws SystemException, PortalException { ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY); PortalPreferences portalPreferences = PortletPreferencesFactoryUtil.getPortalPreferences(themeDisplay.getUserId(), themeDisplay.isSignedIn()); try{ return Boolean.valueOf(portalPreferences.getValue("NS-PORTLET-LAZY-LOADING", "portletIsClosed")); }catch(Exception e){ return false; } } @RenderMapping public String showMainView(Model model, RenderRequest request, RenderResponse response) throws Exception { return "view"; } @RenderMapping(params = "action=showDatas") public String showDatasView(Model model, RenderRequest request, RenderResponse response) throws Exception { return "list-datas"; } @ActionMapping(params = "action=showDatas") public void showDatas(ActionRequest request, ActionResponse response, Model model, boolean portletIsClosed, boolean init) throws Throwable { ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY); PortalPreferences portalPreferences = PortletPreferencesFactoryUtil.getPortalPreferences(themeDisplay.getUserId(), themeDisplay.isSignedIn()); portalPreferences.getPortalPreferences(request).setValue("NS-PORTLET-LAZY-LOADING", "portletIsClosed", String.valueOf(portletIsClosed)); if(!init){ model.addAttribute("result", "Data loading by Ajax"); } response.setRenderParameter("action", "showDatas"); } }
The view.jsp page to render the main page and implements the ajax call:
<portlet:actionURL var="ajaxURL" windowState="EXCLUSIVE">
<portlet:param name="action" value="showDatas" />
</portlet:actionURL>
<script>
var portletIsClosed = ${portletIsClosed};
var init = false;
// When you load the page
$(document).ready(function() {
if(!portletIsClosed){
showDatas();
} else{
$('#listdatas').hide();
}
});
// To get data and show them in the page if the portlet is opened
function showDatas(){
var container = $('#listdatas');
if(portletIsClosed){
portletIsClosed = false;
container.show();
} else if(!portletIsClosed && init){
portletIsClosed = true;
container.hide();
$.post( "${ajaxURL}", {portletIsClosed: portletIsClosed, init: init}, function( data ) {
if(!init){
container.html(data);
init = true;
</script>
<style>
#toggler{
height: 20px;
background-color: grey;
</style>
<div id="main">
<div id="toggler"><a href="#" onclick="showDatas()">My lazy loading portlet [open/close]</a></div>
<div id="listdatas">
<img src="${themeDisplay.pathThemeImages}/myTheme/img/loading.gif">
</div>
The list-datas.jsp page to render only the html for the datas to include in the main page:
<div id="results">
${result}