Saturday, February 14, 2015

Infinite Scroll

How To Use Infinite Scroll On Dynamic Data In Liferay

Version:Liferay 6.2

*In this example JournalArticle table is used for data, you can use any table for getting data.

Steps:

1> Create one custom portlet with named  "scroll" or  "infinite scroll" or anything as per you requirment naming convention

2>Paste below code in portlet jsp page

view.jsp
---------

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui"%>
<portlet:defineObjects />

<script type="text/javascript" src="https://rawgithub.com/asotog/y-commons/master/build/gallery-y-common-infinite-scroll/gallery-y-common-infinite-scroll-min.js"></script>

<div class = "images-infinite-grid-view">
//content will be placed inside this div after getting content from database.
</div>

<script type="text/javascript">
    AUI().use('gallery-y-common-infinite-scroll', 'datatype-xml', 'transition', 'liferay-portlet-url', 'aui-io-request','aui-base', function (A) {

        var PORTLET_ID = 'infinite_WAR_azharportlet';
        var resourceURL = Liferay.PortletURL.createResourceURL();
        resourceURL.setPortletId(PORTLET_ID);
   
        var offset = 5;
        /* js configuration */
        var itemTemplate = '{content}';
                            
       /* infinite scroll instance */
        var infiniteScroll = new A.InfiniteScroll({
           
            requestCustomData: function (callback) {
               
                var data = Liferay.Util.ns("_"+PORTLET_ID+"_", {
                    'start': this.currentOffset - offset,
                    'end': this.currentOffset,
                });
           
                A.io.request(resourceURL.toString(),{
                    method: 'GET',
                    dataType: 'json',
                    data: data,
                    on : {
                        success:  function(){
                            var entries = this.get('responseData');
                            callback(entries);
                       }
                    }
                });  
            },
            container: A.one('div.images-infinite-grid-view'),
            itemTemplate: itemTemplate,
            initialize: true,
            offset: 5,
            itemPreProcessor: function(item) {
               
                return item;
            }
        });
       
        infiniteScroll.on('infinite-scroll:loading', function (e) {
           alert("loading");  
        });
        infiniteScroll.on('infinite-scroll:finished', function (e) {
          
            infiniteScroll.get('container').all('div').transition({
                easing: 'ease-out',
                duration: 1,
                opacity: 1
            });
           
        });
        infiniteScroll.on('infinite-scroll:no-more-results', function (e) {
          
             alert("no more result to show");
             infiniteScroll.get('container').append("No More Content to show..");
           
        });
    });
    </script>

3> Paste below code in portlet controller(java file)

scroll.java
------------

package com.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.kernel.dao.orm.Criterion;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.OrderFactoryUtil;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.OrderByComparatorFactory;
import com.liferay.portal.kernel.util.OrderByComparatorFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portlet.journal.model.JournalArticle;
import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

/**
 * Portlet implementation class Infinite
 */
public class Infinite extends MVCPortlet {

   
    @Override
    public void serveResource(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws IOException,
            PortletException {
       
        int start = ParamUtil.getInteger(resourceRequest, "start");
        int end = ParamUtil.getInteger(resourceRequest, "end");
       
        int totalCount = 0;
        List total = null;
        try {
            total = JournalArticleLocalServiceUtil.
                    dynamicQuery(prepareDynamicQuery(false, start, end));
        } catch (SystemException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
       
        if(Validator.isNotNull(total))
            totalCount = GetterUtil.getInteger(total.get(0));
       
       
        if(totalCount < end )
            end = totalCount;
   
        if(start > end)
            start = end;

        ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(WebKeys.THEME_DISPLAY);
       
        JSONArray jsonarray = JSONFactoryUtil.createJSONArray();
       
        try {
            List<JournalArticle> dynamicarticles = JournalArticleLocalServiceUtil.
                    dynamicQuery(prepareDynamicQuery(true, start, end));
       
            for(JournalArticle dynamicarticle:dynamicarticles){
                   
                JSONObject json = JSONFactoryUtil.createJSONObject();
               
                    String content = StringPool.BLANK;
                    try {
                            content = JournalArticleLocalServiceUtil.getArticleContent(dynamicarticle, "", "", themeDisplay.getLanguageId(), themeDisplay);
                            json.put("content", content);
                            jsonarray.put(json);
                       
                    } catch (PortalException e) {
                        e.printStackTrace();
                    }   
            }
            PrintWriter pw = resourceResponse.getWriter();
            pw.write(jsonarray.toString());           
        } catch (SystemException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   
    private DynamicQuery prepareDynamicQuery(boolean wantLimit, int start , int end) {
       
        DynamicQuery query = DynamicQueryFactoryUtil.forClass(
                JournalArticle.class, "articleParent",
                PortalClassLoaderUtil.getClassLoader());
       
        DynamicQuery subQuery = DynamicQueryFactoryUtil
                .forClass(JournalArticle.class, "articleSub",
                        PortalClassLoaderUtil.getClassLoader())
                .add(PropertyFactoryUtil.forName("articleId").eqProperty(
                        "articleParent.articleId"))
                .setProjection(ProjectionFactoryUtil.max("id"));
       
        query = query.addOrder(OrderFactoryUtil.desc("modifiedDate"));

        query = query.add(PropertyFactoryUtil.forName("id").eq(subQuery));
       
       
        // below line can be used for getting custom type of article, like in this case custom types are TOPIC And ARTICLE.
        //For testing you can use default article type like General, test etc.
        query.add(RestrictionsFactoryUtil.or(RestrictionsFactoryUtil.eq("type", new String("TOPIC"))
                , RestrictionsFactoryUtil.eq("type", new String("ARTICLE"))));
   
        if (wantLimit) {
            query.setLimit(start, end);
        } else {
            query.setProjection(ProjectionFactoryUtil.rowCount());
        }

        return query;
         }

}

Sunday, February 1, 2015

Create Custom Login Portlet In Liferay

Create Custom Login Portlet In Liferay


*Liferay 6.2 version

1.  Before start portlet creation add below property in portal-ext.properties file,

     session.enable.phishing.protection=false

     then start/restart server.

2.    Now create a custom portlet name called "login" or  "custom login" or "xyz" as per your requirement naming convention.

3. Add below lines in liferay-portlet.xml file

        <instanceable>false</instanceable>
        <private-session-attributes>false</private-session-attributes>

 4. In view.jsp paste below code
<%@page import="com.liferay.portal.kernel.util.StringPool"%>
<%@page import="com.liferay.portal.kernel.util.Validator"%>
<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="javax.portlet.ActionRequest"%>
<%@page import="javax.portlet.PortletURL"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui"%>
<portlet:defineObjects />


<%
String passwordNotMatched = Validator.isNotNull((String)request.getAttribute("PASSWORD_NOT_MATCHED")) ? (String)request.getAttribute("PASSWORD_NOT_MATCHED") : StringPool.BLANK;
String emailNotExist = Validator.isNotNull((String)request.getAttribute("EMAIL_NOT_EXIST")) ? (String)request.getAttribute("EMAIL_NOT_EXIST"): StringPool.BLANK;

PortletURL loginURL = renderResponse.createActionURL();
loginURL.setParameter(ActionRequest.ACTION_NAME, "loginUser");
%>

<%
if(Validator.isNotNull(emailNotExist)){%>
<div style="color:red;"><%=emailNotExist%></div>
<%}else if(Validator.isNotNull(passwordNotMatched)){%>
<div style="color:red;"><%=passwordNotMatched%></div>
<%}%>

<aui:form method="post" action="<%=loginURL.toString() %>" id="aui-login-form">
    <div class="col-lg-4 col-a-vik col-b-vik">
        <span style="color:black;font-size: 10.5px;" id="label-email">Email Id</span>
            <div class="input-group">
            <input class="form-control" type="text" placeholder="Email Id"  name="<portlet:namespace/>emailId" id="<portlet:namespace/>emailId" style="margin-bottom: 0px;">
            </div>
    </div>
    <div class="col-lg-4 col-a-vik col-b-vik">
        <span style="color:black;font-size: 10.5px;" id="label-pwd">Password</span>
            <div class="input-group">
            <input class="form-control" type="password" placeholder="password" id="<portlet:namespace/>password" name="<portlet:namespace/>password" style="margin-bottom: 0px;">
            </div>
    </div>
    <div class="col-lg-4 col-a-vik col-b-vik">
            <aui:button type="submit" id="btn-submit" style="background:#EE9400" value="Log In"/>
    </div>
</aui:form>

5. In portlet controller/action class paste below code

package com.test;

import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.CompanyConstants;
import com.liferay.portal.model.User;
import com.liferay.portal.service.PasswordTrackerLocalServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Portlet implementation class Login
 */
public class Login extends MVCPortlet {

    public void loginUser(ActionRequest actionRequest,
            ActionResponse actionResponse) throws IOException, PortletException{
           
            System.out.println("login action called");
           
            String email = ParamUtil.getString(actionRequest, "emailId").trim();
            String password = ParamUtil.getString(actionRequest, "password").trim();
           
            ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);    
            HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest);
            HttpServletResponse response = PortalUtil.getHttpServletResponse(actionResponse);
           
            User userDetail = null;
            try {
                userDetail = UserLocalServiceUtil.fetchUserByEmailAddress(themeDisplay.getCompanyId(), email);
                if(Validator.isNull(userDetail)){
                actionRequest.setAttribute("EMAIL_NOT_EXIST", "Account not exist with email");
                  }else{
                boolean passwordMatched = PasswordTrackerLocalServiceUtil.isSameAsCurrentPassword(userDetail.getUserId(), password);
                if(!passwordMatched){
                actionRequest.setAttribute("PASSWORD_NOT_MATCHED", "Please Enter Correct Password");
                }else{
                // if user exist with provide email and given password matched with user database password
                ClassLoader pcl = PortalClassLoaderUtil.getClassLoader();
                        Class lClass = pcl.loadClass("com.liferay.portlet.login.util.LoginUtil");
                        java.lang.reflect.Method method = lClass.getDeclaredMethod("login", HttpServletRequest.class, HttpServletResponse.class, String.class, String.class, Boolean.TYPE, String.class);
                        method.invoke(null, request, response, email, password, false, CompanyConstants.AUTH_TYPE_EA);
                       
                       //redirection after login...
                       String screenName = userDetail.getScreenName();
                       String portalURL = PortalUtil.getPortalURL(actionRequest);
                       if(PortalUtil.isOmniadmin(userDetail.getUserId()))
                       {
                           System.out.println("admin logged in, redirecting to admin  specified private page");
                           actionResponse.sendRedirect(portalURL + "/user/"+ screenName+"/adminuser");
                       } else {
                           System.out.println("normal user logged in, redirecting to private page specified for normal user");
                           actionResponse.sendRedirect(portalURL + "/user/" + screenName +"/normaluser");      
                       }
                }
                 }
              }catch (Exception e) {
                    e.printStackTrace();
              }
     }
   
}


*change pages name  given above for user redirection after login as per your requirement.

Now deploy this portlet , after deploying add this portlet on any page  try to login using admin /normal user credential .