ZK - Open Source Ajax Java FrameworkZK - Open Source Ajax Java Framework

Calendar

mguilherme
15 Jul 2010 09:14:23 GMT
15 Jul 2010 09:14:23 GMT

Hello,
I'm wondering if exists any mini calendar like <calendar> component of ZK so I can present my users with a mini calendar with events.
The idea is to send a List of events and mark the days on the calendar so users can click on the day and choose from a pop-up list the events.

Thanks

mguilherme
15 Jul 2010 11:31:18 GMT
15 Jul 2010 11:31:18 GMT

I've already watched the "Component Development Essentials" and I've extended the Calendar component, Now I just need to change the color of the days with events, but i can't figure it:

public class MiniCalendar extends org.zkoss.zul.Calendar {

	private List<Date> events;
	
  private static final long serialVersionUID = -6722434089355159212L;

  public List<Date> getEvents() {
  	return this.events;
  }
  
  public void setEvents(List<Date> events) {
  	this.events = events;
  }
  
}

mguilherme
16 Jul 2010 04:42:49 GMT
16 Jul 2010 04:42:49 GMT

I saw there is a new feature in 5.03 for calendar, I don't know if it works for my problem, could someone point me in the right direction.

mguilherme
19 Jul 2010 09:52:08 GMT
19 Jul 2010 09:52:08 GMT

Another test with any success, can't override nothing:

my2calendar.setWidgetOverride("cellHTML", "function (cal, y, m, day, monthofs) {return '<h1>Hello World</h1>';}");

samchuang
19 Jul 2010 21:24:08 GMT
19 Jul 2010 21:24:08 GMT

Hi

from your description, you will need to extend calendar in Server side and in client side, below is the process you need

Server side:
need to sent the event list to client side
you can send data by JSON format and send this to client side, refer the pusdo code below

String getDatesInJSONFormat (List<Date> dates) { return JSONArray.toJSONString(); }
public void setEvents(List<Date> events) {
  	smartUpdate("events", getDatesInJSONFormat(events));
  }

protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer)
			throws java.io.IOException {
		super.renderProperties(renderer);
		render(renderer, "events", getDatesInJSONFormat(events));
	}


Client side:
when you have a list of date, you can override the zul.db.Renderer.cellHTML
in this function, get the list date from calendar widget, and render different color or background by this info

zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
   //1.  get events date list
    var list = cal.getEvents();
   //2. search the list, compare the year, month and day, see if there is a match target
   //3. base on search result, generat different html
   
  //below is the default one, return differently when the date is in the list
  // for example, set different color:   return '<a href="javascript:;" style="color:red;">' + day + '</a>';  

   return '<a href="javascript:;">' + day + '</a>';
};

mguilherme
20 Jul 2010 04:36:33 GMT
20 Jul 2010 04:36:33 GMT

thanks for your answer, I'm trying just to override de CellHTML with no success:

my2calendar.setWidgetOverride("zul.db.Renderer.cellHTML", "function (cal, y, m, day, monthofs) { return '<a href=\"javascript:;\">' + day + '</a>';}");

mguilherme
20 Jul 2010 05:03:06 GMT
20 Jul 2010 05:03:06 GMT

This test code works, but only after I click somewhere on calendar.

<calendar id="my2calendar">
		<attribute w:name="onBind"><![CDATA[
			zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
				return '<a href="javascript:;" style="color:green;">' + day + '</a>';
			}]]>
		</attribute>
</calendar>

samchuang
20 Jul 2010 20:07:06 GMT
20 Jul 2010 20:07:06 GMT

Hi

onBind will call after DOM is ready, so, when you override the zul.db.Renderer.cellHTML at onBind(), the DOM is alreay rendered

use zk.afterLoad, this function will load after package is loaded

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<script><![CDATA[
zk.afterLoad('zul.db', function(){
	zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
		return '<a href="javascript:;" style="color:red;">' + day + '</a>';
	}; 
});
]]></script>
<calendar id="cal">
</calendar>
</zk>

rtfiya
21 Jul 2010 07:02:32 GMT
21 Jul 2010 07:02:32 GMT

Guys thanks for posting the test code.

floor tape
sidewalk stencils

mguilherme
21 Jul 2010 07:09:04 GMT
21 Jul 2010 07:09:04 GMT

thanks, it worked great:
I'm already sending events with json, I guess it's all ok, the browser sends:

['zul.db.Calendar','z_d__7',{id:'mycalendar',$$onSize:false,$$onChange:false,prolog:'\t\n\t',value:'2010/07/21',events:'["2010\\/07\\/21","2010\\/07\\/21"]'},[]]]]]],1);
zk.afterLoad('zul.db', function(){
			zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
				return '<a href="javascript:;" style="color:green;">' + day + '</a>';
			}; 
		});
}finally{zkme();}</script>

The problem is how to access the json data, I think I've no access inside the script.

index.zul:

<?page title="Auto Generated index.zul"?>
<window id="mainWindow" title="Hello World!!" border="normal" width="auto" height="500px">

<space /><space /><space /><space />

	<script><![CDATA[
		zk.afterLoad('zul.db', function(){
			zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
				return '<a href="javascript:;" style="color:green;">' + day + '</a>';
			}; 
		});
	]]></script>	
	<calendar id="mycalendar" use="test.component.EventCalendar">
	</calendar>
	
	<zscript><![CDATA[
		java.util.Date date1 = new java.util.Date();
		java.util.Date date2 = new java.util.Date();
		java.util.List events = new java.util.ArrayList();
		events.add(date1);
		events.add(date2);
		
		mycalendar.setEvents(events);
	]]></zscript>
	
</window>

EventCalendar.java:

package test.component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.zkoss.json.JSONArray;

public class EventCalendar extends org.zkoss.zul.Calendar {

	private List<String> events;
	
  private static final long serialVersionUID = -6722434089355159212L;
  
  private String getEventsInJSONFormat(List<String> events) {
  	return JSONArray.toJSONString(events);
  }
  
  public void setEvents(List<Date> events) {
  	if(events.size() > 0) {
  		this.events = new ArrayList<String>();
	  	for(Date item : events) {
	  		this.events.add(DateToString(item));
	  	}
	  	smartUpdate("events", getEventsInJSONFormat(this.events));
  	}
  }
  
  @Override
  protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException {
  	super.renderProperties(renderer);
  	if(this.events != null && this.events.size() > 0) {
  		render(renderer, "events", getEventsInJSONFormat(this.events));
  	}
  }
  
  private String DateToString(Date date) {
//  	DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
  	return new SimpleDateFormat("yyyy/MM/dd").format(date);
  }
  
}

All I wanna do is a mini calendar with events (marked has green) so the user can click and see a list of events to that specific day.
I though this was easy to do because it's very normal to see a mini calendar in applications / web pages with this calendar.

mguilherme
21 Jul 2010 12:29:33 GMT
21 Jul 2010 12:29:33 GMT

I figured out, not the most elegant code but works!!!

<script><![CDATA[
	zk.afterLoad('zul.db', function(){
		zul.db.Renderer.cellHTML = function (cal, y, m, day, monthofs) {
			var output = '<a href="javascript:;">' + day + '</a>';
			var events = eval('(' + cal.events + ')');
			if(events == null) return output;
			for(var i = 0; i < events.length; i++) {
				var eventSplited = events<i >.split("/");
				var eventYear = parseInt(eventSplited[0]);
				var eventMonth = parseInt(eventSplited[1]);
				var eventDay = parseInt(eventSplited[2]);
				
				if((y == eventYear) && ((m+1) == eventMonth) && (day == eventDay)) {
					output = '<a href="javascript:;" style="color:green; font-weight: bold;">' + day + '</a>';
				}	
			}
			return output;
		}; 
	});
]]></script>
<calendar id="tasksCalendar" use="ui.components.EventCalendar" />

samchuang
21 Jul 2010 21:30:30 GMT
21 Jul 2010 21:30:30 GMT

Hi

maybe the code is not elegant, but I think it's simple. Simple is great ~~

mguilherme
22 Jul 2010 09:03:24 GMT
22 Jul 2010 09:03:24 GMT

Hi there!
I've noticed that the event onClick() has a strange behavior, it is fired only when I click to change a week, not when I click on any day, the onChange() works but is fired when I change a Week or press any day.
I want something like onDayClick and be able to get the Date clicked, the idea is to use a popup component to show a mini list of events to that day, but again the popup is wired to onClick() so this is a problem.

samchuang
22 Jul 2010 20:20:53 GMT
22 Jul 2010 20:20:53 GMT

Hi

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
	<calendar>
		<attribute name="onChange">
	String date = ((InputEvent) event).getValue().toString();
	msg.setValue(date);
	popup.open(self);
</attribute>
	</calendar>
	<popup id="popup">
		<label id="msg"></label>
	</popup>
</zk>

mguilherme
23 Jul 2010 04:32:52 GMT
23 Jul 2010 04:32:52 GMT

Thanks samchuang, I've already managed that with no workarounds, I don't want the event to be fired when I change the month.

raviteja
2 Feb 2012 12:08:21 GMT
2 Feb 2012 12:08:21 GMT

Hi mguilherme ,
Thanks for sharing the code

Actually for me also same problem ...................Can u please post me the clear cut code what it is needed i mean that classes and script and zul...........................