|
Processing...
Description & Source Code
ZK Calendar is an Ajax component readily embeddable into any Java
web application. In this demo, it's shown as a standalone, Google
Calendar like application; offering functionalities such as filtering,
detailed scheduling, multiple time zones, and daily/weekly/monthly view.
Properties such as format and style can be easily configured by setting
the calendar component's attributes. The main task for the developers is
to handle the calendar events and preparing the event data model;
similar to how other data components work in ZK.
This feature requires ZK EE. It can also be used independently under commerical or GPL license.
zk_calendar.zul
<zk> <div apply="demo.app.zk_calendar.CalendarController"> <hlayout valign="middle"> <button id="today" label="Today" /> <button id="prev" iconSclass="z-icon-arrow-left"/> <button id="next" iconSclass="z-icon-arrow-right"/> <separator width="50px" /> <button id="pageDay" label="Day" width="60px" /> <button id="pageWeek" label="Week" width="60px"/> <button id="pageMonth" label="Month" width="60px"/> <separator width="50px"/> Filter : <textbox id="filter"/> <button id="applyFilter" label="Apply"/> <button id="resetFilter" label="Reset"/> </hlayout> <separator bar="true" height="20px"/> <calendars id="calendars" firstDayOfWeek="Sunday" height="600px" timeZone="Main=GMT+0" mold="month"/> </div> <!-- Create/Update Event Popup --> <include src="/widgets/zk_calendar/zk_calendar/calendar_editor.zul" /> </zk> calendar_editor.zul
<div viewModel="@id('vm') @init('demo.app.zk_calendar.CalendarEditorViewModel')" validationMessages="@id('vmsgs')"> <window title="Create Calendar Event" border="normal" width="400px" form="@id('fx') @load(vm.calendarEvent) @save(vm.calendarEvent, before='ok') @validator(vm.dateValidator)" allDay="@ref(vm.isAllDay(fx.beginDate,fx.endDate))" mode="popup" visible="@load(vm.visible)" position="center,center" > <vlayout hflex="1"> <hlayout valign="middle"> Lock this event : <checkbox checked="@bind(fx.locked)" /> All Day: <checkbox checked="@load(allDay)" disabled="true" /> </hlayout> <grid hflex='1'> <columns> <column width="100px" align="right" /> <column /> </columns> <rows> <row> BeginDate: <div> <datebox hflex="1" locale="en" timeZone="GMT+0" format="@load(allDay ? 'long' : 'long+medium')" value="@bind(fx.beginDate)" errorMessage="@load(vmsgs.beginDate)" /> </div> </row> <row> EndDate: <div> <datebox hflex="1" locale="en" timeZone="GMT+0" format="@load(allDay ? 'long' : 'long+medium')" value="@bind(fx.endDate)" errorMessage="@load(vmsgs.endDate)"/> </div> </row> <row> Color: <hlayout valign="middle"> Border <colorbox value="@bind(fx.headerColor)" /> Content <colorbox value="@bind(fx.contentColor)" /> </hlayout> </row> <row> Title: <textbox multiline="true" rows="3" width="97%" value="@bind(fx.content)" /> </row> <row> <cell colspan="2" style="text-align:center;"> <hlayout> <button label="OK" onClick="@command('ok')" width="80px" /> <button label="Cancel" onClick="@command('cancel')" width="80px" /> <button label="Delete" onClick="@command('delete')" width="80px" /> </hlayout> </cell> </row> </rows> </grid> </vlayout> </window> </div> CalendarController.java
package demo.app.zk_calendar; import java.util.Calendar; import java.util.TimeZone; import org.zkoss.calendar.CalendarWebAppInit; import org.zkoss.calendar.Calendars; import org.zkoss.calendar.event.CalendarsEvent; import org.zkoss.web.fn.ServletFns; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.select.SelectorComposer; import org.zkoss.zk.ui.select.annotation.Listen; import org.zkoss.zk.ui.select.annotation.Wire; import org.zkoss.zk.ui.sys.PageCtrl; import org.zkoss.zkmax.ui.select.annotation.Subscribe; import org.zkoss.zul.Style; import org.zkoss.zul.Textbox; import org.zkoss.zul.theme.Themes; import javax.servlet.ServletException; public class CalendarController extends SelectorComposer<Component> { private static final long serialVersionUID = 1L; @Wire private Calendars calendars; @Wire private Textbox filter; private DemoCalendarModel calendarModel; //the in editing calendar ui event private CalendarsEvent calendarsEvent = null; @Override public void doAfterCompose(Component comp) throws Exception { overrideCalendarTheme(comp); super.doAfterCompose(comp); calendarModel = new DemoCalendarModel(new DemoCalendarData().getCalendarEvents()); calendars.setModel(this.calendarModel); } /** * TODO: remove workaround once https://tracker.zkoss.org/browse/ZK-4771 is available and zk-calendar supports it */ private void overrideCalendarTheme(Component comp) throws ServletException { String uri = CalendarWebAppInit.getCalendarThemeURI(Themes.getCurrentTheme()); new Style(uri).setPage(comp.getPage()); } //control the calendar position @Listen("onClick = #today") public void gotoToday(){ TimeZone timeZone = calendars.getDefaultTimeZone(); calendars.setCurrentDate(Calendar.getInstance(timeZone).getTime()); } @Listen("onClick = #next") public void gotoNext(){ calendars.nextPage(); } @Listen("onClick = #prev") public void gotoPrev(){ calendars.previousPage(); } //control page display @Listen("onClick = #pageDay") public void changeToDay(){ calendars.setMold("default"); calendars.setDays(1); } @Listen("onClick = #pageWeek") public void changeToWeek(){ calendars.setMold("default"); calendars.setDays(7); } @Listen("onClick = #pageMonth") public void changeToYear(){ calendars.setMold("month"); } //control the filter @Listen("onClick = #applyFilter") public void applyFilter(){ calendarModel.setFilterText(filter.getValue()); calendars.setModel(calendarModel); } @Listen("onClick = #resetFilter") public void resetFilter(){ filter.setText(""); calendarModel.setFilterText(""); calendars.setModel(calendarModel); } //listen to the calendar-create and edit of a event data @Listen(CalendarsEvent.ON_ITEM_CREATE + " = #calendars; " + CalendarsEvent.ON_ITEM_EDIT + " = #calendars") public void createEvent(CalendarsEvent event) { calendarsEvent = event; //to display a shadow when editing calendarsEvent.stopClearGhost(); DemoCalendarEvent data = (DemoCalendarEvent)event.getCalendarItem(); if(data == null) { data = new DemoCalendarEvent(); data.setHeaderColor("#3366ff"); data.setContentColor("#6699ff"); data.setBeginDate(event.getBeginDate()); data.setEndDate(event.getEndDate()); } else { data = (DemoCalendarEvent) event.getCalendarItem(); } //notify the editor QueueUtil.lookupQueue().publish( new QueueMessage(QueueMessage.Type.EDIT,data)); } //listen to the calendar-update of event data, usually send when user drag the event data @Listen(CalendarsEvent.ON_ITEM_UPDATE + " = #calendars") public void updateEvent(CalendarsEvent event) { DemoCalendarEvent data = (DemoCalendarEvent) event.getCalendarItem(); data.setBeginDate(event.getBeginDate()); data.setEndDate(event.getEndDate()); calendarModel.update(data); } //listen to queue message from other controller @Subscribe(value = QueueUtil.QUEUE_NAME) public void handleQueueMessage(Event event) { if(!(event instanceof QueueMessage)) { return; } QueueMessage message = (QueueMessage)event; switch(message.getType()){ case DELETE: calendarModel.remove((DemoCalendarEvent)message.getData()); //clear the shadow of the event after editing calendarsEvent.clearGhost(); calendarsEvent = null; break; case OK: if (calendarModel.indexOf((DemoCalendarEvent)message.getData()) >= 0) { calendarModel.update((DemoCalendarEvent)message.getData()); } else { calendarModel.add((DemoCalendarEvent)message.getData()); } case CANCEL: //clear the shadow of the event after editing calendarsEvent.clearGhost(); calendarsEvent = null; break; } } } QueueMessage.java
package demo.app.zk_calendar; import org.zkoss.zk.ui.event.Event; public class QueueMessage extends Event { private static final long serialVersionUID = 1L; static public enum Type { EDIT, OK, DELETE, CANCEL; } private Type type; private Object data; public QueueMessage(Type type) { super("onCalendarMessage"); this.type = type; } public QueueMessage(Type type, Object data) { this(type); this.data = data; } public Type getType() { return type; } public Object getData() { return data; } } CalendarEditorViewModel.java
package demo.app.zk_calendar; import java.util.Date; import java.util.Map; import org.zkoss.bind.BindUtils; import org.zkoss.bind.Property; import org.zkoss.bind.ValidationContext; import org.zkoss.bind.Validator; import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.Init; import org.zkoss.bind.annotation.NotifyChange; import org.zkoss.bind.validator.AbstractValidator; import org.zkoss.zk.ui.event.EventListener; public class CalendarEditorViewModel { private DemoCalendarEvent calendarEventData = new DemoCalendarEvent(); private boolean visible = false; public DemoCalendarEvent getCalendarEvent() { return calendarEventData; } public boolean isVisible() { return visible; } public void setVisible(boolean visible) { this.visible = visible; } @Init public void init() { //subscribe a queue, listen to other controller QueueUtil.lookupQueue().subscribe(new QueueListener()); } private void startEditing(DemoCalendarEvent calendarEventData) { this.calendarEventData = calendarEventData; visible = true; //reload entire view-model data when going to edit BindUtils.postNotifyChange(null, null, this, "*"); } public boolean isAllDay(Date beginDate,Date endDate) { int M_IN_DAY = 1000 * 60 * 60 * 24; boolean allDay = false; if(beginDate != null && endDate != null) { long between = endDate.getTime() - beginDate.getTime(); allDay = between > M_IN_DAY; } return allDay; } public Validator getDateValidator(){ return new AbstractValidator(){ @Override public void validate(ValidationContext ctx) { Map<String,Property> formData = ctx.getProperties(ctx.getProperty().getValue()); Date beginDate = (Date)formData.get("beginDate").getValue(); Date endDate = (Date)formData.get("endDate").getValue(); if(beginDate==null){ addInvalidMessage(ctx, "beginDate","Begin date is empty"); } if(endDate==null){ addInvalidMessage(ctx, "endDate","End date is empty"); } if(beginDate!=null && endDate!=null && beginDate.compareTo(endDate) >= 0){ addInvalidMessage(ctx, "endDate","End date is before begin date"); } } }; } @Command @NotifyChange("visible") public void cancel() { QueueMessage message = new QueueMessage(QueueMessage.Type.CANCEL); QueueUtil.lookupQueue().publish(message); this.visible = false; } @Command @NotifyChange("visible") public void delete() { QueueMessage message = new QueueMessage(QueueMessage.Type.DELETE, calendarEventData); QueueUtil.lookupQueue().publish(message); this.visible = false; } @Command @NotifyChange("visible") public void ok() { QueueMessage message = new QueueMessage(QueueMessage.Type.OK, calendarEventData); QueueUtil.lookupQueue().publish(message); this.visible = false; } private class QueueListener implements EventListener<QueueMessage> { @Override public void onEvent(QueueMessage message) throws Exception { if (QueueMessage.Type.EDIT.equals(message.getType())){ CalendarEditorViewModel.this.startEditing((DemoCalendarEvent)message.getData()); } } } } DemoCalendarData.java
package demo.app.zk_calendar; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.LinkedList; import java.util.List; import org.zkoss.calendar.api.CalendarItem; public class DemoCalendarData { private List<CalendarItem> calendarEvents = new LinkedList<>(); private final SimpleDateFormat DATA_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm"); private Calendar cal = Calendar.getInstance(); public DemoCalendarData() { init(); } private void init() { int mod = cal.get(Calendar.MONTH) + 1; int year = cal.get(Calendar.YEAR); String date2 = mod > 9 ? year + "/" + mod + "" : year + "/" + "0" + mod; String date1 = --mod > 9 ? year + "/" + mod + "" : year + "/" + "0" + mod; ++mod; String date3 = ++mod > 9 ? year + "/" + mod + "" : year + "/" + "0" + mod; // Red Events calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/28 00:00"), getDate(date1 + "/29 00:00"), "#A32929", "#D96666", "ZK Jet Released")); calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/04 02:00"), getDate(date1 + "/05 03:00"), "#A32929", "#D96666", "Experience ZK SpreadSheet Live Demo!")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/21 05:00"), getDate(date2 + "/21 07:00"), "#A32929", "#D96666", "New Features of ZK Spreadsheet")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/08 00:00"), getDate(date2 + "/09 00:00"), "#A32929", "#D96666", "ZK Spreadsheet Released")); // Blue Events calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/29 03:00"), getDate(date2 + "/02 06:00"), "#3467CE", "#668CD9", "ZK Released")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/02 10:00"), getDate(date2 + "/02 12:30"), "#3467CE", "#668CD9", "New Feature of ZK ")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/17 14:00"), getDate(date2 + "/18 16:00"), "#3467CE", "#668CD9", "Case Study - Mecatena")); calendarEvents.add(new DemoCalendarEvent(getDate(date3 + "/01 14:30"), getDate(date3 + "/01 17:30"), "#3467CE", "#668CD9", "ZK Unit Testing Project - zunit")); // Purple Events calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/29 08:00"), getDate(date2 + "/03 12:00"), "#7A367A", "#B373B3", "ZK Studio released")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/07 08:00"), getDate(date2 + "/07 12:00"), "#7A367A", "#B373B3", "Tutorial : Reading from the DB with Netbeans and ZK")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/13 11:00"), getDate(date2 + "/13 14:30"), "#7A367A", "#B373B3", "Small talk - ZK Charts")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/16 14:00"), getDate(date2 + "/18 16:00"), "#7A367A", "#B373B3", "Style Guide for ZK released !")); calendarEvents.add(new DemoCalendarEvent(getDate(date3 + "/02 12:00"), getDate(date3 + "/02 17:00"), "#7A367A", "#B373B3", "Small talk -- Simple Database Access From ZK")); // Khaki Events calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/03 00:00"), getDate(date1 + "/04 00:00"), "#88880E", "#BFBF4D", "ZK UK User Group")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/13 05:00"), getDate(date2 + "/13 07:00"), "#88880E", "#BFBF4D", "How to Test ZK Application with Selenium")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/24 19:30"), getDate(date2 + "/24 20:00"), "#88880E", "#BFBF4D", "ZK Alfresco Talk")); calendarEvents.add(new DemoCalendarEvent(getDate(date3 + "/03 00:00"), getDate(date3 + "/04 00:00"), "#88880E", "#BFBF4D", "ZK selected as SourceForge.net Project of the Month")); // Green Events calendarEvents.add(new DemoCalendarEvent(getDate(date1 + "/28 10:00"), getDate(date1 + "/28 12:30"), "#0D7813", "#4CB052", "ZK Mobile Released")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/03 00:00"), getDate(date2 + "/03 05:30"), "#0D7813", "#4CB052", "ZK Gmaps released")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/05 20:30"), getDate(date2 + "/06 00:00"), "#0D7813", "#4CB052", "Refresh with Five New ZK Themes!")); calendarEvents.add(new DemoCalendarEvent(getDate(date2 + "/23 00:00"), getDate(date2 + "/25 16:30"), "#0D7813", "#4CB052", "ZK Roadmap Announced")); calendarEvents.add(new DemoCalendarEvent(getDate(date3 + "/01 08:30"), getDate(date3 + "/01 19:30"), "#0D7813", "#4CB052", "Build Database CRUD Application in 6 Steps")); } private Date getDate(String dateText) { try { return DATA_FORMAT.parse(dateText); } catch (ParseException e) { e.printStackTrace(); } return null; } public List<CalendarItem> getCalendarEvents() { return calendarEvents; } } DemoCalendarEvent.java
package demo.app.zk_calendar; import java.util.Date; import org.zkoss.bind.annotation.Immutable; import org.zkoss.calendar.impl.SimpleCalendarEvent; public class DemoCalendarEvent extends SimpleCalendarEvent { private static final long serialVersionUID = 1L; public DemoCalendarEvent(Date beginDate, Date endDate, String headerColor, String contentColor, String content) { setHeaderColor(headerColor); setContentColor(contentColor); setContent(content); setBeginDate(beginDate); setEndDate(endDate); } public DemoCalendarEvent(Date beginDate, Date endDate, String headerColor, String contentColor, String content, String title) { setHeaderColor(headerColor); setContentColor(contentColor); setContent(content); setTitle(title); setBeginDate(beginDate); setEndDate(endDate); } public DemoCalendarEvent(Date beginDate, Date endDate, String headerColor, String contentColor, String content, String title, boolean locked) { setHeaderColor(headerColor); setContentColor(contentColor); setContent(content); setTitle(title); setBeginDate(beginDate); setEndDate(endDate); setLocked(locked); } public DemoCalendarEvent() { setHeaderColor("#FFFFFF"); setContentColor("#000000"); } @Override @Immutable public Date getBeginDate() { return super.getBeginDate(); } @Override @Immutable public Date getEndDate() { return super.getEndDate(); } } DemoCalendarModel.java
package demo.app.zk_calendar; import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.zkoss.calendar.api.CalendarItem; import org.zkoss.calendar.api.RenderContext; import org.zkoss.calendar.impl.SimpleCalendarModel; public class DemoCalendarModel extends SimpleCalendarModel { private static final long serialVersionUID = 1L; private String filterText = ""; public DemoCalendarModel(List<CalendarItem> calendarEvents) { super(calendarEvents); } public void setFilterText(String filterText) { this.filterText = filterText; } @Override public List<CalendarItem> get(Date beginDate, Date endDate, RenderContext rc) { List<CalendarItem> list = new LinkedList<CalendarItem>(); long begin = beginDate.getTime(); long end = endDate.getTime(); for (Iterator<?> itr = _list.iterator(); itr.hasNext();) { Object obj = itr.next(); CalendarItem ce = obj instanceof CalendarItem ? (CalendarItem)obj : null; if(ce == null) break; long b = ce.getBeginDate().getTime(); long e = ce.getEndDate().getTime(); if (e >= begin && b < end && ce.getContent().toLowerCase().contains(filterText.toLowerCase())) list.add(ce); } return list; } }
Copyright © 2005-2024 Potix Corporation All rights reserved.
|
Processing... |