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/OR
based 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