0

Datebox Problem in ZK 3.5.0

asked 2008-09-16 06:45:56 +0800

enixser gravatar image enixser
185 3

After upgrading to ZK 3.5.0 my derived Datebox component does not work any longer as it did before. In 3.0.7 the setText() method was called when a date was selected in the calender popup. In the new version this method is not called any longer. How is the selected date set in the input field now? Which method is called? I need this to validate the selected date.

delete flag offensive retag edit

8 Replies

Sort by ยป oldest newest

answered 2008-09-17 08:35:09 +0800

windperson gravatar image windperson
415 1

Hi enixser,
Can you post your code? thx.

link publish delete flag offensive edit

answered 2008-09-18 06:44:48 +0800

enixser gravatar image enixser
185 3

updated 2008-09-18 13:57:42 +0800

What do you expect from my code? I only want to know how the content of the textbox is set when the user select a date from the calendar popup. Which method of the Datebox class is called? In 3.0.7 it was setText(). which is called in 3.5.0?

link publish delete flag offensive edit

answered 2008-10-06 20:57:19 +0800

blandrp gravatar image blandrp
72 2

updated 2008-10-06 20:58:15 +0800

Has anyone ever figured this out? I am also trying to figure out how the value typed into the Datebox is converted into an actual Date object, but haven't been able to work out the sequence being followed by the Datebox. I believe that it may be related to the issue described above and illustrated by the example below.

I've provided some example code that worked in 3.0.7 but no longer works in 3.5.0. All it does is declares a datebox that uses a custom Datebox implementation. The custom Datebox implementation simply writes a statement to System.out anytime the text of the Datebox component is set.

sample.zul
----------
<?xml version="1.0" encoding="UTF-8"?>
<?page title="Test" id="test" ?>
<window id="testWin" xmlns="http://www.zkoss.org/2005/zul"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd"
width="95%" position="center" sclass="body1">
<vbox>
Some Text here
<datebox format="MM/dd/yyyy" use="com.test.MyDatebox" />
</vbox>
</window>

MyDatebox
---------
package com.test;

import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zul.Datebox;

public class MyDatebox extends Datebox {

/*
* (non-Javadoc)
*
* @see org.zkoss.zul.impl.InputElement#setText(java.lang.String)
*/
@Override
public void setText(String value) throws WrongValueException {
System.out.println("Setting value of datebox: " + value);
super.setText(value);
}

}

link publish delete flag offensive edit

answered 2008-10-07 03:41:42 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

Hi,

In ZK 3.5.0, datebox has optimized for date formatting from server to client. Therefore, when users choose a date, it won't send to server side.
If you want to know when users choose a date, you can register an onChange event.
For example,

 <datebox format="MM/dd/yyyy" onChange="" use="com.test.MyDatebox" />

Note that ZK specifications do not guarantee the formatting and the validation will finish by server side only.

link publish delete flag offensive edit

answered 2008-10-07 15:31:33 +0800

blandrp gravatar image blandrp
72 2

Is there any way, then, to override the default Datebox so that users can specify multiple entry formats? For example, what I was trying to accomplish was overriding the default Datebox to take a format string that contained multiple formats separated with semi-colons. It would then use the first format as the display format, but accept input in any of the specified formats. An example of the ZUL for this is shown below. Since none of the methods on the Datebox seem to be called during execution I'm not sure how this could be accomplished in ZK 3.5.0.

<datebox format="MM/dd/yyyy;MM/dd/yy;MMddyy;MMddyyyy;MM-dd-yy;MM-dd-yyyy" use="com.test.MultiFormatDatebox" />

link publish delete flag offensive edit

answered 2008-10-08 02:34:11 +0800

jumperchen gravatar image jumperchen
3909 2 8
http://jumperchen.blogspo... ZK Team

Yes, you can. But you have to customize the db.js from zul\src\archive\web\js\zul\ directory.

link publish delete flag offensive edit

answered 2008-10-16 19:46:11 +0800

blandrp gravatar image blandrp
72 2

I was able to get this working. I had to write some JavaScript to handle the dynamic behavior of the Datebox, and also had to override some code in the Datebox class to initialize the Datebox properly. To use my code I have to include <script type="text/javascript" src="[PATH TO FILE]/multi-db.js"></script> and also specify a new class for the Datebox <datebox use="com.test.MultiFormatDatebox" />. I have included the contents of multi-db.js and MultiFormatDatebox below in case anyone else needs it. Any chance something like this could be included in a future version of ZK?

multi-db.js
-----------
/**
* This file can be used to override the default JavaScript implementation for a Datebox
* to enable it to accept multiple formats.<b>
*
* Robert P. Bland III
* Oct 13, 2008 5:03 PM
*/

var defaultDateFormats = "MM/dd/yyyy;MMddyyyy;MMddyy";

//Date//
/** Parses a string into a Date object.
* @param strict whether not to lenient
*/
zk.parseDate = function (txt, fmt, strict) {
if (!fmt) fmt = defaultDateFormats;
var y = 0, m = 0, d = 0;

var fs = fmt.split(";");
for (var fi = 0; fi < fs.length; fi++) {
fmt = fs;
var ts = txt.split(/\W+/);
for (var i = 0, j = 0, fl = fmt.length; j < fl; ++j) {
var cc = fmt.charAt(j);
if ((cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')) {
var len = 1;
for (var k = j; ++k < fl; ++len)
if (fmt.charAt(k) != cc)
break;

var nosep; //no separator
if (k < fl) {
var c2 = fmt.charAt(k);
nosep = c2 == 'y' || c2 == 'M' || c2 == 'd' || c2 == 'E';
}

var token = ts[i++];
switch (cc) {
case 'y':
if (nosep) {
if (len <= 3) len = 2;
if (token.length > len) {
ts[--i] = token.substring(len);
token = token.substring(0, len);
}
}

y = $int(token);
if (isNaN(y)) {
break; //failed
}
if (y < 100) y += y > 29 ? 1900 : 2000;
break;
case 'M':
if (len == 3){
switch (token.toLowerCase()){
case 'jan':
m=0;
break;
case 'feb':
m=1;
break;
case 'mar':
m=2;
break;
case 'apr':
m=3;
break;
case 'may':
m=4;
break;
case 'jun':
m=5;
break;
case 'jul':
m=6;
break;
case 'aug':
m=7;
break;
case 'sep':
m=8;
break;
case 'oct':
m=9;
break;
case 'nov':
m=10;
break;
case 'dec':
m=11;
break;
default:
if (isNaN(m)) {
break; //failed
}
}
break;
}else if (len <= 2) {
if (nosep && token.length > 2) {
ts[--i] = token.substring(2);
token = token.substring(0, 2);
}
m = $int(token) - 1;
if (isNaN(m)) {
break; //failed
}
} else {
for (var l = 0;; ++l) {
if (l == 12) {
break; //failed
}
if (len == 3) {
if (zk.SMON.split(/\W+/)[0] == token) {
m = l;
break;
}
} else {
if (zk.FMON.split(/\W+/)[0] == token) {
m = l;
break;
}
}
}
}
break;
case 'd':
if (nosep) {
if (len < 2) len = 2;
if (token.length > len) {
ts[--i] = token.substring(len);
token = token.substring(0, len);
}
}
d = $int(token);
if (isNaN(d)) {
break; //failed
}
break;
//default: ignored
}
j = k - 1;
}
}
if (y != 0 && m != 0 && d != 0) {
break;
}
}

if (y == 0 || m == 0 || d == 0) return null;

var dt = new Date(y, m, d);
if (strict) {
if (dt.getFullYear() != y || dt.getMonth() != m || dt.getDate() != d)
return null; //failed

txt = txt.trim();
txt = zk._ckDate(zk.SDOW, txt);
txt = zk._ckDate(zk.S2DOW, txt);
txt = zk._ckDate(zk.FDOW, txt);
txt = zk._ckDate(zk.SMON, txt);
txt = zk._ckDate(zk.S2MON, txt);
txt = zk._ckDate(zk.FMON, txt);
txt = zk._ckDate(zk.APM, txt);
for (var j = txt.length; --j >= 0;) {
var cc = txt.charAt(j);
if ((cc > '9' || cc < '0') && fmt.indexOf(cc) < 0)
return null; //failed
}
}
return dt;
};

/** Generates a formated string for the specified Date object. */
zk.formatDate = function (val, fmt) {
if (!fmt) fmt = "yyyy/MM/dd";

var txt = "";
var fs = fmt.split(";");
fmt = fs[0];
for (var j = 0, fl = fmt.length; j < fl; ++j) {
var cc = fmt.charAt(j);
if ((cc >= 'a' && cc <= 'z') || (cc >= 'A' && cc <= 'Z')) {
var len = 1;
for (var k = j; ++k < fl; ++len)
if (fmt.charAt(k) != cc)
break;

switch (cc) {
case 'y':
if (len <= 3) txt += zk.formatFixed(val.getFullYear() % 100, 2);
else txt += zk.formatFixed(val.getFullYear(), len);
break;
case 'M':
if (len <= 2) txt += zk.formatFixed(val.getMonth()+1, len);
else if (len == 3) txt += zk.SMON[val.getMonth()];
else txt += zk.FMON[val.getMonth()];
break;
case 'd':
txt += zk.formatFixed(val.getDate(), len);
break;
case 'E':
if (len <= 3) txt += zk.SDOW[val.getDay()];
else txt += zk.FDOW[val.getDay()];
break;
case 'D':
txt += zk.dayInYear(val);
break;
case 'd':
txt += zk.dayInMonth(val);
break;
case 'w':
txt += zk.weekInYear(val);
break;
case 'W':
txt += zk.weekInMonth(val);
break;
case 'G':
txt += "AD";
break;
case 'F':
txt += zk.dayOfWeekInMonth(val);
break;
default:
txt += '1';
//fake; SimpleDateFormat.parse might ignore it
//However, it must be an error if we don't generate a digit
}
j = k - 1;
} else {
txt += cc;
}
}
return txt;
};


MultiFormatDatebox.java
-----------------------
package com.test;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.zkoss.zul.Datebox;

/**
* <p>
* </p>
* <p>
* Created: Oct 6, 2008 1:19:59 PM
* </p>
* <p>
* <table border="1" cellpaddding="2" cellspacing="2" >
* <tr>
* <td align="center" colspan="3">UPDATES</td>
* </tr>
* <tr>
* <td align="center">DATE</td>
* <td align="center">DEVELOPER</td>
* <td align="center">CHANGES</td>
* </tr>
* </table>
* </p>
*
* @author Robert P. Bland III
*/
public class MultiFormatDatebox extends Datebox {
public final static String DEFAULT_DATE_FORMAT = "MM/dd/yyyy;MMddyyyy";

public final static String FORMAT_SEPARATOR = ";";

private List<String> formats = null;

/* (non-Javadoc)
* @see org.zkoss.zul.Datebox#coerceToString(java.lang.Object)
*/
@Override
protected String coerceToString(Object value) {
final String fmt = getFormats().isEmpty() ? getFormat() : getFormats().get(0);
final DateFormat df = getDateFormat(fmt);
return value != null ? df.format((Date)value): "";
}

/**
* @param format
* @return
*/
private String initializeFormats(String format) {
if (format == null || format.length() == 0) {
format = getDefaultFormat();
getFormats().add(format);
} else {
final StringTokenizer st = new StringTokenizer(format, FORMAT_SEPARATOR);
if (st.countTokens() == 0) {
format = getDefaultFormat();
getFormats().add(format);
} else {
while (st.hasMoreTokens()) {
final String token = st.nextToken();
getDateFormat(token); //make sure the format is correct
getFormats().add(token);
}
}
}
return format;
}

/**
* @return the formats
*/
private synchronized List<String> getFormats() {
if (formats == null) {
formats = new ArrayList<String>();
initializeFormats(getFormat());
}
return formats;
}

/*
* (non-Javadoc)
*
* @see org.zkoss.zul.Datebox#getDefaultFormat()
*/
@Override
protected String getDefaultFormat() {
return MultiFormatDatebox.DEFAULT_DATE_FORMAT;
}

}

link publish delete flag offensive edit

answered 2008-10-17 17:05:02 +0800

guleri gravatar image guleri
75 2

Very useful!
+1 for adding this functionality to the core. I might want to use this myself, after skimming the code above I only have some i18n worries. My preferred format would be dd.MM.yyyy;dd.MM.yy;ddMMyyyy;ddMMyy; that i think would work, but what about the month names? Mine says 'okt', 'des' etc, so some mapping here would make a killer component =)

link publish delete flag offensive edit

answered 2008-10-17 17:31:59 +0800

blandrp gravatar image blandrp
72 2

Since my app will only be a US English app I didn't worry too much about the i18n, but I realize that my solution isn't the best for that. I just found the appropriate code in the db.js file provided with ZK, copied it, and modified it to work through multiple formats. I'm not really sure how ZK handles the i18n of month names since this was all I found in their code.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2008-09-16 06:45:56 +0800

Seen: 1,206 times

Last updated: Oct 17 '08

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More