Wednesday, August 4, 2010

orderable search container in liferay by example

Liferay provide us with many good taglib out of them search container is one of them.It is widely used taglib. For simple understanding of search container please check Wiki here is the link Wiki Search Container. One thing that article is missing how to implement ordering using. For that we will follow few step and will do a simple example.
Step 1: Read the wiki article Search Container.
Step 2:Now write the below code in your jsp.

<%
PortalPreferences portalPrefs = PortletPreferencesFactoryUtil.getPortalPreferences(request);
String orderByCol = ParamUtil.getString(request, "orderByCol");

String orderByType = ParamUtil.getString(request, "orderByType");

if (Validator.isNotNull(orderByCol) && Validator.isNotNull(orderByType)) {
portalPrefs.setValue("KK_3", "kk-order-by-col", orderByCol);
portalPrefs.setValue("KK_3", "kk-order-by-type", orderByType);

} else {

orderByCol = portalPrefs.getValue("KK_3", "kk-order-by-col", "name");
orderByType = portalPrefs.getValue("KK_3", "kk-order-by-type", "asc");

}

OrderByComparator orderByComparator = AddressBookUtil.getAddressBookOrderByComparator(orderByCol, orderByType);
%>


Now I will explain what is happening we are getting the column on which we have to do ordering in orderByCol and order asc or desc in orderByType.
In line portalPrefs.setValue("KK_3", "kk-order-by-col", orderByCol);
here "KK_3" is namespace , "kk-order-by-col" is key and orderByCol is value.
In last line OrderByComparator orderByComparator = AddressBookUtil.getAddressBookOrderByComparator(orderByCol, orderByType);
For this you need to write a comparator , I have written it in com.ext.portlet.addressBook.util.AddressBookUtil and write this code


public class AddressBookUtil {

/**
*
* @param orderByCol
* @param orderByType
* @return
*/

public static OrderByComparator getAddressBookOrderByComparator(
String orderByCol, String orderByType) {

boolean orderByAsc = false;

if (orderByType.equals("asc")) {
orderByAsc = true;
}

OrderByComparator orderByComparator = null;

if (orderByCol.equals("name")) {
orderByComparator = new AddressBookNameComparator(orderByAsc);
} else if (orderByCol.equals("status")) {
orderByComparator = new AddressBookStatusComparator(orderByAsc);
}

return orderByComparator;
}

}

Now in same package write AddressBookNameComparator and AddressBookStatusComparator if you want you can write any where else and do the required imports. Below is the code for AddressBookNameComparator

public class AddressBookNameComparator extends OrderByComparator {

public static String ORDER_BY_ASC = "name ASC";

public static String ORDER_BY_DESC = "name DESC";

public AddressBookNameComparator() {
this(false);
}

public AddressBookNameComparator(boolean asc) {
_asc = asc;
}

public int compare(Object obj1, Object obj2) {
AddressBook project1 = (AddressBook) obj1;
AddressBook project2 = (AddressBook) obj2;

int value = project1.getName().toLowerCase().compareTo(
project2.getName().toLowerCase());

if (_asc) {
return value;
} else {
return -value;
}
}

public String getOrderBy() {
if (_asc) {
return ORDER_BY_ASC;
} else {
return ORDER_BY_DESC;
}
}

private boolean _asc;

}

Do the required imports .Same way you can do for other columns.
Step 3: Use the SearchContainer taglib.

<liferay-ui:search-container
emptyResultsMessage="No Result Found"
orderByCol="<%= orderByCol %>"
orderByType="<%= orderByType %>"
>
<liferay-ui:search-container-results results="<%= AddressBookLocalServiceUtil.getAddressBookList(searchContainer.getStart(), searchContainer.getEnd(),orderByComparator)%>">
total="<%= AddressBookLocalServiceUtil.getAddressBookCount() %>"
/>
<liferay-ui:search-container-row classname="com.ext.portlet.addressBook.model.AddressBook" escapedmodel="<%= true %>">
keyProperty="bookId"
modelVar="addressBook"
>


<liferay-ui:search-container-column-text name="name" orderable="<%= true %>" orderableproperty="name">
>

<%= addressBook.getName() %>

</liferay-ui:search-container-column-text>

<liferay-ui:search-container-column-text name="status" orderable="<%= true %>" orderableproperty="status" property="status">
/>

</liferay-ui:search-container-column-text>


<liferay-ui:search-iterator />
</liferay-ui:search-container-row></liferay-ui:search-container-results>
That is all about orderable search container.If you have read the wiki article then you will easily understand this.

HTH

13 comments:

Anonymous said...

great post! Thanks

Kapeas said...

Thank you. Great article. Finally got it to work. It would be really useful if you could also append some info about the LocalServiceImpl modifications, because I think my changes are a bit sloppy and I could use some extra ideas :D. Thanks again. Great post. Bookmarked.

Anonymous said...

Good article and great help

As "Kapeas" said please add some information about LocalServiceImpl, it will make last steps more easy.

Unknown said...

You can get basic info of service layer in liferay from this post
http://kamalkantrajput.blogspot.com/2009/08/using-json-in-liferay.html

Venka said...

hi... can u post some basic needs for liferay development

Anna said...

Hi kamal,

Thanks for your wonderful post. I think this can help me in sorting custom attributes in my directory hook plugin. I am beginner and have never used ext myself. Can you help me what I should do, maybe with a folder structure. I have some artivle explaingin ext. But can you give me a simple ext sample.

Regards,
Smile

Unknown said...

@anna:which version of Liferay you are using

Anonymous said...

hi all,
can anyone tell me how to sort cusotm fields in directory portlet.

Arun said...

Thanks for gr8 guide for orderable search container in liferay.

Just to mention one missing bit: To make step 3) working one need define : getAddressBookList(int start, int end, OrderByComparator orderByComparator) method in AddressBookLocalServiceImpl and regenerate the Service.

Laxman Rana said...

Hi kamal,
i like ur post and tried it.Every thing is working fine..here sorting is done on single column...Now i want to do for multiple column headers.how to achieve this??
can u help me out.....

Unknown said...

Hi Laxman,
When we click on header that time only on based on header value ordering is done not sorting. Do you require ordering on multiple column.

Anonymous said...

Kamal,
Nice post,
Just wanted to know what needs to be done if we want to iterate though our custom objects list? as there will be no liferay model class we can use in that case.

Unknown said...

There are few ways one of the common way to create a in between model layer having all custom object details.