You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2012/07/10 11:33:18 UTC

svn commit: r1359538 - in /myfaces/tobago/trunk: tobago-core/src/main/java/org/apache/myfaces/tobago/model/ tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/ tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/ tobago-e...

Author: lofwyr
Date: Tue Jul 10 09:33:17 2012
New Revision: 1359538

URL: http://svn.apache.org/viewvc?rev=1359538&view=rev
Log:
TOBAGO-1173: Refactor Scripting of the Date/Time/Calender components
 - Using jQuery.
 - Removing Scripts and onXXX event handlers from the renderer classes.
 - using data-attributes (HTML5) instead of hidden fields.
 - using Tobago.registerListener for initialization of the DOM

Modified:
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/CalendarModel.java
    myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
    myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/DataAttributesUnitTest.java
    myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/reference/time.jsp
    myfaces/tobago/trunk/tobago-theme/tobago-theme-richmond/src/main/resources/org/apache/myfaces/tobago/renderkit/html/richmond/standard/style/style.css
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/CalendarRenderer.java
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DatePickerRenderer.java
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DateRenderer.java
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/InRenderer.java
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TimeRenderer.java
    myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css
    myfaces/tobago/trunk/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/style.less
    myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-calendar.js

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/CalendarModel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/CalendarModel.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/CalendarModel.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/model/CalendarModel.java Tue Jul 10 09:33:17 2012
@@ -17,12 +17,6 @@ package org.apache.myfaces.tobago.model;
  * limitations under the License.
  */
 
-/*
- * Created: Nov 20, 2002 10:05:10 PM
- * $Id$
- */
-
-
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
@@ -31,7 +25,6 @@ public class CalendarModel {
 
   private DateModel[][] calendarArray;
   private int firstDayOffset;
-  //private int firstDayOfWeek;
 
   public CalendarModel(Calendar calendar) {
 //    int weekCount = CalendarUtils.weekCount(calendar);
@@ -42,7 +35,6 @@ public class CalendarModel {
     c.set(Calendar.DAY_OF_MONTH, 1);
     // assert c.isLenient() : "'add -x days' may not work in a non-lenient calendar";
     firstDayOffset = firstDayOffset(c);
-    //firstDayOfWeek = c.getFirstDayOfWeek();
     c.add(Calendar.DAY_OF_WEEK, -firstDayOffset);
     for (int week = 0; week < weekCount; ++week) {
       for (int day = 0; day < 7; ++day) {

Modified: myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/html/DataAttributes.java Tue Jul 10 09:33:17 2012
@@ -25,6 +25,22 @@ package org.apache.myfaces.tobago.render
 public final class DataAttributes {
 
   /**
+   * Custom command attribute. Is used to mark different client side JavaScript buttons.
+   * Should only contain the command name as a keyword, for security reasons.
+   */
+  public static final String COMMAND = "data-tobago-command";
+
+  /**
+   * Reference to the corresponding date input field. Used for date picker popups.
+   */
+  public static final String DATEINPUTID = "data-tobago-dateinputid";
+
+  /**
+   * Holds the day of a calendar control.
+   */
+  public static final String DAY = "data-tobago-day";
+
+  /**
    * Custom disabled attribute. Use for element, that don't have the disabled attribute.
    */
   public static final String DISABLED = "data-tobago-disabled";
@@ -35,6 +51,31 @@ public final class DataAttributes {
   public static final String DEFAULT = "data-tobago-default";
 
   /**
+   * Holds the first day of a week of a calendar control.
+   */
+  public static final String FIRSTDAYOFWEEK = "data-tobago-firstdayofweek";
+
+  /**
+   * Defines a maximum value.
+   */
+  public static final String MAX = "data-tobago-max";
+
+  /**
+   * Holds the month of a calendar control.
+   */
+  public static final String MONTH = "data-tobago-month";
+
+  /**
+   * Holds the names of the months of a calendar control.
+   */
+  public static final String MONTHNAMES = "data-tobago-monthnames";
+
+  /**
+   * Custom attribute to describe a pattern, e. g. for an date input field.
+   */
+  public static final String PATTERN = "data-tobago-pattern";
+
+  /**
    * Custom reload attribute. Used to reload a panel.
    */
   public static final String RELOAD = "data-tobago-reload";
@@ -63,4 +104,15 @@ public final class DataAttributes {
    * Id of the parent node in a tree node.
    */
   public static final String TREEPARENT = "data-tobago-treeparent";
+
+  /**
+   * Defines the unit, e. g. to differ between hours, minutes and seconds in a time control.
+   */
+  public static final String UNIT = "data-tobago-unit";
+
+  /**
+   * Holds the year of a calendar control.
+   */
+  public static final String YEAR = "data-tobago-year";
+
 }

Modified: myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/DataAttributesUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/DataAttributesUnitTest.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/DataAttributesUnitTest.java (original)
+++ myfaces/tobago/trunk/tobago-core/src/test/java/org/apache/myfaces/tobago/renderkit/html/DataAttributesUnitTest.java Tue Jul 10 09:33:17 2012
@@ -24,17 +24,16 @@ import java.lang.reflect.Field;
 
 public class DataAttributesUnitTest {
 
-  public static final String PREFIX = "data-tobago-";
-
   @Test
   public void testAttributeNames() throws IllegalAccessException {
     for (Field field : DataAttributes.class.getFields()) {
+
       String value = (String) field.get(null);
-      Assert.assertTrue("Prefix check: value='" + value + "'", value.startsWith(PREFIX));
-      String extension = value.substring(PREFIX.length());
-      Assert.assertTrue("Regexp check: extension='" + extension + "'", extension.matches("[a-z]+(-[a-z]+)*"));
-      String fieldExtension = field.getName().toLowerCase().replace('_', '-');
-      Assert.assertEquals(fieldExtension, extension);
+      Assert.assertTrue("Regexp check: value='" + value + "'", value.matches("data-tobago-[a-z]+"));
+
+      String extension = value.substring("data-tobago-".length());
+      String name = field.getName();
+      Assert.assertEquals(name, extension.toUpperCase());
     }
   }
 }

Modified: myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/reference/time.jsp
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/reference/time.jsp?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/reference/time.jsp (original)
+++ myfaces/tobago/trunk/tobago-example/tobago-example-demo/src/main/webapp/reference/time.jsp Tue Jul 10 09:33:17 2012
@@ -28,7 +28,7 @@
   <jsp:body>
       <tc:box label="Time Specific Controls">
         <f:facet name="layout">
-          <tc:gridLayout columns="400px;*" rows="auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;250px;*"/>
+          <tc:gridLayout columns="400px;*" rows="auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;auto;250px;*"/>
         </f:facet>
         <%-- code-sniplet-start id="date" --%>
         <tx:date label="Date" value="#{now}">
@@ -89,6 +89,26 @@
         </tx:time>
         <tc:cell/>
 
+        <tx:time label="Time" value="#{now}" readonly="true">
+          <f:convertDateTime type="time"  pattern="HH:mm"/>
+        </tx:time>
+        <tc:cell/>
+
+        <tx:time label="Time (Seconds)" value="#{now}" readonly="true">
+          <f:convertDateTime type="time" pattern="HH:mm:ss"/>
+        </tx:time>
+        <tc:cell/>
+
+        <tx:time label="Time" value="#{now}" disabled="true">
+          <f:convertDateTime type="time"  pattern="HH:mm"/>
+        </tx:time>
+        <tc:cell/>
+
+        <tx:time label="Time (Seconds)" value="#{now}" disabled="true">
+          <f:convertDateTime type="time" pattern="HH:mm:ss"/>
+        </tx:time>
+        <tc:cell/>
+
         <%-- code-sniplet-start id="calendar" --%>
         <tc:calendar />
         <%-- code-sniplet-end id="calendar" --%>

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-richmond/src/main/resources/org/apache/myfaces/tobago/renderkit/html/richmond/standard/style/style.css
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-richmond/src/main/resources/org/apache/myfaces/tobago/renderkit/html/richmond/standard/style/style.css?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-richmond/src/main/resources/org/apache/myfaces/tobago/renderkit/html/richmond/standard/style/style.css (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-richmond/src/main/resources/org/apache/myfaces/tobago/renderkit/html/richmond/standard/style/style.css Tue Jul 10 09:33:17 2012
@@ -332,7 +332,7 @@ li.tobago-menu-markup-selected {
   color: #3366CC;
 }
 
-.tobago-time-input-markup-selected {
+.tobago-time-input:focus {
   background: #D6EBFF;
 }
 

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/CalendarRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/CalendarRenderer.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/CalendarRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/CalendarRenderer.java Tue Jul 10 09:33:17 2012
@@ -27,13 +27,11 @@ import org.apache.myfaces.tobago.model.D
 import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
-import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
 import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
@@ -46,22 +44,13 @@ import java.util.Locale;
 
 public class CalendarRenderer extends LayoutComponentRendererBase {
 
-  private static final Logger LOG = LoggerFactory.getLogger(CalendarRenderer.class);
-
-
   @Override
   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
 
     UICalendar output = (UICalendar) component;
     String id = output.getClientId(facesContext);
-    String dateTextBoxId = (String) component.getAttributes().get(Attributes.DATE_INPUT_ID);
-
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("dateTextBoxId = '" + dateTextBoxId + "'");
-    }
 
     Locale locale = facesContext.getViewRoot().getLocale();
-    SimpleDateFormat dateFormat = new SimpleDateFormat("MMMMM yyyy", locale);
 
     Object value = output.getValue();
     Calendar calendar;
@@ -83,6 +72,16 @@ public class CalendarRenderer extends La
     writer.writeClassAttribute(Classes.create(output));
     Style style = new Style(facesContext, output);
     writer.writeStyleAttribute(style);
+    String dateInputId = (String) output.getAttributes().get(Attributes.DATE_INPUT_ID);
+    if (dateInputId != null) {
+      writer.writeAttribute(DataAttributes.DATEINPUTID, dateInputId, false);
+    }
+    writer.writeAttribute(DataAttributes.DAY, Integer.toString(calendar.get(Calendar.YEAR)), false);
+    writer.writeAttribute(DataAttributes.MONTH, Integer.toString(1 + calendar.get(Calendar.MONTH)), false);
+    writer.writeAttribute(DataAttributes.YEAR, Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)), false);
+
+    writer.writeAttribute(DataAttributes.FIRSTDAYOFWEEK, Integer.toString(calendar.getFirstDayOfWeek()), false);
+    writer.writeAttribute(DataAttributes.MONTHNAMES, getMonthNames(locale), false);
 
     // begin header
     writer.startElement(HtmlElements.DIV, null);
@@ -93,7 +92,7 @@ public class CalendarRenderer extends La
     writer.writeAttribute(HtmlAttributes.ALT, "", false);
     writer.writeAttribute(HtmlAttributes.SRC,
         ResourceManagerUtils.getImageWithPath(facesContext, "image/calendarFastPrev.gif"), false);
-    writer.writeAttribute(HtmlAttributes.ONCLICK, "addMonth('" + id + "', -12)", false);
+    writer.writeAttribute(DataAttributes.COMMAND, "fastPrev", false);
     writer.endElement(HtmlElements.IMG);
 
     writer.startElement(HtmlElements.IMG, null);
@@ -101,13 +100,24 @@ public class CalendarRenderer extends La
     writer.writeAttribute(HtmlAttributes.ALT, "", false);
     writer.writeAttribute(HtmlAttributes.SRC,
         ResourceManagerUtils.getImageWithPath(facesContext, "image/calendarPrev.gif"), false);
-    writer.writeAttribute(HtmlAttributes.ONCLICK, "addMonth('" + id + "', -1)", false);
+    writer.writeAttribute(DataAttributes.COMMAND, "prev", false);
     writer.endElement(HtmlElements.IMG);
 
     writer.startElement(HtmlElements.SPAN, null);
     writer.writeClassAttribute(Classes.create(output, "header"));
-    writer.writeIdAttribute(id + ":title"); // todo: ComponentUtils.SUB_SEPARATOR
-    writer.writeText(dateFormat.format(calendar.getTime()));
+
+    writer.startElement(HtmlElements.SPAN, null);
+    writer.writeAttribute(DataAttributes.COMMAND, "month", false);
+    writer.writeText(new SimpleDateFormat("MMMMM", locale).format(calendar.getTime()));
+    writer.endElement(HtmlElements.SPAN);
+
+    writer.writeText(" "); // non breaking space
+
+    writer.startElement(HtmlElements.SPAN, null);
+    writer.writeAttribute(DataAttributes.COMMAND, "year", false);
+    writer.writeText(new SimpleDateFormat("yyyy", locale).format(calendar.getTime()));
+    writer.endElement(HtmlElements.SPAN);
+
     writer.endElement(HtmlElements.SPAN);
 
     writer.startElement(HtmlElements.IMG, null);
@@ -115,7 +125,7 @@ public class CalendarRenderer extends La
     writer.writeAttribute(HtmlAttributes.ALT, "", false);
     writer.writeAttribute(HtmlAttributes.SRC,
         ResourceManagerUtils.getImageWithPath(facesContext, "image/calendarNext.gif"), false);
-    writer.writeAttribute(HtmlAttributes.ONCLICK, "addMonth('" + id + "', 1)", false);
+    writer.writeAttribute(DataAttributes.COMMAND, "next", false);
     writer.endElement(HtmlElements.IMG);
 
     writer.startElement(HtmlElements.IMG, null);
@@ -123,7 +133,7 @@ public class CalendarRenderer extends La
     writer.writeAttribute(HtmlAttributes.ALT, "", false);
     writer.writeAttribute(HtmlAttributes.SRC,
         ResourceManagerUtils.getImageWithPath(facesContext, "image/calendarFastNext.gif"), false);
-    writer.writeAttribute(HtmlAttributes.ONCLICK, "addMonth('" + id + "', 12)", false);
+    writer.writeAttribute(DataAttributes.COMMAND, "fastNext", false);
     writer.endElement(HtmlElements.IMG);
 
     writer.endElement(HtmlElements.DIV);
@@ -133,10 +143,10 @@ public class CalendarRenderer extends La
     writer.startElement(HtmlElements.DIV, null);
     writer.writeClassAttribute(Classes.create(output, "row"));
 
-    dateFormat = new SimpleDateFormat("E", locale);
+    SimpleDateFormat dayInWeekFormat = new SimpleDateFormat("E", locale);
     for (int dayIt = 0; dayIt < 7; ++dayIt) {
       DateModel date = model.getDate(0, dayIt);
-      String dayName = dateFormat.format(date.getCalendar().getTime());
+      String dayName = dayInWeekFormat.format(date.getCalendar().getTime());
       dayName = StringUtils.substring(dayName, 0, 2);
 
       writer.startElement(HtmlElements.SPAN, null);
@@ -148,81 +158,38 @@ public class CalendarRenderer extends La
     writer.endElement(HtmlElements.DIV);
     // end weeks
 
-//    int weekCount = model.getWeekCount();
+    // begin grid
+    writer.startElement(HtmlElements.DIV, null);
+    writer.writeClassAttribute(Classes.create(output, "grid"));
     for (int week = 0; week < 6; ++week) {
-//    String style = (week < weekCount) ? "" : "style=\"display: none\"";
       writer.startElement(HtmlElements.DIV, null);
-      writer.writeIdAttribute(id + ":" + week);
       writer.writeClassAttribute(Classes.create(output, "row"));
-//      writer.writeAttribute(HtmlAttributes.STYLE, style, null);
 
       for (int dayIt = 0; dayIt < 7; ++dayIt) {
-//      if (week < weekCount) {
         DateModel date = model.getDate(week, dayIt);
         String dayDescription = String.valueOf(date.getDay());
-        String onclick = "selectDay('" + id + "', " + week + " , " + dayIt + ");";
 
         writer.startElement(HtmlElements.SPAN, null);
-        writer.writeAttribute(HtmlAttributes.ONCLICK, onclick, true);
-        writer.writeIdAttribute(id + ":" + week + ":" + dayIt);
         writer.writeClassAttribute(
             Classes.create(output, "day", date.getMonth() == model.getMonth() ? null : Markup.DISABLED));
 
         writer.writeText(dayDescription);
 
         writer.endElement(HtmlElements.SPAN);
-
-//      } else {
-//        % ><td id="< %= id + ":" + week + ":" + day % >">x</td>< %
-//      }
       }
       writer.endElement(HtmlElements.DIV);
     }
     writer.endElement(HtmlElements.DIV);
+    // end grid
 
-    writeInputHidden(writer, "/" + id + "/year", id + ":year", Integer.toString(calendar.get(Calendar.YEAR)));
-
-    writeInputHidden(writer, "/" + id + "/month", id + ":month", Integer.toString(1 + calendar.get(Calendar.MONTH)));
-
-    writeInputHidden(writer, "/" + id + "/day", id + ":day", Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
-
-    writeInputHidden(writer, id + ":firstDayOfWeek", Integer.toString(calendar.getFirstDayOfWeek()));
-
-    writeInputHidden(writer, id + ":monthNames", getMonthNames(locale));
-
-    writeInputHidden(writer, id + ":fieldId", "");
-
-    String[] cmd = {
-        "document.calendar = new Object();",
-        dateTextBoxId != null
-            ? "initCalendarParse('" + id + "', '" + dateTextBoxId + "');"
-            : ""
-    };
-    HtmlRendererUtils.writeScriptLoader(facesContext, null, cmd);
+    writer.endElement(HtmlElements.DIV);
   }
   
-  private void writeInputHidden(TobagoResponseWriter writer,
-       String id, String value) throws IOException {
-    writeInputHidden(writer, null, id, value);
-   }
-
-  private void writeInputHidden(TobagoResponseWriter writer, String name,
-      String id, String value) throws IOException {
-    writer.startElement(HtmlElements.INPUT, null);
-    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
-    if (name != null) {
-      writer.writeNameAttribute(name);
-    }
-    writer.writeIdAttribute(id);
-    writer.writeAttribute(HtmlAttributes.VALUE, value, true);
-    writer.endElement(HtmlElements.INPUT);
-  }
-
   private String getMonthNames(Locale locale) {
     SimpleDateFormat dateFormat = new SimpleDateFormat("MMMMM", locale);
     StringBuilder buffer = new StringBuilder(64);
     Calendar calendar = Calendar.getInstance();
-    calendar.set(2000, 0, 1);
+    calendar.set(2000, Calendar.JANUARY, 1);
     for (int month = 0; month < 12; ++month) {
       if (month > 0) {
         buffer.append(',');
@@ -234,4 +201,3 @@ public class CalendarRenderer extends La
   }
 
 }
-

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DatePickerRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DatePickerRenderer.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DatePickerRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DatePickerRenderer.java Tue Jul 10 09:33:17 2012
@@ -134,7 +134,9 @@ public class DatePickerRenderer extends 
         facesContext, UIButton.COMPONENT_TYPE, RendererTypes.BUTTON, "ok");
     buttonPanel.getChildren().add(okButton);
     FacesUtils.setBindingOrExpression(okButton, Attributes.LABEL, "#{tobagoContext.resourceBundle.datePickerOk}");
-    okButton.setOnclick("writeIntoField2(this);");
+    //    okButton.setOnclick("writeIntoField2(this);");
+    okButton.setOnclick("/* dummy to trick the CommandRendererHelper */");
+    // XXX find a way to mark this button as the "ok" button for the tobago-calendar.js! data-tobago-datepickerok
     okButton.getAttributes().put(Attributes.POPUP_CLOSE, "afterSubmit");
 
     final UIButton cancelButton = (UIButton) CreateComponentUtils.createComponent(

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DateRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DateRenderer.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DateRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/DateRenderer.java Tue Jul 10 09:33:17 2012
@@ -17,16 +17,13 @@ package org.apache.myfaces.tobago.render
  * limitations under the License.
  */
 
+import org.apache.myfaces.tobago.internal.component.AbstractUIInput;
 import org.apache.myfaces.tobago.internal.util.DateFormatUtils;
-import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
-import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
-import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
-import org.apache.myfaces.tobago.renderkit.html.util.HtmlRendererUtils;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.DateTimeConverter;
@@ -36,29 +33,23 @@ public class DateRenderer extends InRend
 
   private static final Logger LOG = LoggerFactory.getLogger(DateRenderer.class);
 
-
   @Override
-  public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
-
-    super.encodeEnd(facesContext, component);
+  protected void writeAdditionalAttributes(
+      FacesContext facesContext, TobagoResponseWriter writer, AbstractUIInput input) throws IOException {
+    super.writeAdditionalAttributes(facesContext, writer, input);
 
-    Converter help = getConverter(facesContext, component);
-    // TODO is this really needed?
+    Converter help = getConverter(facesContext, input);
     if (help instanceof DateTimeConverter) {
       DateTimeConverter converter = (DateTimeConverter) help;
       String pattern = DateFormatUtils.findPattern(converter);
 
-      if (pattern != null) {
-        TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
-        String id = component.getClientId(facesContext);
-        writer.startElement(HtmlElements.INPUT, component);
-        writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
-        writer.writeIdAttribute(id + ":converterPattern");
-        writer.writeAttribute(HtmlAttributes.VALUE, pattern, false);
-        writer.endElement(HtmlElements.INPUT);
-      } else {
-        LOG.warn("Can't find the pattern for the converter! DatePicker may not work correctly.");
+      if (pattern == null) {
+        pattern = "yyyy-MM-dd";
+        LOG.warn("Can't find the pattern for the converter! DatePicker may not work correctly. "
+            + "Trying to use: '" + pattern + "'");
       }
+
+      writer.writeAttribute(DataAttributes.PATTERN, pattern, true);
     }
   }
 }

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/InRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/InRenderer.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/InRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/InRenderer.java Tue Jul 10 09:33:17 2012
@@ -133,6 +133,7 @@ public class InRenderer extends InputRen
      //      writer.writeAttribute(HtmlAttributes.ONCHANGE, onchange, null);
        }
      } */
+      writeAdditionalAttributes(facesContext, writer, input);
       writer.endElement(HtmlElements.INPUT);
 
       HtmlRendererUtils.checkForCommandFacet(input, facesContext, writer);
@@ -166,6 +167,10 @@ public class InRenderer extends InputRen
     }
   }
 
+  protected void writeAdditionalAttributes(
+      FacesContext facesContext, TobagoResponseWriter writer, AbstractUIInput input) throws IOException {
+  }
+
   private void encodeAjax(FacesContext facesContext, UIComponent component) throws IOException {
     if (!(component instanceof UIIn)) {
       LOG.error("Wrong type: Need " + UIIn.class.getName() + ", but was " + component.getClass().getName());

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TimeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TimeRenderer.java?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TimeRenderer.java (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TimeRenderer.java Tue Jul 10 09:33:17 2012
@@ -17,11 +17,6 @@ package org.apache.myfaces.tobago.render
  * limitations under the License.
  */
 
-/*
- * Created 07.02.2003 16:00:00.
- * $Id$
- */
-
 import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.UITime;
 import org.apache.myfaces.tobago.context.Markup;
@@ -30,6 +25,7 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.renderkit.InputRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
+import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
@@ -52,12 +48,7 @@ public class TimeRenderer extends InputR
 
   private static final Logger LOG = LoggerFactory.getLogger(TimeRenderer.class);
 
-
   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
-    if (!(component instanceof UITime)) {
-      LOG.error("Wrong type: Need " + UITime.class.getName() + ", but was " + component.getClass().getName());
-      return;
-    }
 
     UITime time = (UITime) component;
 
@@ -67,18 +58,18 @@ public class TimeRenderer extends InputR
       LOG.debug("currentValue = '" + currentValue + "'");
     }
 
-    String converterPattern = "HH:mm";
+    String pattern = "HH:mm";
     if (time.getConverter() != null) {
       Converter converter = time.getConverter();
       if (converter instanceof DateTimeConverter) {
-        String pattern = DateFormatUtils.findPattern((DateTimeConverter) converter);
-        if (pattern != null && pattern.indexOf('s') > -1) {
-          converterPattern += ":ss";
+        String string = DateFormatUtils.findPattern((DateTimeConverter) converter);
+        if (string != null && string.indexOf('s') > -1) {
+          pattern += ":ss";
         }
       }
     }
 
-    boolean hasSeconds = converterPattern.indexOf('s') > -1;
+    boolean hasSeconds = pattern.indexOf('s') > -1;
 
     Object value = time.getValue();
     Date date;
@@ -96,77 +87,65 @@ public class TimeRenderer extends InputR
 
     String id = time.getClientId(facesContext);
     final String idPrefix = id + ComponentUtils.SUB_SEPARATOR;
-    TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+
+    final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
+
     writer.startElement(HtmlElements.DIV, time);
+    writer.writeIdAttribute(id);
     writer.writeClassAttribute(Classes.create(time));
     Style style = new Style(facesContext, time);
     writer.writeStyleAttribute(style);
+    String dateInputId = (String) time.getAttributes().get(Attributes.DATE_INPUT_ID);
+    if (dateInputId != null) {
+      writer.writeAttribute(DataAttributes.DATEINPUTID, dateInputId, false);
+    }
+    writer.writeAttribute(DataAttributes.PATTERN, pattern, false);
 
     writer.startElement(HtmlElements.DIV, time);
-    writer.writeAttribute(HtmlAttributes.ID, idPrefix + "borderDiv", false);
+    writer.writeIdAttribute(idPrefix + "borderDiv");
     Markup markup = time.getCurrentMarkup();
     if (hasSeconds) {
       markup = markup.add(Markup.SECONDS);
     }
     writer.writeClassAttribute(Classes.create(time, "borderDiv", markup));
 
-    writeInput(writer, time, idPrefix + "hour", hour, true, title);
+    writeInput(writer, time, idPrefix, "hour", hour, title, 24);
     writeInputSeparator(writer, time, ":");
-    writeInput(writer, time, idPrefix + "minute", minute, false, title);
+    writeInput(writer, time, idPrefix, "minute", minute, title, 60);
     if (hasSeconds) {
       writeInputSeparator(writer, time, ":");
-      writeInput(writer, time, idPrefix + "second", second, false, title);
+      writeInput(writer, time, idPrefix, "second", second, title, 60);
     }
 
     writer.endElement(HtmlElements.DIV);
 
-    String imageId = idPrefix + "inc";
-    String imageSrc = "image/timeIncrement.gif";
     writer.startElement(HtmlElements.IMG, null);
-    writer.writeIdAttribute(imageId);
+    writer.writeIdAttribute(idPrefix + "inc");
     writer.writeClassAttribute(Classes.create(time, "incImage", markup));
-    writer.writeAttribute(HtmlAttributes.SRC, ResourceManagerUtils.getImageWithPath(facesContext, imageSrc), true);
+    writer.writeAttribute(HtmlAttributes.SRC,
+        ResourceManagerUtils.getImageWithPath(facesContext, "image/timeIncrement.gif"), true);
     writer.writeAttribute(HtmlAttributes.ALT, "", false); // TODO: tip
-
-    if (!(ComponentUtils.getBooleanAttribute(time, Attributes.DISABLED)
-        || ComponentUtils.getBooleanAttribute(time, Attributes.READONLY))) {
-      writer.writeAttribute(HtmlAttributes.ONCLICK, "tbgIncTime(this)", false);
-    }
+    writer.writeAttribute(HtmlAttributes.READONLY, time.isReadonly());
+    writer.writeAttribute(HtmlAttributes.DISABLED, time.isDisabled());
     writer.endElement(HtmlElements.IMG);
 
-    imageId = idPrefix + "dec";
-    imageSrc = "image/timeDecrement.gif";
     writer.startElement(HtmlElements.IMG, null);
-    writer.writeIdAttribute(imageId);
+    writer.writeIdAttribute(idPrefix + "dec");
     writer.writeClassAttribute(Classes.create(time, "decImage", markup));
-    writer.writeAttribute(HtmlAttributes.SRC, ResourceManagerUtils.getImageWithPath(facesContext, imageSrc), true);
+    writer.writeAttribute(HtmlAttributes.SRC,
+        ResourceManagerUtils.getImageWithPath(facesContext, "image/timeDecrement.gif"), true);
     writer.writeAttribute(HtmlAttributes.ALT, "", false); // TODO: tip
-    if (!(ComponentUtils.getBooleanAttribute(time, Attributes.DISABLED)
-        || ComponentUtils.getBooleanAttribute(time, Attributes.READONLY))) {
-      writer.writeAttribute(HtmlAttributes.ONCLICK, "tbgDecTime(this)", false);
-    }
+    writer.writeAttribute(HtmlAttributes.READONLY, time.isReadonly());
+    writer.writeAttribute(HtmlAttributes.DISABLED, time.isDisabled());
     writer.endElement(HtmlElements.IMG);
 
     writer.startElement(HtmlElements.INPUT, time);
     writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
-    writer.writeIdAttribute(id + ":converterPattern");
-    writer.writeAttribute(HtmlAttributes.VALUE, converterPattern, true);
-    writer.endElement(HtmlElements.INPUT);
-
-    writer.startElement(HtmlElements.INPUT, time);
-    writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
-    writer.writeIdAttribute(id);
+    writer.writeIdAttribute(idPrefix + "field");
     writer.writeNameAttribute(id);
     writer.writeAttribute(HtmlAttributes.VALUE, hour + ":" + minute + ":" + second, false);
     writer.endElement(HtmlElements.INPUT);
 
-    String dateTextBoxId = (String) time.getAttributes().get(Attributes.DATE_INPUT_ID);
-
-    if (dateTextBoxId != null) {
-      String[] cmds = {"tbgInitTimeParse('" + id + "', '" + dateTextBoxId + "');"};
-      HtmlRendererUtils.writeScriptLoader(facesContext, null, cmds);
-    }
-
     writer.endElement(HtmlElements.DIV);
   }
 
@@ -177,27 +156,24 @@ public class TimeRenderer extends InputR
     writer.endElement(HtmlElements.SPAN);
   }
 
-  private void writeInput(TobagoResponseWriter writer, UITime input, String id, String hour, boolean hourMode,
-      String title) throws IOException {
+  private void writeInput(
+      TobagoResponseWriter writer, UITime input, String idPrefix, String unit, String value, String title, int max)
+      throws IOException {
     Integer tabIndex = input.getTabIndex();
     writer.startElement(HtmlElements.INPUT, null);
     writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.TEXT, false);
-    writer.writeIdAttribute(id);
+    writer.writeIdAttribute(idPrefix + unit);
     if (tabIndex != null) {
       writer.writeAttribute(HtmlAttributes.TABINDEX, tabIndex);
     }
     writer.writeAttribute(HtmlAttributes.TITLE, title, true);
 
     writer.writeClassAttribute(Classes.create(input, "input"));
-    writer.writeAttribute(HtmlAttributes.READONLY, ComponentUtils.getBooleanAttribute(input, Attributes.READONLY));
-    writer.writeAttribute(HtmlAttributes.DISABLED, ComponentUtils.getBooleanAttribute(input, Attributes.DISABLED));
-    if (!(ComponentUtils.getBooleanAttribute(input, Attributes.DISABLED)
-        || ComponentUtils.getBooleanAttribute(input, Attributes.READONLY))) {
-      writer.writeAttribute(HtmlAttributes.ONFOCUS, "tbgTimerInputFocus(this, " + hourMode + ")", false);
-      writer.writeAttribute(HtmlAttributes.ONBLUR, "tbgTimerInputBlur(this)", false);
-      writer.writeAttribute(HtmlAttributes.ONKEYUP, "tbgTimerKeyUp(this, event)", false);
-    }
-    writer.writeAttribute(HtmlAttributes.VALUE, hour, true);
+    writer.writeAttribute(HtmlAttributes.READONLY, input.isReadonly());
+    writer.writeAttribute(HtmlAttributes.DISABLED, input.isDisabled());
+    writer.writeAttribute(HtmlAttributes.VALUE, value, true);
+    writer.writeAttribute(DataAttributes.MAX, Integer.toString(max), true);
+    writer.writeAttribute(DataAttributes.UNIT, unit, true);
     writer.endElement(HtmlElements.INPUT);
   }
 }

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css Tue Jul 10 09:33:17 2012
@@ -1394,7 +1394,7 @@ div.tobago-richTextEditor-body {
   text-align: center;
 }
 
-.tobago-time-input-markup-selected {
+.tobago-time-input:focus {
   background-color: #fafad2;
 }
 

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/style.less
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/style.less?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/style.less (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-speyside/src/main/less/org/apache/myfaces/tobago/renderkit/html/speyside/standard/style/style.less Tue Jul 10 09:33:17 2012
@@ -847,7 +847,7 @@ div.tobago-tabGroup-toolBar {
   width: 21px;
 }
 
-.tobago-time-input-markup-selected {
+.tobago-time-input:focus {
   background: #E8E8E8;
 }
 

Modified: myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-calendar.js
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-calendar.js?rev=1359538&r1=1359537&r2=1359538&view=diff
==============================================================================
--- myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-calendar.js (original)
+++ myfaces/tobago/trunk/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-calendar.js Tue Jul 10 09:33:17 2012
@@ -15,72 +15,121 @@
  * limitations under the License.
  */
 
-if (!Calendar) {
-  var Calendar = new Object;
-}
-
-Calendar.MONTH_LENGTH = [31,28,31,30,31,30,31,31,30,31,30,31];
-
-Calendar.isLeapYear = function (year) {
-  return (year%4 == 0) 
-      && (year%100 != 0 || year%400 == 0);
-}
+Tobago.Calendar = {};
 
-Calendar.getMonthLength = function (month, year) {
-  if (month == 2 && Calendar.isLeapYear(year)) {
+Tobago.Calendar.init = function (elements) {
+  // init next/prev buttons
+  var buttons = Tobago.Utils.selectWidthJQuery(elements, ".tobago-calendar-header[data-tobago-command]");
+  buttons.each(function () {
+    var button = jQuery(this);
+    var step;
+    switch (button.data("tobago-command")) {
+      case "fastPrev":
+        step = -12;
+        break;
+      case "prev":
+        step = -1;
+        break;
+      case "next":
+        step = 1;
+        break;
+      case "fastNext":
+        step = 12;
+        break;
+      default:
+        // ignore
+        return;
+    }
+    button.click(function () {
+      Tobago.Calendar.addMonth(jQuery(this).parents(".tobago-calendar"), step);
+    });
+  });
+
+  // click directly on a day
+  var days = Tobago.Utils.selectWidthJQuery(elements, ".tobago-calendar-day");
+  days.each(function () {
+    var day = jQuery(this);
+    day.click(function () {
+      var day = jQuery(this);
+      var column = day.index();
+      var row = day.parent().index();
+      Tobago.Calendar.selectDay(jQuery(this).parents(".tobago-calendar"), row, column);
+    });
+  });
+
+  // init from data field, if there is any (e. g. we are in date picker popup)
+  var calendarWithDateField = Tobago.Utils.selectWidthJQuery(elements, ".tobago-calendar[data-tobago-dateinputid]");
+  calendarWithDateField.each(function () {
+    var calendar = jQuery(this);
+    Tobago.Calendar.initFromDateField(calendar);
+  });
+
+  // XXX find a way to mark this button as the "ok" button in the DatePickerRenderer.java! data-tobago-datepickerok
+  var okButton = Tobago.Utils.selectWidthJQuery(elements, ".tobago-calendar").parent().find("button").eq(0);
+  okButton.click(function () {
+    var button = jQuery(this);
+    var calendar = button.parent().parent().find(".tobago-calendar");
+    var time = button.parent().parent().find(".tobago-time");
+    Tobago.Calendar.writeIntoField(calendar, time);
+    Tobago.Popup.close(button);
+  });
+
+};
+
+Tobago.Calendar.MONTH_LENGTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+Tobago.Calendar.isLeapYear = function (year) {
+  return (year % 4 == 0)
+      && (year % 100 != 0 || year % 400 == 0);
+};
+
+Tobago.Calendar.getMonthLength = function (month, year) {
+  if (month == 2 && Tobago.Calendar.isLeapYear(year)) {
     return 29;
   }
-  return Calendar.MONTH_LENGTH[month - 1];
-}  
+  return Tobago.Calendar.MONTH_LENGTH[month - 1];
+};
 
-Calendar.getPreviousMonth = function (month, year) {
-  return (month == 1) ? 12 : month - 1;
-}  
+Tobago.Calendar.getPreviousMonthLength = function (month, year) {
+  if (month == 1) {
+    return Tobago.Calendar.getMonthLength(12, year - 1);
+  } else {
+    return Tobago.Calendar.getMonthLength(month - 1, year);
+  }
+};
 
-Calendar.getDayOfWeek = function(day, month, year) {
+Tobago.Calendar.getDayOfWeek = function (day, month, year) {
   var date = new Date();
   date.setDate(day);
   date.setMonth(month - 1);
   date.setFullYear(year);
   // getDay() -> 0 (Su) to 6 (Sa)
   return date.getDay() + 1; // +1 -> Java compatibility
-}
+};
 
-Calendar.firstDayOffset = function (month, year, firstDayOfWeek) {
-  var day = Calendar.getDayOfWeek(1, month, year);
+Tobago.Calendar.firstDayOffset = function (month, year, firstDayOfWeek) {
+  var day = Tobago.Calendar.getDayOfWeek(1, month, year);
   return (day + 7 - firstDayOfWeek) % 7;
-}
+};
 
-Calendar._weekCount = function (days) {
-  return Math.floor(((days + (7 - 1)) / 7));
-}
-
-Calendar.weekCount = function (month, year, firstDayOfWeek) {
-  var firstDayOffset = Calendar.firstDayOffset(month, year, firstDayOfWeek);
-  var daysInMonth = Calendar.getMonthLength(month, year);
-  return Calendar._weekCount(firstDayOffset + daysInMonth);
-}
-
-// -- calendar control -----------------------------------------------
-
-// XXX make page global
-function getFirstDayOfWeek(id) {
-  return parseInt(document.getElementById(id + ":firstDayOfWeek").value, 10);
-}
-
-// XXX make page global
-function getMonthName(id, month) {
-  return document.getElementById(id + ":monthNames").value.split(',')[month-1];
-}
-
-function initCalendarData(id, year, month, day) {
-  document.getElementById(id + ":day").value = day;
-  document.getElementById(id + ":month").value = month;
-  document.getElementById(id + ":year").value = year;
-  recalculateValues(id);
-}
+Tobago.Calendar.getMonthName = function (calendar, month) {
+  return calendar.data("tobago-monthnames").split(',')[month - 1];
+};
 
-function addMonth(id, monthDelta) {
+/**
+ * @param calendar The base element as jQuery object (root of the component).
+ */
+Tobago.Calendar.initCalendarData = function (calendar, year, month, day) {
+  calendar.data("tobago-day", day);
+  calendar.data("tobago-month", month);
+  calendar.data("tobago-year", year);
+  Tobago.Calendar.recalculateValues(calendar);
+};
+
+/**
+ * @param calendar The base element as jQuery object (root of the component).
+ */
+Tobago.Calendar.addMonth = function (calendar, monthDelta) {
   var yearDelta = 0;
   if (monthDelta > 0) {
     yearDelta = Math.floor(monthDelta / 12);
@@ -89,9 +138,9 @@ function addMonth(id, monthDelta) {
     yearDelta = -Math.floor(-monthDelta / 12);
     monthDelta = -((-monthDelta) % 12);
   }
-  var year = parseInt(document.getElementById(id + ":year").value, 10) + yearDelta;
-  var month = parseInt(document.getElementById(id + ":month").value, 10) + monthDelta;
-  var day = parseInt(document.getElementById(id + ":day").value, 10);
+  var day = calendar.data("tobago-day");
+  var month = calendar.data("tobago-month") + monthDelta;
+  var year = calendar.data("tobago-year") + yearDelta;
   if (month < 1) {
     month = 12;
     --year;
@@ -99,18 +148,17 @@ function addMonth(id, monthDelta) {
     month = 1;
     ++year;
   }
-  if (day > Calendar.getMonthLength(month, year)) {
-    day = Calendar.getMonthLength(month, year);
+  if (day > Tobago.Calendar.getMonthLength(month, year)) {
+    day = Tobago.Calendar.getMonthLength(month, year);
   }
-  initCalendarData(id, year, month, day);
-  initCalendar(id);
-}
-
-function recalculateValues(id) {
-  var day = parseInt(document.getElementById(id + ":day").value, 10);
-  var month = parseInt(document.getElementById(id + ":month").value, 10);
-  var year = parseInt(document.getElementById(id + ":year").value, 10);
-//  alert("before " + day + "." + month + "." + year);
+  Tobago.Calendar.initCalendarData(calendar, year, month, day);
+  Tobago.Calendar.initCalendar(calendar);
+};
+
+Tobago.Calendar.recalculateValues = function (calendar) {
+  var day = calendar.data("tobago-day");
+  var month = calendar.data("tobago-month");
+  var year = calendar.data("tobago-year");
 
   if (month < 1) {
     month += 12;
@@ -126,9 +174,9 @@ function recalculateValues(id) {
       month += 12;
       --year;
     }
-    day += Calendar.getMonthLength(month, year);
-  } else if (day > Calendar.getMonthLength(month, year)) {
-    day -= Calendar.getMonthLength(month, year);
+    day += Tobago.Calendar.getMonthLength(month, year);
+  } else if (day > Tobago.Calendar.getMonthLength(month, year)) {
+    day -= Tobago.Calendar.getMonthLength(month, year);
     ++month;
     if (month > 12) {
       month -= 12;
@@ -136,303 +184,291 @@ function recalculateValues(id) {
     }
   }
 
-//  alert("after " + day + "." + month + "." + year);
-
-  document.getElementById(id + ":day").value = day;
-  document.getElementById(id + ":month").value = month;
-  document.getElementById(id + ":year").value = year;
-}
+  calendar.data("tobago-day", day);
+  calendar.data("tobago-month", month);
+  calendar.data("tobago-year", year);
+};
 
-function selectDay(id, row, column) {
+Tobago.Calendar.selectDay = function (calendar, row, column) {
 //  alert(id + " "  + row + " " + column);
-  var month = document.getElementById(id + ":month").value;
-  var year = document.getElementById(id + ":year").value;
-  var firstDayOfWeek = getFirstDayOfWeek(id);
-  var firstDayOffset = Calendar.firstDayOffset(month, year, firstDayOfWeek);
-  initCalendarData(id, year, month, row * 7 + column - firstDayOffset + 1);
-  initCalendar(id);
-}
-
-function initCalendar(id) {
-  var day = parseInt(document.getElementById(id + ":day").value, 10);
-  var month = parseInt(document.getElementById(id + ":month").value, 10);
-  var year = parseInt(document.getElementById(id + ":year").value, 10);
-  var firstDayOfWeek = getFirstDayOfWeek(id);
-  var firstDayOffset = Calendar.firstDayOffset(month, year, firstDayOfWeek);
-//  var weekCount = Calendar.weekCount(month, year, firstDayOfWeek);
-  var prevMonthLength = Calendar.getMonthLength(
-      Calendar.getPreviousMonth(month, year), year);
-  var monthLength = Calendar.getMonthLength(month, year);
-  // alert(month + "/" + year + " weekCount: " + weekCount + "; firstDayOffset: " + firstDayOffset);
-  var title = document.getElementById(id + ":title");
-  title.innerHTML = getMonthName(id, month) + " " + year;
-  for (var week = 0; week < 6; ++week) {
-    var row = document.getElementById(id + ":" + week);
-//    if (week < weekCount) {
-      row.style.display = "";
-      for (var column = 0; column < 7; ++column) {
-        var el = document.getElementById(id + ":" + week + ":" + column);
-        var d = (week * 7) + column - firstDayOffset + 1;
-        var styleClass = "tobago-calendar-day";
-        var monthAfterClick = month;
-        if (d <= 0) {
-          d = prevMonthLength + d;
-          styleClass = "tobago-calendar-day tobago-calendar-day-markup-disabled";
-          monthAfterClick = month - 1;
-        } else if (d > monthLength) {
-          styleClass = "tobago-calendar-day tobago-calendar-day-markup-disabled";
-          d -= monthLength;
-          monthAfterClick = month + 1;
-        } else if (d == day) {
-          styleClass = "tobago-calendar-day tobago-calendar-day-markup-selected";
+  var month = calendar.data("tobago-month");
+  var year = calendar.data("tobago-year");
+  var firstDayOfWeek = calendar.data("tobago-firstdayofweek");
+  var firstDayOffset = Tobago.Calendar.firstDayOffset(month, year, firstDayOfWeek);
+  Tobago.Calendar.initCalendarData(calendar, year, month, row * 7 + column - firstDayOffset + 1);
+  Tobago.Calendar.initCalendar(calendar);
+};
+
+Tobago.Calendar.initCalendar = function (calendar) {
+  var day = calendar.data("tobago-day");
+  var month = calendar.data("tobago-month");
+  var year = calendar.data("tobago-year");
+  var firstDayOfWeek = calendar.data("tobago-firstdayofweek");
+  var firstDayOffset = Tobago.Calendar.firstDayOffset(month, year, firstDayOfWeek);
+  var prevMonthLength = Tobago.Calendar.getPreviousMonthLength(month, year);
+  var monthLength = Tobago.Calendar.getMonthLength(month, year);
+
+  var monthTitle = calendar.find(".tobago-calendar-header > [data-tobago-command=month]");
+  monthTitle.html(Tobago.Calendar.getMonthName(calendar, month));
+  var yearTitle = calendar.find(".tobago-calendar-header > [data-tobago-command=year]");
+  yearTitle.html(year);
+
+  calendar.find(".tobago-calendar-grid").children(".tobago-calendar-row").each(function (i) {
+    var row = jQuery(this);
+    row.children(".tobago-calendar-day").each(function (j) {
+      var span = jQuery(this);
+      var display = (i * 7) + j - firstDayOffset + 1;
+      if (display <= 0) {
+        span.addClass("tobago-calendar-day-markup-disabled");
+        span.removeClass("tobago-calendar-day-markup-selected");
+        display += prevMonthLength;
+      } else if (display > monthLength) {
+        span.addClass("tobago-calendar-day-markup-disabled");
+        span.removeClass("tobago-calendar-day-markup-selected");
+        display -= monthLength;
+      } else {
+        span.removeClass("tobago-calendar-day-markup-disabled");
+        if (display == day) {
+          span.addClass("tobago-calendar-day-markup-selected");
+        } else {
+          span.removeClass("tobago-calendar-day-markup-selected");
         }
-        el.className = styleClass;
-        el.innerHTML = d;
       }
-//    } else {
-//      row.style.display = "none";
-//    }
-  }
-}
-
-function initCalendarParse(id, textBoxId) {
-  var textBox = document.getElementById(textBoxId);
-  document.getElementById(id + ":fieldId").value = textBoxId;
-  var patternField = document.getElementById(textBoxId + ":converterPattern");
-  if (patternField) {
-    document.calendar.formatPattern = patternField.value;
-  } else {
-    document.calendar.formatPattern = "yyyy-MM-dd";
-  }
-
-  var string = textBox.value;
-  var date = new Date(getDateFromFormat(string, document.calendar.formatPattern));
+      span.html(display);
+    });
+  });
+};
+
+/**
+ * @param element jQuery element with a reference to the date field (with data attribute tobago-dateinputid)
+ * @return the date field as jQuery object
+ */
+Tobago.Calendar.getDateField = function (element) {
+  return jQuery(Tobago.Utils.escapeClientId(element.data("tobago-dateinputid")));
+};
+
+Tobago.Calendar.initFromDateField = function (calendar) {
+  var dateField = Tobago.Calendar.getDateField(calendar);
+  var pattern = dateField.data("tobago-pattern");
+  var value = dateField.attr("value");
+  var date = new Date(getDateFromFormat(value, pattern));
   if (date.getTime() == 0) {
     date = new Date();
-  } else if (! document.calendar.formatPattern.match(/d/)) {
-    // XXX Workaround for patterns without day (d) like mm/yyyy (repair the result from parsing)
+  } else if (!pattern.match(/d/)) {
+    // Workaround for patterns without day (d) like mm/yyyy (repair the result from parsing)
     date.setDate(date.getDate() + 1);
   }
   var day = date.getDate();
   var month = date.getMonth() + 1;
   var year = date.getFullYear();
 
-  initCalendarData(id, year, month, day);
-  initCalendar(id);
-}
-
-function writeIntoField2(obj) {
-  var id = obj.id;
-  var index = id.lastIndexOf(':');
-  return writeIntoField(obj, id.substring(0, index));
-}
-
-
-function writeIntoField(obj, id) {
-  var textBoxId = document.getElementById(id + ":calendar:fieldId");
-  var textBox = document.getElementById(textBoxId.value);
-
-  var day = parseInt(document.getElementById(id + ":calendar:day").value, 10);
-  var month = parseInt(document.getElementById(id + ":calendar:month").value, 10);
-  var year = parseInt(document.getElementById(id + ":calendar:year").value, 10);
-
-  var idPrefix = id + ":time" + Tobago.SUB_COMPONENT_SEP;
-  var hour = document.getElementById(idPrefix + "hour");
-  if (hour) {
-    hour = parseInt(hour.value, 10);
-  } else {
-    hour = 0;
+  Tobago.Calendar.initCalendarData(calendar, year, month, day);
+  Tobago.Calendar.initCalendar(calendar);
+};
+
+Tobago.Calendar.writeIntoField = function (calendar, time) {
+
+  var day = calendar.data("tobago-day");
+  var month = calendar.data("tobago-month");
+  var year = calendar.data("tobago-year");
+
+  var hour = Tobago.Time.getValueField(time, "hour");
+  var minute = Tobago.Time.getValueField(time, "minute");
+  var second = Tobago.Time.getValueField(time, "second");
+
+  var date = new Date(year, month - 1, day, hour, minute, second);
+  var dateField = Tobago.Calendar.getDateField(calendar);
+  var newValue = formatDate(date, dateField.data("tobago-pattern"));
+  if (dateField.val() != newValue) {
+    dateField.val(newValue);
+    dateField.change();
+  }
+
+  dateField.focus();
+};
+
+Tobago.registerListener(Tobago.Calendar.init, Tobago.Phase.DOCUMENT_READY);
+Tobago.registerListener(Tobago.Calendar.init, Tobago.Phase.AFTER_UPDATE);
+
+// --------------------------------------------------------------------------------------------------------------------
+
+Tobago.Time = {};
+
+Tobago.Time.init = function (elements) {
+
+  // time input fields
+  Tobago.Utils.selectWidthJQuery(elements, ".tobago-time-input")
+      .not("[disabled]").not("[readonly]")
+      .focus(function () {
+        Tobago.Time.focus(jQuery(this));
+      })
+      .blur(function () {
+        Tobago.Time.blur(jQuery(this));
+      })
+      .bind("keyup", function (event) {
+        Tobago.Time.keyUp(jQuery(this), event);
+      });
+
+  // increment button
+  Tobago.Utils.selectWidthJQuery(elements, ".tobago-time-incImage")
+      .not("[disabled]").not("[readonly]")
+      .click(function () {
+        Tobago.Time.increment(jQuery(this));
+      });
+
+  // decrement button
+  Tobago.Utils.selectWidthJQuery(elements, ".tobago-time-decImage")
+      .not("[disabled]").not("[readonly]")
+      .click(function () {
+        Tobago.Time.decrement(jQuery(this));
+      });
+
+  // init from data field, if there is any (e. g. we are in date picker popup)
+  Tobago.Utils.selectWidthJQuery(elements, ".tobago-time[data-tobago-dateinputid]")
+      .each(function () {
+        Tobago.Time.initFromDateField(jQuery(this));
+      });
+};
+
+Tobago.Time.getValueField = function (time, name) {
+  var input = Tobago.Time.findElement(time, name);
+  return Tobago.Time.getValue(input);
+};
+
+Tobago.Time.getValue = function (input) {
+  var number = parseInt(input.val(), 10); // use 10 to avoid parsing octal numbers, if the string begins with 0
+  return isNaN(number) ? 0 : number;
+};
+
+Tobago.Time.setValueField = function (time, name, value) {
+  var input = Tobago.Time.findElement(time, name);
+  Tobago.Time.setValue(input, value);
+};
+
+Tobago.Time.setValue = function (input, value) {
+  var max = input.data("tobago-max");
+  while (value >= max) {
+    value -= max;
   }
-  var minute = document.getElementById(idPrefix + "minute");
-  if (minute) {
-    minute = parseInt(minute.value, 10);
-  } else {
-    minute = 0;
+  while (value < 0) {
+    value += max;
   }
-  var second = document.getElementById(idPrefix + "second");
-  if (second) {
-    second = parseInt(second.value, 10);
-  } else {
-    second = 0;
+  if (value < 10) { // formatting 0#
+    value = "0" + value;
   }
-  var date = new Date(year, month - 1, day, hour, minute, second);
+  input.val(value);
 
-  Tobago.Popup.close(obj);
+  Tobago.Time.updateHidden(input);
+};
+/**
+ * Looks for a specific element inside of the time component.
+ *
+ * @param any jQuery element inside the "time" component.
+ * @param suffix id suffix or null for search for the base time element
+ */
+Tobago.Time.findElement = function (any, suffix) {
+  var id = any.attr("id");
+  var pos = id.lastIndexOf(Tobago.SUB_COMPONENT_SEP);
+  if (pos > -1) {
+    id = id.substring(0, pos);
+  }
+  if (suffix != null) {
+    id += Tobago.SUB_COMPONENT_SEP + suffix;
+  }
+  return jQuery(Tobago.Utils.escapeClientId(id));
+};
+
+Tobago.Time.updateHidden = function (anyInput) {
+  var time = Tobago.Time.findElement(anyInput, null);
+
+  var hour = Tobago.Time.getValueField(time, "hour");
+  var minute = Tobago.Time.getValueField(time, "minute");
+
+  var second = 0;
+  if (Tobago.Time.findElement(time, "second").length > 0) {
+    second = Tobago.Time.getValueField(time, "second");
+  }
+
+  var pattern = time.data("tobago-pattern");
+  var value = formatDate(new Date(1970, 1, 1, hour, minute, second), pattern);
+  var hidden = Tobago.Time.findElement(time, "field");
+  hidden.val(value);
+};
+
+Tobago.Time.increment = function (imageButton) {
+  var input = Tobago.Time.findCurrent(imageButton);
+  Tobago.Time.setValue(input, Tobago.Time.getValue(input) + 1);
+  input.focus();
+};
 
-  textBox.focus();
+Tobago.Time.decrement = function (imageButton) {
+  var input = Tobago.Time.findCurrent(imageButton);
+  Tobago.Time.setValue(input, Tobago.Time.getValue(input) - 1);
+  input.focus();
+};
 
-  var newValue =  formatDate(date, document.calendar.formatPattern);
-  if (textBox.value != newValue) {
-    textBox.value = newValue;
-    Tobago.raiseEvent("change", textBox);
+Tobago.Time.findCurrent = function (imageButton) {
+  var time = Tobago.Time.findElement(imageButton, null);
+  var unit = time.data("tobago-lastactive");
+  var input;
+  if (unit != null) {
+    input = Tobago.Time.findElement(imageButton, unit);
   }
-}
-// ------------------------------------------------------------------
-
-function tbgGetTimeInput(imageButton) {
-  if (imageButton.parentNode.selectedId) {
-    input = document.getElementById(imageButton.parentNode.selectedId);
-  } else {
-    var id = imageButton.id.substring(0, imageButton.id.lastIndexOf(":"));
-    input = document.getElementById(id + ":hour");
+  if (input == null) { // if there is no "last active" then use "hour"
+    input = Tobago.Time.findElement(imageButton, "hour");
   }
   return input;
-}
+};
 
-function tbgSetTimeInputValue(input, value) {
-
-//  LOG.debug("value = " + value);
-  if (input.parentNode.parentNode.hourMode) {
-    if (value < 0) {
-      value = 23;
-    } else if (value > 23) { // TODO: 12/24 hour mode ?
-      value = 0;
-    }
+Tobago.Time.focus = function (input) {
+  // save the last active
+  var time = Tobago.Time.findElement(input, null);
+  time.data("tobago-lastactive", input.data("tobago-unit"));
+
+  // save the old value
+  input.data("tobago-oldvalue", input.val());
+};
+
+Tobago.Time.blur = function (input) {
+  var value = input.val();
+  if (isNaN(value)) {
+    value = input.data("tobago-oldvalue");
   } else {
-    if (value < 0) {
-      value = 59;
-    } else if (value > 59) {
-      value = 0;
-    }
+    value = parseInt(value, 10); // use 10 to avoid parsing octal numbers, if the string begins with 0
   }
-  if (value < 10) {
-    value = "0" + value;
-  }
-  input.value = value;
-  var id = input.id.substring(0,input.id.lastIndexOf(Tobago.SUB_COMPONENT_SEP));
-  var hidden = document.getElementById(id);
-  if (hidden) {
-     var idPrefix = id + Tobago.SUB_COMPONENT_SEP;
-     var hour = document.getElementById(idPrefix + "hour");
-    if (hour) {
-      hour = parseInt(hour.value, 10);
-      if (hour < 10) {
-        hour = "0" + hour;
-      }
-    } else {
-      hour = "00";
-    }
-    var minute = document.getElementById(idPrefix + "minute");
-    if (minute) {
-      minute = parseInt(minute.value, 10);
-      if (minute < 10) {
-        minute = "0" + minute;
-      }
-    } else {
-      minute = "00";
-    }
-    hidden.value = hour + ":" + minute;
+  Tobago.Time.setValue(input, value);
+};
 
-    var second = document.getElementById(idPrefix + "second");
-    if (second) {
-      second = parseInt(second.value, 10);
-      if (second < 10) {
-        second = "0" + second;
-      }
-      hidden.value = hidden.value + ":" + second;
-    }
-  }
-//  LOG.debug("value 2 = " + input.value);
-}
-
-function tbgDecTime(imageButton, hour) {
-  var input = tbgGetTimeInput(imageButton);
-  tbgSetTimeInputValue(input, input.value - 1);
-  input.focus();
-}
-function tbgIncTime(imageButton, hour) {
-  var input = tbgGetTimeInput(imageButton);
-  tbgSetTimeInputValue(input, input.value - 0 + 1)
-  input.focus();
-}
+Tobago.Time.initFromDateField = function (time) {
+  var dateField = Tobago.Calendar.getDateField(time);
 
-function tbgTimerInputFocus(input, hour) {
-//  LOG.debug("focus " + input.id + " hourMode=" + hour);
-  input.parentNode.parentNode.selectedId = input.id;
-  input.parentNode.parentNode.hourMode = hour;
-  Tobago.addCssClass(input, "tobago-time-input-markup-selected");
-  input.oldValue = input.value;
-}
-
-function tbgTimerInputBlur(input) {
-//  LOG.debug("value XX = " + input.value);
-  var value = parseInt(input.value, 10);
-//  LOG.debug("value 3  = " + value);
-  if (value == NaN) {
-    input.value = input.oldValue;
-    return;
-  }
-  if (input.parentNode.parentNode.hourMode) {
-    if (value > 23 || value < 0) {
-      value = input.oldValue;
-    }
-  } else {
-    if (value > 59 || value < 0) {
-      value = input.oldValue;
-    }
+  var pattern = dateField.data("tobago-pattern");
+  if (!pattern) { // todo: test it
+    pattern = "HH:mm";
   }
-  tbgSetTimeInputValue(input, value)
-  Tobago.removeCssClass(input, "tobago-time-input-markup-selected");
-//  LOG.debug("value  4= " + input.value);
-}
-
-function tbgInitTimeParse(timeId, dateId) {
-  var time = document.getElementById(dateId);
-  if (time) {
-
-    var patternField = document.getElementById(dateId + ":converterPattern");
-    var formatPattern;
-    if (patternField) {
-      formatPattern = patternField.value;
-    } else {
-      formatPattern = "HH:mm";
-    }
 
-
-    var date = new Date(getDateFromFormat(time.value, formatPattern));
-    if (date.getTime() == 0) {
-      date = new Date();
-    }
-    var hours = date.getHours();
-    var minutes = date.getMinutes();
-    var seconds = date.getSeconds();
-
-    LOG.debug("init time :" + hours + ":" + minutes + ":" + seconds); // @DEV_ONLY
-    tbgInitTimeData(timeId, hours, minutes, seconds);
-  }
-}
-
-function tbgInitTimeData(id, hours, minutes, seconds) {
-  var element = document.getElementById(id);
-  if (element) {
-    var idPrefix = id + Tobago.SUB_COMPONENT_SEP;
-    var hourField = document.getElementById(idPrefix + "hour");
-    if (hourField) {
-      hourField.value = hours < 10 ? "0" + hours : hours;
-    }
-    var minuteField = document.getElementById(idPrefix + "minute");
-    if (minuteField) {
-      minuteField.value = minutes < 10 ? "0" + minutes : minutes;
-    }
-    var secondsField = document.getElementById(idPrefix + "second");
-    if (secondsField) {
-      secondsField.value = seconds < 10 ? "0" + seconds : seconds;
-    }
+  var date = new Date(getDateFromFormat(dateField.val(), pattern));
+  if (date.getTime() == 0) {
+    date = new Date();
   }
-}
 
-function tbgTimerKeyUp(inputElement, event) {
-  if (! event) {
-    event = window.event;
+  Tobago.Time.setValueField(time, "hour", date.getHours());
+  Tobago.Time.setValueField(time, "minute", date.getMinutes());
+  if (pattern.indexOf("s") > -1) {
+    Tobago.Time.setValueField(time, "second", date.getSeconds());
   }
+};
+
+Tobago.Time.keyUp = function (input, event) {
   switch (event.keyCode) {
     case 38:
-      tbgSetTimeInputValue(inputElement, inputElement.value - 0 + 1);
+      Tobago.Time.setValue(input, Tobago.Time.getValue(input) + 1);
       break;
     case 40:
-      tbgSetTimeInputValue(inputElement, inputElement.value - 1);
+      Tobago.Time.setValue(input, Tobago.Time.getValue(input) - 1);
       break;
   }
-}
-
+};
 
+Tobago.registerListener(Tobago.Time.init, Tobago.Phase.DOCUMENT_READY);
+Tobago.registerListener(Tobago.Time.init, Tobago.Phase.AFTER_UPDATE);