Liferay is introduced Lexicon UI framework to standardize
all UI components across the Liferay portal. It is a design language to develop
UI components. Liferay 7.2/DXP is following the Lexicon standards to design UI
elements. All standards are aligned with latest bootstrap UI framework and its standards.
Clay is one of the web implementation for Lexicon and
it contains many UI components that can be used in Liferay application
development.
Liferay is implemented clay tag library to create UI
components which is based on Clay UI web implementation. Tag libraries are very
useful to create reusable UI components by simply placing tags.
These Clay tag libraries can be used in JSP and Freemarker
templates.
Clay ag libraries are implemented in “frontend-taglib-clay”
OSGi module and it is one of the Liferay 7.2/DXP portal module available by
default.
Clay Talib Implementation Module source is available
here.
Usage in JSP Pages.
Use following Taglib directive in JSP page. Usually init.jsp
is best place to keep the taglibs.
<%@
taglib uri="http://liferay.com/tld/clay" prefix="clay"
%>
|
Liferay is also provided these tags as macro to use in
FreeMarker theme templates and Webcontent templates.
Following is usage of Clay Macros in FreeMarker theme
templated and Webcontent templates.
<@clay["tag-name"]
attribute="string value" attribute=10 />
|
This article will focus on some of clay form elements
that is implemented by Clay Taglib.
The following are Form UI elements available in Clay Taglib.
- Clay Checkbox
- Clay Radio
- Clay Selector
These are the available Taglib and each tag have many
attributes to use in JSP pages or freemarker templates.
Clay Checkbox
Sample usage in JSP page
<clay:checkbox
label="Music" name="<%=curPortletNameSpace+"hobbies"%>"
showLabel="<%= true %>" value="Music"/>
|
Important Attributes
checked:
It take Boolean value. If it is true then by default it will be selected.
disabled:
It take Boolean value. If it is true then by Check will be disabled mode.
hideLabel:
Make the label is hidden for true attribute value. It takes Boolean value.
indeterminate:
Checkbox variable for multiple selection
label:
Label for checkbox.
name:
Name for checkbox. We will use this name to get value from request object.
|
Clay Radio
Sample usage in JSP page
<clay:radio
checked="<%= true %>" label="Male" name="<%=curPortletNameSpace+"gender"%>"
showLabel="<%= true %>" value="male"/>
|
Important Attributes
checked:
It take Boolean value. If it is true then by default it will be selected.
hideLabel:
Make the label is hidden for true attribute value. It takes Boolean value.
disabled:
It take Boolean value. If it is true then by Check will be disabled mode.
label:
Label for checkbox.
name:
Name for checkbox. We will use this name to get value from request object.
|
Clay Selector
Sample usage in JSP page
<clay:select
label="Country"
name="<%=curPortletNameSpace+"country"%>"
options="<%= selectOptions %>"/>
|
It is required option as List object and we need to provide
java list object
Example:
<%@page import="com.liferay.frontend.taglib.clay.servlet.taglib.util.SelectOption"
%>
<%
List<SelectOption>
selectOptions = new ArrayList<>();
selectOptions.add(new SelectOption("India",
String.valueOf("India")));
selectOptions.add(new SelectOption("US", String.valueOf("US")));
selectOptions.add(new SelectOption("UK", String.valueOf("UK")));
%>
|
Important Attributes
disabled:
It take Boolean value. If it is true then by Check will be disabled mode.
label:
The selector’s label
multiple:
Whether multiple options can be selected and accepted values true or false.
name:
Label for checkbox
|
Check here for complete tags and its attributes
Important Note:
Taglib element name should be associated with portlet
name space otherwise it will be ignored in request parameter list.
Example to get Portlet Namespace in JSP page
<%
String curPortletNameSpace =
themeDisplay.getPortletDisplay().getNamespace();
%>
|
Clay tag with portlet name space
<clay:radio
checked="<%= true %>" label="Male" name="<%=curPortletNameSpace+"gender"%>"
showLabel="<%= true %>" value="male"/>
|
Example to get value in Portlet component class
String
gender = ParamUtil.getString(actionRequest, "gender");
|
Liferay recommended to use Clay Taglib instead of AUI
Taglib. The following is note from Liferay docs.
Note:
AUI taglibs are deprecated as of Liferay Portal CE 7.1. We
recommend that you use Clay taglibs to avoid future compatibility issues.
|
Clay Taglib Example
I have provided the simple Portlet component which uses
the Clay form elements. It is rendering by Clay tags. Some of components from AUI
Taglib but you can ignore AUI tags and focus on Clay tags.
Important Points of the Example
- Init JSP page have all Taglib definitions including Clay Taglib. It also has some common objects which is used across all JSP pages. All JSP pages will include init JSP page.
- View JSP Page just have anchor tag to navigate to edit employee JSP page
- Edit employee JSP page contains the Clay Tag UI Elements.
- Once submit the form it will execute the Edit Employee Action Command. It will get values from request object and put the data in request object to render in JSP page.
- MVC Render commands will provide navigation between JSP pages.
- Once action is executed, it will navigate to view employee JSP page.
- From View Employee JSP page, we can navigate to Home page, that is view JSP page.
- We have to add one of the Taglib dependency in pom.xml or “build.gradle”. That is “com.liferay.frontend.taglib.clay”
Note:
The objective of example is just showing usage of Clay
Taglib and its not covering any other functionality.
Source Code Gradle Build
Source Code MAVEN Build
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/theme" prefix="liferay-theme" %>
<%@taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/clay" prefix="clay" %>
<liferay-theme:defineObjects />
<portlet:defineObjects />
<%@ page import="java.util.ArrayList" %>
<%@page import="java.util.HashMap" %>
<%@page import="java.util.List" %>
<%@page import="java.util.Map" %>
<%@page import="com.liferay.frontend.taglib.clay.servlet.taglib.util.SelectOption"
%>
<%
String curPortletNameSpace =
themeDisplay.getPortletDisplay().getNamespace();
%>
|
view.jsp
<%@ include file="/init.jsp" %>
<h2>Welcome to Clay Taglib Examples</h2><br/>
<portlet:renderURL var="renderEditEmployee">
<portlet:param name="mvcRenderCommandName" value="/clayform/edit_employee" />
</portlet:renderURL>
<aui:button href="<%= renderEditEmployee %>" value="Edit Employee" />
|
edit_employee.jsp
<%@ include file="/init.jsp" %>
<portlet:actionURL name="/clayfrom/edit_employee" var="editEmployeeURL" />
<%
List<SelectOption>
selectOptions = new ArrayList<>();
selectOptions.add(new SelectOption("India",
String.valueOf("India")));
selectOptions.add(new SelectOption("US", String.valueOf("US")));
selectOptions.add(new SelectOption("UK", String.valueOf("UK")));
%>
<aui:form action="<%= editEmployeeURL %>" cssClass="edit-entry" enctype="multipart/form-data" method="post" name="fm">
<aui:fieldset-group markupView="lexicon">
<aui:fieldset>
<div class="clearfix">
<label class="control-label">Gender</label>
<clay:radio checked="<%= true %>" label="Male" name="<%=curPortletNameSpace+"gender"%>" showLabel="<%= true %>" value="male"/>
<clay:radio checked="<%= true %>" label="Female" name="<%=curPortletNameSpace+"gender"%>" showLabel="<%= true %>" value="female"/>
</div>
</aui:fieldset>
<aui:fieldset>
<div class="clearfix">
<label class="control-label">Hobbies</label>
<clay:checkbox checked="<%= true %>" label="Music" name="<%=curPortletNameSpace+"hobbies"%>" showLabel="<%= true %>" value="Music"/>
<clay:checkbox label="Travel" name="<%=curPortletNameSpace+"hobbies"%>" showLabel="<%= true %>" value="Travel"/>
<clay:checkbox label="Movies" name="<%=curPortletNameSpace+"hobbies"%>" showLabel="<%= true %>" value="Movies"/>
</div>
</aui:fieldset>
<aui:fieldset>
<div class="clearfix">
<clay:select label="Country" name="<%=curPortletNameSpace+"country"%>" options="<%= selectOptions %>"/>
</div>
</aui:fieldset>
<aui:fieldset>
<div class="clearfix">
<aui:button name="saveButton" type="submit" value="Save" />
</div>
</aui:fieldset>
</aui:fieldset-group>
</aui:form>
|
view_employee.jsp
<%@ include file="/init.jsp" %>
<%@page import="java.util.List"%>
<%@page import="java.util.Map"%>
<h2>Display Employee Details</h2><br/>
<%
Map<String,String> employeeMap=(Map<String,String>)request.getAttribute("employeeObject");
%>
<b>Gender: </b><%=employeeMap.get("gender")%> <br/>
<b>Country: </b><%=employeeMap.get("country")%> <br/>
<b>Hobbies: </b><br/>
<%
List<String> hobbiesList=(List<String>)request.getAttribute("hobbiesList");
if(hobbiesList!=null){
for(String hobby:hobbiesList){
%>
<%=hobby%><br/>
<%}}%>
<portlet:renderURL var="homeURL">
</portlet:renderURL>
<br/>
<br/>
<aui:button href="<%= homeURL %>" value="Home" />
|
EditEmployeeMVCActionCommand.java
package com.liferaysavvy.gradle.clayform.portlet.action;
import
com.liferay.portal.kernel.log.Log;
import
com.liferay.portal.kernel.log.LogFactoryUtil;
import
com.liferay.portal.kernel.portlet.bridges.mvc.BaseMVCActionCommand;
import
com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand;
import
com.liferay.portal.kernel.theme.ThemeDisplay;
import
com.liferay.portal.kernel.util.Constants;
import
com.liferay.portal.kernel.util.ListUtil;
import
com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import
com.liferay.portal.kernel.util.WebKeys;
import
com.liferaysavvy.gradle.clayform.constants.ClayFormPortletKeys;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import
javax.portlet.ActionRequest;
import
javax.portlet.ActionResponse;
import
org.osgi.service.component.annotations.Component;
@Component(
immediate = true,
property = {
"javax.portlet.name=" +
ClayFormPortletKeys.CLAYFORM,
"mvc.command.name=/clayfrom/edit_employee"
},
service =
MVCActionCommand.class
)
public class
EditEmployeeMVCActionCommand extends BaseMVCActionCommand {
@Override
protected void doProcessAction(
ActionRequest
actionRequest,
ActionResponse actionResponse)
throws Exception {
String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
updateEntry(actionRequest,actionResponse);
}
protected void updateEntry(ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
WebKeys.THEME_DISPLAY);
// Get form values from request object
String gender = ParamUtil.getString(actionRequest, "gender");
String country = ParamUtil.getString(actionRequest, "country");
String[] hobbies = ParamUtil.getParameterValues(actionRequest, "hobbies", null);
// Display logs in console for debug
_log.info("gender"+gender);
_log.info("gender"+hobbies.toString());
_log.info("gender"+country);
//Preparing object to send to JSP page.
Map<String,
String> employeeObject = new HashMap();
employeeObject.put("gender", gender);
employeeObject.put("country", country);
//set View details object in request object.
actionRequest.setAttribute("employeeObject", employeeObject);
List<String>
hobbiesList = new ArrayList();
hobbiesList = ListUtil.toList(hobbies);
//set View details object in request object.
actionRequest.setAttribute("hobbiesList", hobbiesList);
//Navigation to view employee details JSP page.
actionResponse.
}
private static final Log _log = LogFactoryUtil.getLog(
EditEmployeeMVCActionCommand.class);
}
|
Author
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteIs there any clay:input tag or continue to use aui:input ?
ReplyDeleteWill Clay components be injected portlet:namespace value automatically in the future like aui components?
Wonderful illustrated information. I thank you about that. No doubt it will be very useful for my future projects. Would like to see some other posts on the same subject!
ReplyDeleteNice post. I learn something new and challenging on websites I stumbleupon on a daily basis.대구오피