DateTime and Time widgets in Chiba 2.3

View: New views
2 Messages — Rating Filter:   Alert me  

DateTime and Time widgets in Chiba 2.3

by Vodoo Moth :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,
I have a few problems with the UI widgets used in Chiba 2.3 for bind elements with type "time" or "dateTime". I know, v2.3 will look "old" in some eyes but I hope someone encountered these problems before and can confirm these are bugs.

1- with " <xf:bind nodeset="datMaj" id="bind-3" type="time" />", the input field that is bound to this receives, as expected, a time widget for the user to select a time. BUT, when this element has "readonly=true()", the input field does not get disabled. Same goes for the widget, which is still accessible although the control is supposed to be "readonly". Inspecting the DOM tree with Firebug(Firefox) or DragonFly(Opera), the "xfreadonly" attribute is "undefined". When I change the type to anything else, the field is indeed disabled. When that type is "date", attribute "xfreadonly" is "true". I tried to set an alert in DropdownTimePicher.fillInTemplate and noticed that the initial value of xfreadonly is undefined.
To sum up, the problem is that the time widget does not reflect the "readonly" status as declared in the xhtml template.

2- when the type of a bind element is "dateTime", the dateTime widget does not appear: no icon, no "dojoAttachPoint" attribute in the DOM tree. I can see a DropdownDateTimePicker.js file in resources/scripts/chiba/widget.

If anyone ever noticed these, thanks for letting me know it.



     

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Chiba-users mailing list
Chiba-users@...
https://lists.sourceforge.net/lists/listinfo/chiba-users

Re: DateTime and Time widgets in Chiba 2.3

by Tambet Matiisen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I can confirm the second one. I never needed input widget for dateTime,
so it didn't bother me too much. I fixed some issues with output widget
tough. Timezones didn't work correctly in edge cases, so I replaced the
dateTime parsing code. Also, when the form was populated dynamically,
the dates didn't get localized. I attached the patches, in case you
happen to get these errors too.

In general I had to fix quite a many bugs in Chiba 2.3. I once posted my
patches to Trac, but then the Trac crashed and I haven't had time to
recreate all the testcases and explanations. I still have most of the
patches and sent them to Joern for review. But as you said, Chiba 2.3 is
not in active development any more. I don't know, if any of my patches
applies to 3.0.

  Tambet

Vodoo Moth wrote:

> Hi all,
> I have a few problems with the UI widgets used in Chiba 2.3 for bind elements with type "time" or "dateTime". I know, v2.3 will look "old" in some eyes but I hope someone encountered these problems before and can confirm these are bugs.
>
> 1- with " <xf:bind nodeset="datMaj" id="bind-3" type="time" />", the input field that is bound to this receives, as expected, a time widget for the user to select a time. BUT, when this element has "readonly=true()", the input field does not get disabled. Same goes for the widget, which is still accessible although the control is supposed to be "readonly". Inspecting the DOM tree with Firebug(Firefox) or DragonFly(Opera), the "xfreadonly" attribute is "undefined". When I change the type to anything else, the field is indeed disabled. When that type is "date", attribute "xfreadonly" is "true". I tried to set an alert in DropdownTimePicher.fillInTemplate and noticed that the initial value of xfreadonly is undefined.
> To sum up, the problem is that the time widget does not reflect the "readonly" status as declared in the xhtml template.
>
> 2- when the type of a bind element is "dateTime", the dateTime widget does not appear: no icon, no "dojoAttachPoint" attribute in the DOM tree. I can see a DropdownDateTimePicker.js file in resources/scripts/chiba/widget.
>
> If anyone ever noticed these, thanks for letting me know it.
>
>
>
>      
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
> trial. Simplify your report design, integration and deployment - and focus on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Chiba-users mailing list
> Chiba-users@...
> https://lists.sourceforge.net/lists/listinfo/chiba-users
>  

Index: C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/dojo-0.4/src/i18n/calendar/nls/et/gregorian.js
===================================================================
--- C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/dojo-0.4/src/i18n/calendar/nls/et/gregorian.js (revision 653)
+++ C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/dojo-0.4/src/i18n/calendar/nls/et/gregorian.js (revision 654)
@@ -19,12 +19,12 @@
  'dateFormat-full': "EEEE, d. MMMM yyyy",
  'dateFormat-long': "d. MMMM yyyy",
  'dateFormat-medium': "d. MMM yyyy",
- 'dateFormat-short': "dd.MM.yyyy",
+ 'dateFormat-short': "d.MM.yyyy",
 
- 'timeFormat-full': "h:mm:ss a v",
- 'timeFormat-long': "h:mm:ss a z",
- 'timeFormat-medium': "h:mm:ss a",
- 'timeFormat-short': "h:mm a",
+ 'timeFormat-full': "HH:mm:ss v",
+ 'timeFormat-long': "HH:mm:ss z",
+ 'timeFormat-medium': "HH:mm:ss",
+ 'timeFormat-short': "HH:mm:ss",
 
  eras: ['EK','PK']
 })
\ No newline at end of file
Index: C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/PresentationContext.js
===================================================================
--- C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/PresentationContext.js (revision 653)
+++ C:/Projects/xteeportal/chiba-web/src/main/webapp/resources/scripts/PresentationContext.js (revision 654)
@@ -119,9 +119,9 @@
   //    if(type ==null && getClassComponent(target.className, 1) != "string"){
   //        type="string";
   //    }
-    if (targetName == "output" && (type == undefined || type == "date")) {
-      type = "string";
-  }
+  //  if (targetName == "output" && (type == undefined || type == "date")) {
+  //    type = "string";
+  //}
   if (!tmpControl) {
     dojo.debug("PresentationContext.prototype.handleStateChanged: Create new " + type + " widget");
       switch (type) {
@@ -184,7 +184,20 @@
           case "date":
           case "time":
           case "dateTime":
-              if (targetName == 'output') break;
+              if (targetName == 'output')
+              {
+                if (value != null)
+                {
+                  dojo.require('dojo.date.serialize');
+                  dojo.require('dojo.date.format');
+                  var date = new Date();
+                  dojo.date.setIso8601(date, value);
+                  var selector = (type == 'dateTime' ? type : type + 'Only');
+                  value = dojo.date.format(date, {selector: selector, formatLength: 'short'});
+                  PresentationContext._setControlValue(targetId, value);
+                }
+                break;
+              }
 
   dojo.require("chiba.widget.DropdownDatePicker");
 

Index: C:/Projects/xteeportal/chiba-core/src/main/java/org/chiba/xml/xforms/ui/state/UIElementStateUtil.java
===================================================================
--- C:/Projects/xteeportal/chiba-core/src/main/java/org/chiba/xml/xforms/ui/state/UIElementStateUtil.java (revision 410)
+++ C:/Projects/xteeportal/chiba-core/src/main/java/org/chiba/xml/xforms/ui/state/UIElementStateUtil.java (revision 715)
@@ -112,6 +112,8 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.events.EventTarget;
+import org.w3c.util.DateParser;
+import org.w3c.util.InvalidDateException;
 
 import java.text.DateFormat;
 import java.text.NumberFormat;
@@ -310,9 +312,9 @@
      * @param value the string value to convert
      * @return returns a localized representation of the input string
      */
-    public static String localiseValue(BindingElement owner,Element state,String type, String value) throws ParseException {
+    public static String localiseValue(BindingElement owner,Element state,String type, String value) throws ParseException, InvalidDateException {
         Locale locale = (Locale) owner.getModel().getContainer().getProcessor().getContext().get(ChibaBean.CHIBA_LOCALE);
-        if(type == null) {
+        if(type == null || value == null || value.equals("")) {
             return value;
         }
         if(type.equalsIgnoreCase("float") ||
@@ -326,22 +328,11 @@
             formatter.setMaximumFractionDigits(Double.SIZE);
             return formatter.format(num.doubleValue());
         }else if(type.equalsIgnoreCase("date")){
-            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
-            Date d = sf.parse(value);
+            Date d = DateParser.parse(value);
             return DateFormat.getDateInstance(DateFormat.DEFAULT,locale).format(d);
         }else if(type.equalsIgnoreCase("dateTime")){
-
-            //hackery due to lacking pattern for ISO 8601 Timezone representation in SimpleDateFormat
-            String timezone = "";
-            if(value.length() > 19){
-                timezone =  " GMT" + value.substring(value.lastIndexOf(":")-3,value.length());
-                int devider =value.lastIndexOf(":");
-                value = value.substring(0,devider) + value.substring(devider+1,value.length());
-            }
-            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-            Date d = sf.parse(value);
-
-            return DateFormat.getDateTimeInstance(DateFormat.DEFAULT,DateFormat.DEFAULT,locale).format(d) + timezone;
+            Date d = DateParser.parse(value);
+            return DateFormat.getDateTimeInstance(DateFormat.DEFAULT,DateFormat.DEFAULT,locale).format(d);
         } else{
             return value;
         }
Index: C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/InvalidDateException.java
===================================================================
--- C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/InvalidDateException.java (revision 0)
+++ C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/InvalidDateException.java (revision 715)
@@ -0,0 +1,17 @@
+// InvalidDateException.java
+// $Id: InvalidDateException.java,v 1.1 2000/09/26 13:54:04 bmahe Exp $
+// (c) COPYRIGHT MIT, INRIA and Keio, 2000.
+// Please first read the full copyright statement in file COPYRIGHT.html
+package org.w3c.util;
+
+/**
+ * @version $Revision: 1.1 $
+ * @author  BenoÄ«t Mahé (bmahe@...)
+ */
+public class InvalidDateException extends Exception {
+
+    public InvalidDateException(String msg) {
+ super(msg);
+    }
+    
+}
Index: C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/DateParser.java
===================================================================
--- C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/DateParser.java (revision 0)
+++ C:/Projects/xteeportal/chiba-core/src/main/java/org/w3c/util/DateParser.java (revision 715)
@@ -0,0 +1,274 @@
+// DateParser.java
+// $Id: DateParser.java,v 1.5 2005/05/16 10:19:19 ylafon Exp $
+// (c) COPYRIGHT MIT, INRIA and Keio, 2000.
+// Please first read the full copyright statement in file COPYRIGHT.html
+package org.w3c.util;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+/**
+ * Date parser for ISO 8601 format
+ * http://www.w3.org/TR/1998/NOTE-datetime-19980827
+ * @version $Revision: 1.5 $
+ * @author  BenoÄ«t Mahé (bmahe@...)
+ * @author  Yves Lafon (ylafon@...)
+ */
+public class DateParser {
+
+    private static boolean check(StringTokenizer st, String token)
+ throws InvalidDateException
+    {
+ try {
+    if (st.nextToken().equals(token)) {
+ return true;
+    } else {
+ throw new InvalidDateException("Missing ["+token+"]");
+    }
+ } catch (NoSuchElementException ex) {
+    return false;
+ }
+    }
+
+    private static Calendar getCalendar(String isodate)
+     throws InvalidDateException
+    {
+ // YYYY-MM-DDThh:mm:ss.sTZD
+ StringTokenizer st = new StringTokenizer(isodate, "-T:.+Z", true);
+
+ Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ calendar.clear();
+ try {
+    // Year
+    if (st.hasMoreTokens()) {
+ int year = Integer.parseInt(st.nextToken());
+ calendar.set(Calendar.YEAR, year);
+    } else {
+ return calendar;
+    }
+    // Month
+    if (check(st, "-") && (st.hasMoreTokens())) {
+ int month = Integer.parseInt(st.nextToken()) -1;
+ calendar.set(Calendar.MONTH, month);
+    } else {
+ return calendar;
+    }
+    // Day
+    if (check(st, "-") && (st.hasMoreTokens())) {
+ int day = Integer.parseInt(st.nextToken());
+ calendar.set(Calendar.DAY_OF_MONTH, day);
+    } else {
+ return calendar;
+    }
+    // Hour
+    if (check(st, "T") && (st.hasMoreTokens())) {
+ int hour = Integer.parseInt(st.nextToken());
+ calendar.set(Calendar.HOUR_OF_DAY, hour);
+    } else {
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar;
+    }
+    // Minutes
+    if (check(st, ":") && (st.hasMoreTokens())) {
+ int minutes = Integer.parseInt(st.nextToken());
+ calendar.set(Calendar.MINUTE, minutes);
+    } else {
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ return calendar;
+    }
+
+    //
+    // Not mandatory now
+    //
+
+    // Secondes
+    if (! st.hasMoreTokens()) {
+ return calendar;
+    }
+    String tok = st.nextToken();
+    if (tok.equals(":")) { // secondes
+ if (st.hasMoreTokens()) {
+    int secondes = Integer.parseInt(st.nextToken());
+    calendar.set(Calendar.SECOND, secondes);
+    if (! st.hasMoreTokens()) {
+ return calendar;
+    }
+    // frac sec
+    tok = st.nextToken();
+    if (tok.equals(".")) {
+ // bug fixed, thx to Martin Bottcher
+ String nt = st.nextToken();
+ while(nt.length() < 3) {
+    nt += "0";
+ }
+ nt = nt.substring( 0, 3 ); //Cut trailing chars..
+ int millisec = Integer.parseInt(nt);
+ //int millisec = Integer.parseInt(st.nextToken()) * 10;
+ calendar.set(Calendar.MILLISECOND, millisec);
+ if (! st.hasMoreTokens()) {
+    return calendar;
+ }
+ tok = st.nextToken();
+    } else {
+ calendar.set(Calendar.MILLISECOND, 0);
+    }
+ } else {
+    throw new InvalidDateException("No secondes specified");
+ }
+    } else {
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+    }
+    // Timezone
+    if (! tok.equals("Z")) { // UTC
+ if (! (tok.equals("+") || tok.equals("-"))) {
+    throw new InvalidDateException("only Z, + or - allowed");
+ }
+ boolean plus = tok.equals("+");
+ if (! st.hasMoreTokens()) {
+    throw new InvalidDateException("Missing hour field");
+ }
+ int tzhour = Integer.parseInt(st.nextToken());
+ int tzmin  = 0;
+ if (check(st, ":") && (st.hasMoreTokens())) {
+    tzmin = Integer.parseInt(st.nextToken());
+ } else {
+    throw new InvalidDateException("Missing minute field");
+ }
+ if (plus) {
+    calendar.add(Calendar.HOUR, -tzhour);
+    calendar.add(Calendar.MINUTE, -tzmin);
+ } else {
+    calendar.add(Calendar.HOUR, tzhour);
+    calendar.add(Calendar.MINUTE, tzmin);
+ }
+    }
+ } catch (NumberFormatException ex) {
+    throw new InvalidDateException("["+ex.getMessage()+
+   "] is not an integer");
+ }
+ return calendar;
+    }
+
+    /**
+     * Parse the given string in ISO 8601 format and build a Date object.
+     * @param isodate the date in ISO 8601 format
+     * @return a Date instance
+     * @exception InvalidDateException if the date is not valid
+     */
+    public static Date parse(String isodate)
+     throws InvalidDateException
+    {
+ Calendar calendar = getCalendar(isodate);
+ return calendar.getTime();
+    }
+
+    private static String twoDigit(int i) {
+ if (i >=0 && i < 10) {
+    return "0"+String.valueOf(i);
+ }
+ return String.valueOf(i);
+    }
+
+    /**
+     * Generate a ISO 8601 date
+     * @param date a Date instance
+     * @return a string representing the date in the ISO 8601 format
+     */
+    public static String getIsoDate(Date date) {
+ Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ calendar.setTime(date);
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(calendar.get(Calendar.YEAR));
+ buffer.append("-");
+ buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1));
+ buffer.append("-");
+ buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH)));
+ buffer.append("T");
+ buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY)));
+ buffer.append(":");
+ buffer.append(twoDigit(calendar.get(Calendar.MINUTE)));
+ buffer.append(":");
+ buffer.append(twoDigit(calendar.get(Calendar.SECOND)));
+ buffer.append(".");
+ buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10));
+ buffer.append("Z");
+ return buffer.toString();
+    }
+
+    /**
+     * Generate a ISO 8601 date
+     * @param date a Date instance
+     * @return a string representing the date in the ISO 8601 format
+     */
+    public static String getIsoDateNoMillis(Date date) {
+ Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ calendar.setTime(date);
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(calendar.get(Calendar.YEAR));
+ buffer.append("-");
+ buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1));
+ buffer.append("-");
+ buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH)));
+ buffer.append("T");
+ buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY)));
+ buffer.append(":");
+ buffer.append(twoDigit(calendar.get(Calendar.MINUTE)));
+ buffer.append(":");
+ buffer.append(twoDigit(calendar.get(Calendar.SECOND)));
+ buffer.append("Z");
+ return buffer.toString();
+    }
+
+    public static void test(String isodate) {
+ System.out.println("----------------------------------");
+ try {
+    Date date = parse(isodate);
+    System.out.println(">> "+isodate);
+    System.out.println(">> "+date.toString()+" ["+date.getTime()+"]");
+    System.out.println(">> "+getIsoDate(date));
+ } catch (InvalidDateException ex) {
+    System.err.println(isodate+" is invalid");
+    System.err.println(ex.getMessage());
+ }
+ System.out.println("----------------------------------");
+    }
+
+    public static void test(Date date) {
+ String isodate = null;
+ System.out.println("----------------------------------");
+ try {
+    System.out.println(">> "+date.toString()+" ["+date.getTime()+"]");
+    isodate = getIsoDate(date);
+    System.out.println(">> "+isodate);
+    date = parse(isodate);
+    System.out.println(">> "+date.toString()+" ["+date.getTime()+"]");
+ } catch (InvalidDateException ex) {
+    System.err.println(isodate+" is invalid");
+    System.err.println(ex.getMessage());
+ }
+ System.out.println("----------------------------------");
+    }
+
+    public static void main(String args[]) {
+ test("1997-07-16T19:20:30.45-02:00");
+ test("1997-07-16T19:20:30+01:00");
+ test("1997-07-16T19:20:30+01:00");
+ test("1997-07-16T12:20:30-06:00");
+ test("1997-07-16T19:20");
+ test("1997-07-16");
+ test("1997-07");
+ test("1997");
+ test(new Date());
+    }
+    
+}

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Chiba-users mailing list
Chiba-users@...
https://lists.sourceforge.net/lists/listinfo/chiba-users