Introduction:
Liferay Search form is Liferay UI component to design search form in liferay portlet development. This is simple JSTL tag we can use in JPS pages. In real time when we want implement search feature to portlet application then we can use the tag.
Generally we will use Search From with Liferay search container. We will enclose liferay search form in search container so that when we search data the result can be displayed in the grid.
Go through following link for more about search container
Liferay Search Form:
Search form we can enclose in the search container and it initially display single text box and we can design many input elements inside search form so that it will be inside toggle. We can open toggle and close
When we open toggle then we can see all input elements enclosed by the tag.
The following is declaration and we need pass jsp path there we will defined all input elements.
<liferay-ui:search-form page="/html/jsps/student_search.jsp" servletContext="<%= application %>" /> |
Search form as follows (/html/jsps/student_search.jsp)
<%@ include file="init.jsp" %> <% SearchContainer searchContainer = (SearchContainer)request.getAttribute("liferay-ui:search:searchContainer"); DisplayTerms displayTerms = searchContainer.getDisplayTerms(); %> <liferay-ui:search-toggle buttonLabel="Student Search" displayTerms="<%= displayTerms %>" id="toggle_id_student_search"> <aui:input label="First Name" name="firstName" value="<%=firstName %>" /> <aui:input label="Last Name" name="lastName" value="<%=lastName %>" /> <aui:input label="studentAge" name="studentAge" value="<%= studentAge %>" /> <aui:select name="studentGender"> <aui:option label="Male" value="1"></aui:option> <aui:option label="Female" value="0"></aui:option> </aui:select> <aui:input label="studentAddress" name="studentAddress" value="<%= studentAddress %>" /> </liferay-ui:search-toggle> |
Note:
We use toggle tag which will wrap the all the input elements.
Implementing Search with Search container
Generally in the development we will use search form with liferay search container and this tag will be enclose by search container tag one more thing search container tag should be within form tag.
The following syntax
<aui:form> <liferay-ui:search-container/> <liferay-ui:search-form> <liferay-ui:search-container-results/> <liferay-ui:search-container-row/> <liferay-ui:search-container-column-text/> </liferay-ui:search-container-row> <liferay-ui:search-iterator/> </liferay-ui:search-container> </aui:form> |
Steps to implementation:
- Declare from tag with form create search container and its child tags.
- Implement search logic in respective Service Implementation class
- Pass search terms to Service method and fetch the result and pass to search container.
Declare from tag with form create search container and its child tags.
<aui:form> <liferay-ui:search-container/> <liferay-ui:search-form> <liferay-ui:search-container-results/> <liferay-ui:search-container-row/> <liferay-ui:search-container-column-text/> </liferay-ui:search-container-row> <liferay-ui:search-iterator/> </liferay-ui:search-container> </aui:form> |
Implement search logic in respective Service Implementation class
Based on search key word we need to implement logic in respective service implementation class.
Assume we are using Student data so we need to implement search logic in StudentLocalServiceImpl.java and we need run the service builder.
In the search we have implemented the Liferay Dynamic Query API and you can have more knowledge in Liferay wikis or liferay documentation.
The following is search implementation logic in StudentLocalServiceImpl.java
public class StudentLocalServiceImpl extends StudentLocalServiceBaseImpl { public List getSerachStudents(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch, int start, int end, OrderByComparator orderByComparator) throws SystemException { DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch); return StudentLocalServiceUtil.dynamicQuery(dynamicQuery, start, end, orderByComparator); } public int getSearchStudentsCount(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch) throws SystemException { DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch); return (int)StudentLocalServiceUtil.dynamicQueryCount(dynamicQuery); } protected DynamicQuery buildStudentDynamicQuery(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch) { Junction junction = null; if(andSearch) junction = RestrictionsFactoryUtil.conjunction(); else junction = RestrictionsFactoryUtil.disjunction(); if(Validator.isNotNull(firstName)) { Property property = PropertyFactoryUtil.forName("firstName"); String value = (new StringBuilder("%")).append(firstName).append("%").toString(); junction.add(property.like(value)); } if(Validator.isNotNull(lastName)) { Property property = PropertyFactoryUtil.forName("lastName"); String value = (new StringBuilder("%")).append(lastName).append("%").toString(); junction.add(property.like(value)); } if(studentAge > 0) { Property property = PropertyFactoryUtil.forName("studentAge"); junction.add(property.eq(Integer.valueOf(studentAge))); } if(studentGender > 0) { Property property = PropertyFactoryUtil.forName("studentGender"); junction.add(property.eq(Integer.valueOf(studentGender))); } if(Validator.isNotNull(studentAddress)) { Property property = PropertyFactoryUtil.forName("studentAddress"); String value = (new StringBuilder("%")).append(studentAddress).append("%").toString(); junction.add(property.like(value)); } DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(Student.class, getClassLoader()); return dynamicQuery.add(junction); } } |
Pass search terms to Service method and fetch the result and pass to search container
Search URL:
We need search URL and it should carry search container JSP page otherwise it will navigate portlet default view page after search button click and it is simple liferay render URL.
<liferay-portlet:renderURL varImpl="studentSearchURL"> <portlet:param name="mvcPath" value="/html/jsps/student_search_container.jsp" /> </liferay-portlet:renderURL> |
In the search form we have toggle open and close when we open toggle then we will input all search values so that our search logic fetch the result based on search terms.
We have two kind of search option in toggle one for match any key word and match all keywords.
Match ANY we will use OR operator in the search logic
Match ALL we will use AND operator in search logic
When we open toggle then it wills treats as Advance search and the result should be fetch based on all columns and its values with operators like AND/ORbased on user input.
If the toggle off then there only input box so that user can give anything in the box then we will use this key word to search data on behalf of all columns in the table.
Calling of search method and fetch the data all the logic should be present inside search-container-result tag.
The following example code you can understand
<liferay-ui:search-container-results> <% DisplayTerms displayTerms =searchContainer.getDisplayTerms(); if (displayTerms.isAdvancedSearch()) { total = StudentLocalServiceUtil.getSearchStudentsCount(firstName, lastName, studentAge, studentGender, studentAddress,displayTerms.isAndOperator()); searchContainer.setTotal(total); searchContainer.setResults(StudentLocalServiceUtil.getSerachStudents(firstName, lastName,studentAge,studentGender,studentAddress,displayTerms.isAndOperator(), searchContainer.getStart(), searchContainer.getEnd(), new StudentNameComparator())); }else { String searchkeywords = displayTerms.getKeywords(); String numbesearchkeywords = Validator.isNumber(searchkeywords) ? searchkeywords : String.valueOf(0); total = StudentLocalServiceUtil.getSearchStudentsCount (firstName,lastName, studentAge, studentGender, studentAddress,displayTerms.isAndOperator()); searchContainer.setResults(StudentLocalServiceUtil.getSerachStudents (searchkeywords,searchkeywords,Integer.parseInt(numbesearchkeywords), Integer.parseInt(numbesearchkeywords), searchkeywords,false, searchContainer.getStart(), searchContainer.getEnd(), new StudentNameComparator())); } %> </liferay-ui:search-container-results> |
Iterator URL
We already know search container need iterator URL so that when we change the page it will use Iterator URL.
When we apply search we need to maintain all search keywords and its values as URL parameters otherwise search result will be changes.
For each page change it will get the search key words values from Iterator URL so that it can pass to respective search methods which are written inside search-container-result tag.
<liferay-portlet:renderURL varImpl="iteratorURL"> <portlet:param name="firstName" value="<%= firstName %>" /> <portlet:param name="lastName" value="<%= lastName %>" /> <portlet:param name="studentAge" value="<%= String.valueOf(studentAge) %>" /> <portlet:param name="studentGender" value="<%= String.valueOf(studentGender) %>" /> <portlet:param name="studentAddress" value="<%= String.valueOf(studentAddress) %>" /> <portlet:param name="mvcPath" value="/html/jsps/student_search_container.jsp" /> </liferay-portlet:renderURL> |
Note:
We already implement search logic in respective service implementation class.
Complete code for Example
Search container JSP page (/html/jsps/student_search_container.jsp)
<%@page import="com.meera.dbservice.model.Student"%> <%@page import="com.meera.liferaymvc.StudentNameComparator"%> <%@page import="com.meera.dbservice.service.StudentLocalServiceUtil"%> <%@ include file="init.jsp" %> <a href="<portlet:renderURL />">«Home</a> <div class="separator"></div> <liferay-portlet:renderURL varImpl="studentSearchURL"> <portlet:param name="mvcPath" value="/html/jsps/student_search_container.jsp" /> </liferay-portlet:renderURL> <aui:form action="<%=studentSearchURL %>" method="get" name="studentForm"> <liferay-portlet:renderURLParams varImpl="studentSearchURL" /> <liferay-portlet:renderURL varImpl="iteratorURL"> <portlet:param name="firstName" value="<%= firstName %>" /> <portlet:param name="lastName" value="<%= lastName %>" /> <portlet:param name="studentAge" value="<%= String.valueOf(studentAge) %>" /> <portlet:param name="studentGender" value="<%= String.valueOf(studentGender) %>" /> <portlet:param name="studentAddress" value="<%= String.valueOf(studentAddress) %>" /> <portlet:param name="mvcPath" value="/html/jsps/student_search_container.jsp" /> </liferay-portlet:renderURL> <liferay-ui:search-container displayTerms="<%= new DisplayTerms(renderRequest) %>" emptyResultsMessage="there-are-no-students" headerNames="firstName,lastName,studentAge, studentGender,studentAddress" iteratorURL="<%= iteratorURL %>" > <liferay-ui:search-form page="/html/jsps/student_search.jsp" servletContext="<%= application %>" /> <liferay-ui:search-container-results> <% DisplayTerms displayTerms =searchContainer.getDisplayTerms(); if (displayTerms.isAdvancedSearch()) { total = StudentLocalServiceUtil.getSearchStudentsCount(firstName, lastName, studentAge, studentGender, studentAddress,displayTerms.isAndOperator()); searchContainer.setTotal(total); searchContainer. setResults(StudentLocalServiceUtil.getSerachStudents(firstName, lastName,studentAge,studentGender, studentAddress,displayTerms.isAndOperator(), searchContainer.getStart(), searchContainer.getEnd(), new StudentNameComparator())); }else { String searchkeywords = displayTerms.getKeywords(); String numbesearchkeywords = Validator.isNumber(searchkeywords) ? searchkeywords : String.valueOf(0); total = StudentLocalServiceUtil.getSearchStudentsCount(firstName,lastName, studentAge, studentGender, studentAddress,displayTerms.isAndOperator()); searchContainer.setResults(StudentLocalServiceUtil. getSerachStudents(searchkeywords, searchkeywords,Integer.parseInt(numbesearchkeywords), Integer.parseInt(numbesearchkeywords), searchkeywords,false, searchContainer.getStart(), searchContainer.getEnd(), new StudentNameComparator())); } %> </liferay-ui:search-container-results> <liferay-ui:search-container-row className="Student" keyProperty="studentId" modelVar="currentStudent"> <liferay-portlet:renderURL varImpl="rowURL"> <portlet:param name="backURL" value="<%= currentURL %>" /> <portlet:param name="mvcPath" value="/html/jsps/display_student.jsp" /> <portlet:param name="redirect" value="<%= currentURL %>" /> <portlet:param name="studentId" value="<%= String.valueOf(currentStudent.getStudentId()) %>" /> </liferay-portlet:renderURL> <liferay-ui:search-container-column-text href="<%= rowURL %>" name="firstName" property="firstName" /> <liferay-ui:search-container-column-text href="<%= rowURL %>" name="lastName" property="lastName" /> <liferay-ui:search-container-column-text href="<%= rowURL %>" name="studentAge" property="studentAge" /> <liferay-ui:search-container-column-text href="<%= rowURL %>" name="studentGender" value='<%=currentStudent.getStudentGender()==1?"Male":"Female"%>' /> <liferay-ui:search-container-column-text href="<%= rowURL %>" name="studentAddress" property="studentAddress"/> </liferay-ui:search-container-row> <liferay-ui:search-iterator searchContainer="<%=searchContainer %>" /> </liferay-ui:search-container> </aui:form> |
Search from JSP(/html/jsps/student_search.jsp)
<%@ include file="init.jsp" %> <% SearchContainer searchContainer = (SearchContainer)request.getAttribute("liferay-ui:search:searchContainer"); DisplayTerms displayTerms = searchContainer.getDisplayTerms(); %> <liferay-ui:search-toggle buttonLabel="Student Search" displayTerms="<%= displayTerms %>" id="toggle_id_student_search"> <aui:input label="First Name" name="firstName" value="<%=firstName %>" /> <aui:input label="Last Name" name="lastName" value="<%=lastName %>" /> <aui:input label="studentAge" name="studentAge" value="<%= studentAge %>" /> <aui:select name="studentGender"> <aui:option label="Male" value="1"></aui:option> <aui:option label="Female" value="0"></aui:option> </aui:select> <aui:input label="studentAddress" name="studentAddress" value="<%= studentAddress %>" /> </liferay-ui:search-toggle> |
Init.jsp page maintain all Tag lib URL declarations, Common Imports and Common Variables for all JSP pages
Init.jsp (html/jsps/init.jsp)
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %> <%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %><%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %><%@ taglib uri="http://liferay.com/tld/security" prefix="liferay-security" %><%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %><%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %><%@ taglib uri="http://liferay.com/tld/util" prefix="liferay-util" %> <portlet:defineObjects /> <liferay-theme:defineObjects /> <% String currentURL = PortalUtil.getCurrentURL(request); String firstName = ParamUtil.getString(request, "firstName"); String lastName = ParamUtil.getString(request, "lastName"); int studentAge = ParamUtil.getInteger(request, "studentAge"); int studentGender = ParamUtil.getInteger(request, "studentGender"); String studentAddress = ParamUtil.getString(request, "studentAddress");%> |
Search Implementation service class (StudentLocalServiceImpl.java)
package com.meera.dbservice.service.impl; import java.util.List; import com.liferay.portal.kernel.dao.orm.DynamicQuery; import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil; import com.liferay.portal.kernel.dao.orm.Junction; import com.liferay.portal.kernel.dao.orm.Property; import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil; import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.Validator; import com.meera.dbservice.model.Student; import com.meera.dbservice.service.StudentLocalServiceUtil; import com.meera.dbservice.service.base.StudentLocalServiceBaseImpl; public class StudentLocalServiceImpl extends StudentLocalServiceBaseImpl { public List getSerachStudents(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch, int start, int end, OrderByComparator orderByComparator) throws SystemException { DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch); return StudentLocalServiceUtil.dynamicQuery(dynamicQuery, start, end, orderByComparator); } public int getSearchStudentsCount(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch) throws SystemException { DynamicQuery dynamicQuery = buildStudentDynamicQuery(firstName, lastName, studentAge, studentGender, studentAddress, andSearch); return (int)StudentLocalServiceUtil.dynamicQueryCount(dynamicQuery); } protected DynamicQuery buildStudentDynamicQuery(String firstName,String lastName,int studentAge,int studentGender,String studentAddress,boolean andSearch) { Junction junction = null; if(andSearch) junction = RestrictionsFactoryUtil.conjunction(); else junction = RestrictionsFactoryUtil.disjunction(); if(Validator.isNotNull(firstName)) { Property property = PropertyFactoryUtil.forName("firstName"); String value = (new StringBuilder("%")).append(firstName).append("%").toString(); junction.add(property.like(value)); } if(Validator.isNotNull(lastName)) { Property property = PropertyFactoryUtil.forName("lastName"); String value = (new StringBuilder("%")).append(lastName).append("%").toString(); junction.add(property.like(value)); } if(studentAge > 0) { Property property = PropertyFactoryUtil.forName("studentAge"); junction.add(property.eq(Integer.valueOf(studentAge))); } if(studentGender > 0) { Property property = PropertyFactoryUtil.forName("studentGender"); junction.add(property.eq(Integer.valueOf(studentGender))); } if(Validator.isNotNull(studentAddress)) { Property property = PropertyFactoryUtil.forName("studentAddress"); String value = (new StringBuilder("%")).append(studentAddress).append("%").toString(); junction.add(property.like(value)); } DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(Student.class, getClassLoader()); return dynamicQuery.add(junction); } } |
Download Search Container Portlet
Environment:
Liferay IDE 2.x+Eclipse (Kepler) +Liferay Plugins SDK 6.2+Tomcat 7.x Liferay Portal Bundle
Deployment and its Working.
Download portlet you can source or war file to deploy into liferay portal as your convenient.
Once portlet successfully deployed drag the portlet in any desired page. Portlet is available in sample category.
In the portlet page you can click on Student Search link then you can see the search container with search from.
Portlet Screens:
Default Page
Search Page
Search with toggle advanced search
Reference Links
Author
0 comments:
Post a Comment