Liferay中日历组件的使用

calendar Portlet的例子用法:在Liferay自带portlet中,calendar 是个不错的例子。

calendar Portlet包含7个选项:总结,天,星期,月,年,事项,出口/进口
默认显示“总结”选项的主页面,单击页面的“增加事项”按钮,跳转到[b]edit_event.jsp[/b]页面,页面显示效果如下:

[img]http://fantasyyong840205.iteye.com/upload/picture/pic/8110/8955b435-7b90-33ed-95ef-17d4d4e01439.jpg [/img]

edit_event.jsp页面:

<%
// 只列出关键代码
String redirect = ParamUtil.getString(request, "redirect");

CalEvent event = (CalEvent)request.getAttribute(WebKeys.CALENDAR_EVENT);

long eventId = BeanParamUtil.getLong(event, request, "eventId");

Calendar startDate = CalendarUtil.roundByMinutes((Calendar)selCal.clone(), 15);

if (event != null) {
if (!event.isTimeZoneSensitive()) {
startDate = CalendarFactoryUtil.getCalendar();
}

startDate.setTime(event.getStartDate());
}

Calendar endDate = (Calendar)curCal.clone();

endDate.add(Calendar.YEAR, 1);

if (event != null) {
if (!event.isTimeZoneSensitive()) {
endDate = CalendarFactoryUtil.getCalendar();
}

if (event.getEndDate() != null) {
endDate.setTime(event.getEndDate());
}
}

%>

<!-- 省略中间代码 -->

<table class="liferay-table">
<tr>
<td>
<liferay-ui:message key="start-date" />
</td>
<td>
<liferay-ui:input-field model="<%= CalEvent.class %>" bean="<%= event %>" field="startDate" defaultValue="<%= startDate %>" />
</td>
</tr>


这样,将会显示日期控件,实现样式效果如上图所示。年月日分别显示,并且有一个日历按钮,可以弹出一个典型的日历界面。

生成的代码,主要分成以下几个部分:

1. 相应的JavaScript语句
这部分代码,一是创建一个Calendar对象,就是会弹出来的日历页面。

2.生成年月日的HTML代码
年月日代码,在Liferay里面,是三个单独的Select框。

3.一个弹出日历页面的图片
用了一个图片calendar.gif,单击就会显示日历页面。

4.生成时分的HTML代码
在Liferay里面,有两个Select框,分别选择时和分,还有一个AM、PM的Select框。

看到这里,可能会有一个疑问,几乎所有的input输入框,都是使用<liferay-ui:input-field>这个Taglib实现的,而且从JSP中,看不出在哪儿定义了这个input-field应该显示为日期,而不是普通的input窗口。

而这,可以通过阅读源代码来解释。具体代码为:
portal\portal-web\docroot\html\taglib\ui\input_field\page.jsp



<%@ include file="/html/taglib/init.jsp" %>

<%@ page import="com.liferay.portal.model.impl.BaseModelImpl" %>
<%@ page import="com.liferay.util.XSSUtil" %>

<%
// 得到liferay-ui:input-field 标签提交的 model 属性
String model = (String)request.getAttribute("liferay-ui:input-field:model");
// 得到liferay-ui:input-field 标签提交的 bean 属性
Object bean = request.getAttribute("liferay-ui:input-field:bean");
// 得到liferay-ui:input-field 标签提交的 field 属性
String field = (String)request.getAttribute("liferay-ui:input-field:field");
// 得到liferay-ui:input-field 标签提交的 fieldParam 属性
String fieldParam = (String)request.getAttribute("liferay-ui:input-field:fieldParam");
// 得到liferay-ui:input-field 标签提交的 defaultValue 属性
Object defaultValue = request.getAttribute("liferay-ui:input-field:defaultValue");
// 得到liferay-ui:input-field 标签提交的 disabled 属性
boolean disabled = GetterUtil.getBoolean((String)request.getAttribute("liferay-ui:input-field:disabled"));

// 得到配置文件中对应 model的 field 的 type属性
String type = ModelHintsUtil.getType(model, field);
Map hints = ModelHintsUtil.getHints(model, field);
%>

<c:if test="<%= type != null %>">
<c:choose>
<c:when test='<%= type.equals("boolean") %>'>

<%
boolean defaultBoolean = GetterUtil.DEFAULT_BOOLEAN;

if (defaultValue != null) {
defaultBoolean = ((Boolean)defaultValue).booleanValue();
}
else {
if (hints != null) {
defaultBoolean = GetterUtil.getBoolean((String)hints.get("default-value"));
}
}

boolean value = BeanParamUtil.getBoolean(bean, request, field, defaultBoolean);
%>

<liferay-ui:input-checkbox param="<%= field %>" defaultValue="<%= value %>" disabled="<%= disabled %>" />
</c:when>

<!-- 配置文件中对应 model的 field 的 type属性值是“Date” -->
<c:when test='<%= type.equals("Date") %>'>

<%
// 如果liferay-ui:input-field 标签没有提交fieldParam属性,fieldParam值等同于field属性值
if (fieldParam == null) {
fieldParam = field;
}
// defaultValue 属性值一般是表单提交当时的时间
Calendar cal = (Calendar)defaultValue;

int month = ParamUtil.getInteger(request, fieldParam + "Month", -1);

if ((month == -1) && (cal != null)) {
month = cal.get(Calendar.MONTH);
}

boolean monthNullable = false;

if (hints != null) {
monthNullable = GetterUtil.getBoolean((String)hints.get("month-nullable"), monthNullable);
}

int day = ParamUtil.getInteger(request, fieldParam + "Day", -1);

if ((day == -1) && (cal != null)) {
day = cal.get(Calendar.DATE);
}

boolean dayNullable = false;

if (hints != null) {
dayNullable = GetterUtil.getBoolean((String)hints.get("day-nullable"), dayNullable);
}

int year = ParamUtil.getInteger(request, fieldParam + "Year", -1);

if ((year == -1) && (cal != null)) {
year = cal.get(Calendar.YEAR);
}

boolean yearNullable = false;

if (hints != null) {
yearNullable = GetterUtil.getBoolean((String)hints.get("year-nullable"), yearNullable);
}

int yearRangeDelta = 5;

if (hints != null) {
yearRangeDelta = GetterUtil.getInteger((String)hints.get("year-range-delta"), yearRangeDelta);
}

int yearRangeStart = year - yearRangeDelta;
int yearRangeEnd = year + yearRangeDelta;

if (year == -1) {
Calendar now = CalendarFactoryUtil.getCalendar(timeZone, locale);

yearRangeStart = now.get(Calendar.YEAR) - yearRangeDelta;
yearRangeEnd = now.get(Calendar.YEAR) + yearRangeDelta;
}

int firstDayOfWeek = Calendar.SUNDAY - 1;

if (cal != null) {
firstDayOfWeek = cal.getFirstDayOfWeek() - 1;
}

int hour = ParamUtil.getInteger(request, fieldParam + "Hour", -1);

if ((hour == -1) && (cal != null)) {
hour = cal.get(Calendar.HOUR);
}

int minute = ParamUtil.getInteger(request, fieldParam + "Minute", -1);

if ((minute == -1) && (cal != null)) {
minute = cal.get(Calendar.MINUTE);
}

int amPm = ParamUtil.getInteger(request, fieldParam + "AmPm", -1);

if ((amPm == -1) && (cal != null)) {
amPm = cal.get(Calendar.AM_PM);
}

boolean showTime = true;

if (hints != null) {
showTime = GetterUtil.getBoolean((String)hints.get("show-time"), showTime);
}
%>

<liferay-ui:input-date
monthParam='<%= fieldParam + "Month" %>'
monthValue="<%= month %>"
monthNullable="<%= monthNullable %>"
dayParam='<%= fieldParam + "Day" %>'
dayValue="<%= day %>"
dayNullable="<%= dayNullable %>"
yearParam='<%= fieldParam + "Year" %>'
yearValue="<%= year %>"
yearNullable="<%= yearNullable %>"
yearRangeStart="<%= yearRangeStart %>"
yearRangeEnd="<%= yearRangeEnd %>"
firstDayOfWeek="<%= firstDayOfWeek %>"
imageInputId='<%= fieldParam + "ImageInputId" %>'
disabled="<%= disabled %>"
/>

<c:if test="<%= showTime %>">
 

<liferay-ui:input-time
hourParam='<%= fieldParam + "Hour" %>'
hourValue="<%= hour %>"
minuteParam='<%= fieldParam + "Minute" %>'
minuteValue="<%= minute %>"
minuteInterval="1"
amPmParam='<%= fieldParam + "AmPm" %>'
amPmValue="<%= amPm %>"
disabled="<%= disabled %>"
/>
</c:if>
</c:when>
<c:when test='<%= type.equals("double") || type.equals("int") || type.equals("String") %>'>

<%
String defaultString = GetterUtil.DEFAULT_STRING;

if (defaultValue != null) {
defaultString = (String)defaultValue;
}

String value = null;

if (fieldParam == null) {
fieldParam = namespace + field;

if (type.equals("double")) {
value = String.valueOf(BeanParamUtil.getDouble(bean, request, field, GetterUtil.DEFAULT_DOUBLE));
}
else if (type.equals("int")) {
value = String.valueOf(BeanParamUtil.getInteger(bean, request, field, GetterUtil.DEFAULT_INTEGER));
}
else {
value = BeanParamUtil.getString(bean, request, field, defaultString);

String httpValue = request.getParameter(field);

if (httpValue != null) {
boolean xssAllowByModel = GetterUtil.getBoolean(PropsUtil.get("xss.allow." + model), BaseModelImpl.XSS_ALLOW);
boolean xssAllowByField = GetterUtil.getBoolean(PropsUtil.get("xss.allow." + model + "." + field), xssAllowByModel);

value = XSSUtil.strip(httpValue);
}
}
}
else {
fieldParam = namespace + fieldParam;
value = defaultString;
}

String displayHeight = ModelHintsDefaults.TEXT_DISPLAY_HEIGHT;
String displayWidth = ModelHintsDefaults.TEXT_DISPLAY_WIDTH;
String maxLength = ModelHintsDefaults.TEXT_MAX_LENGTH;
boolean upperCase = false;
boolean checkTab = false;

if (hints != null) {
displayHeight = GetterUtil.getString((String)hints.get("display-height"), displayHeight);
displayWidth = GetterUtil.getString((String)hints.get("display-width"), displayWidth);
maxLength = GetterUtil.getString((String)hints.get("max-length"), maxLength);
upperCase = GetterUtil.getBoolean((String)hints.get("upper-case"), upperCase);
checkTab = GetterUtil.getBoolean((String)hints.get("check-tab"), checkTab);
}
%>

<c:choose>
<c:when test='<%= displayHeight.equals(ModelHintsDefaults.TEXT_DISPLAY_HEIGHT) %>'>

<%
if (Validator.isNotNull(value)) {
int maxLengthInt = GetterUtil.getInteger(maxLength);

if (value.length() > maxLengthInt) {
value = value.substring(0, maxLengthInt);
}
}
%>

<input <%= disabled ? "disabled" : "" %> id="<%= fieldParam %>" name="<%= fieldParam %>" style="width: <%= displayWidth %>px; <%= upperCase ? "text-transform: uppercase;" : "" %>" type="text" value="<%= value %>" onKeyPress="Liferay.Util.checkMaxLength(this, <%= maxLength %>);">
</c:when>
<c:otherwise>
<textarea <%= disabled ? "disabled" : "" %> id="<%= fieldParam %>" name="<%= fieldParam %>" style="height: <%= displayHeight %><%= Validator.isDigit(displayHeight) ? "px" : "" %>; width: <%= displayWidth %><%= Validator.isDigit(displayWidth) ? "px" : "" %>;" wrap="soft" onKeyDown="<%= checkTab ? "Liferay.Util.checkTab(this); " : "" %> Liferay.Util.disableEsc();" onKeyPress="Liferay.Util.checkMaxLength(this, <%= maxLength %>);"><%= value %></textarea>
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
</c:if>


ModelHintsUtil.java:

package com.liferay.portal.model;

import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.util.InitUtil;
import com.liferay.portal.util.PropsUtil;
import com.liferay.util.CollectionFactory;
import com.liferay.util.ListUtil;

import java.io.StringReader;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* <a href="ModelHintsUtil.java.html"><b><i>View Source</i></b></a>
*
* @author Brian Wing Shun Chan
*
*/
public class ModelHintsUtil {

static {
InitUtil.init();
}

public static Map getDefaultHints(String model) {
return _instance._getDefaultHints(model);
}

public static Element getFieldsEl(String model, String field) {
return _instance._getFieldsEl(model, field);
}

public static List getModels() {
return _instance._getModels();
}

public static String getType(String model, String field) {
return _instance._getType(model, field);
}

public static Map getHints(String model, String field) {
return _instance._getHints(model, field);
}

public static String trimString(String model, String field, String value) {
if (value == null) {
return value;
}

Map hints = getHints(model, field);

if (hints == null) {
return value;
}

int maxLength = GetterUtil
.getInteger(ModelHintsDefaults.TEXT_MAX_LENGTH);

maxLength = GetterUtil.getInteger((String) hints.get("max-length"),
maxLength);

if (value.length() > maxLength) {
return value.substring(0, maxLength);
} else {
return value;
}
}

private ModelHintsUtil() {
_hintCollections = CollectionFactory.getHashMap();
_defaultHints = CollectionFactory.getHashMap();
// 从CollectionFactory中得到新的HashMap对象
_modelFields = CollectionFactory.getHashMap();
_models = new TreeSet();

try {
ClassLoader classLoader = getClass().getClassLoader();

String[] configs = StringUtil.split(PropsUtil
.get(PropsUtil.MODEL_HINTS_CONFIGS));

for (int i = 0; i < configs.length; i++) {
_read(classLoader, configs[i]);
}
} catch (Exception e) {
_log.error(e, e);
}
}

private Map _getDefaultHints(String model) {
return (Map) _defaultHints.get(model);
}

private Element _getFieldsEl(String model, String field) {
Map fields = (Map) _modelFields.get(model);

if (fields == null) {
return null;
} else {
return (Element) fields.get(field + _ELEMENTS_SUFFIX);
}
}

private List _getModels() {
return ListUtil.fromCollection(_models);
}

/**
* Portal容器加载portal-model-hints.xml配置文件,按照节点解析为内存对象。
*
* 把文件中的 model 的name属性作为 key 将所有的 model节点对象(Map类型)存入集合.
*
* 根据配置文件中的 field 的name属性 + “_TYPE”字符串 作为 key 得到对应的field节点对象的type属性值。
*
*/
private String _getType(String model, String field) {
Map fields = (Map) _modelFields.get(model);

if (fields == null) {
return null;
} else {
return (String) fields.get(field + _TYPE_SUFFIX);
}
}

private Map _getHints(String model, String field) {
Map fields = (Map) _modelFields.get(model);

if (fields == null) {
return null;
} else {
return (Map) fields.get(field + _HINTS_SUFFIX);
}
}

private void _read(ClassLoader classLoader, String source) throws Exception {

String xml = null;

try {
xml = StringUtil.read(classLoader, source);
} catch (Exception e) {
_log.warn("Cannot load " + source);
}

if (xml == null) {
return;
}

if (_log.isDebugEnabled()) {
_log.debug("Loading " + source);
}

SAXReader reader = new SAXReader();

Document doc = reader.read(new StringReader(xml));

Element root = doc.getRootElement();

Iterator itr1 = root.elements("hint-collection").iterator();

while (itr1.hasNext()) {
Element hintCollection = (Element) itr1.next();

String name = hintCollection.attributeValue("name");

Map hints = (Map) _hintCollections.get(name);

if (hints == null) {
hints = CollectionFactory.getHashMap();

_hintCollections.put(name, hints);
}

Iterator itr2 = hintCollection.elements("hint").iterator();

while (itr2.hasNext()) {
Element hint = (Element) itr2.next();

String hintName = hint.attributeValue("name");
String hintValue = hint.getText();

hints.put(hintName, hintValue);
}
}

itr1 = root.elements("model").iterator();

while (itr1.hasNext()) {
Element model = (Element) itr1.next();

String name = model.attributeValue("name");

Map defaultHints = CollectionFactory.getHashMap();

_defaultHints.put(name, defaultHints);

Element defaultHintsEl = model.element("default-hints");

if (defaultHintsEl != null) {
Iterator itr2 = defaultHintsEl.elements("hint").iterator();

while (itr2.hasNext()) {
Element hint = (Element) itr2.next();

String hintName = hint.attributeValue("name");
String hintValue = hint.getText();

defaultHints.put(hintName, hintValue);
}
}

Map fields = (Map) _modelFields.get(name);

if (fields == null) {
fields = CollectionFactory.getHashMap();

_modelFields.put(name, fields);
}

_models.add(name);

Iterator itr2 = model.elements("field").iterator();

while (itr2.hasNext()) {
Element field = (Element) itr2.next();

String fieldName = field.attributeValue("name");
String fieldType = field.attributeValue("type");

Map fieldHints = CollectionFactory.getHashMap();

fieldHints.putAll(defaultHints);

Iterator itr3 = field.elements("hint-collection").iterator();

while (itr3.hasNext()) {
Element hintCollection = (Element) itr3.next();

Map hints = (Map) _hintCollections.get(hintCollection
.attributeValue("name"));

fieldHints.putAll(hints);
}

itr3 = field.elements("hint").iterator();

while (itr3.hasNext()) {
Element hint = (Element) itr3.next();

String hintName = hint.attributeValue("name");
String hintValue = hint.getText();

fieldHints.put(hintName, hintValue);
}

fields.put(fieldName + _ELEMENTS_SUFFIX, field);
fields.put(fieldName + _TYPE_SUFFIX, fieldType);
fields.put(fieldName + _HINTS_SUFFIX, fieldHints);
}
}
}

private static final String _ELEMENTS_SUFFIX = "_ELEMENTS";

private static final String _TYPE_SUFFIX = "_TYPE";

private static final String _HINTS_SUFFIX = "_HINTS";

private static Log _log = LogFactory.getLog(ModelHintsUtil.class);

private static ModelHintsUtil _instance = new ModelHintsUtil();

private Map _hintCollections;
private Map _defaultHints;
private Map _modelFields;
private Set _models;

}


通过阅读这段代码,可以知道,不同类型的field,将会生成不同的HTML代码,而依据就是配置文件portal-model-hints.xml和ext-model-hints.xml。这里面有Field的类型的定义。

例如在 portal\portal-impl\classes\META-INF\portal-model-hints.xml 路径找到并打开portal-model-hints.xml文件:
calendar 里面的displayDate的定义则为:

	<model name="com.liferay.portlet.calendar.model.CalEvent">
<field name="eventId" type="long" />
<field name="groupId" type="long" />
<field name="companyId" type="long" />
<field name="userId" type="long" />
<field name="userName" type="String" />
<field name="createDate" type="Date" />
<field name="modifiedDate" type="Date" />
<field name="title" type="String" />
<field name="description" type="String">
<hint-collection name="TEXTAREA" />
</field>

<!-- startDate的field定义 -->
<field name="startDate" type="Date" />

<field name="endDate" type="Date" />
<field name="durationHour" type="int" />
<field name="durationMinute" type="int" />
<field name="allDay" type="boolean" />
<field name="timeZoneSensitive" type="boolean" />
<field name="type" type="String" />
<field name="repeating" type="boolean" />
<field name="recurrence" type="String">
<hint-collection name="CLOB" />
</field>
<field name="remindBy" type="String" />
<field name="firstReminder" type="int" />
<field name="secondReminder" type="int" />
</model>


另外,通过源代码还可以看到,如果只是显示年月日,而不显示时分,可以设置为
  <field name=" displayDate" type="Date">
<hint name="show-time">false</hint>
</field>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值