001 package org.apache.tapestry.dojo.form;
002
003 import org.apache.tapestry.IMarkupWriter;
004 import org.apache.tapestry.IRequestCycle;
005 import org.apache.tapestry.IScript;
006 import org.apache.tapestry.TapestryUtils;
007 import org.apache.tapestry.form.TranslatedField;
008 import org.apache.tapestry.form.TranslatedFieldSupport;
009 import org.apache.tapestry.form.ValidatableFieldSupport;
010 import org.apache.tapestry.json.JSONLiteral;
011 import org.apache.tapestry.json.JSONObject;
012 import org.apache.tapestry.valid.ValidatorException;
013
014 import java.util.*;
015
016 /**
017 * Implementation of an html form input field that has a dynamic drop down selection list of
018 * time segments displayed in the {@link org.apache.tapestry.IPage}'s {@link java.util.Locale}.
019 */
020 public abstract class GTimePicker extends AbstractFormWidget implements TranslatedField
021 {
022 /**
023 * For a full day - broken up in to half hour segments.
024 */
025 static final int TIME_SEGMENT_LENGTH = 48;
026
027 /**
028 * Core value used to place input in to.
029 * @return The current bound value, may be null.
030 */
031 public abstract Object getValue();
032
033 public abstract void setValue(Object value);
034
035 public abstract boolean isDisabled();
036
037 /**
038 * {@inheritDoc}
039 */
040 protected void renderFormWidget(IMarkupWriter writer, IRequestCycle cycle)
041 {
042 String value = getTranslatedFieldSupport().format(this, getValue());
043
044 renderDelegatePrefix(writer, cycle);
045
046 writer.beginEmpty("input");
047 writer.attribute("type", "text");
048 writer.attribute("autocomplete", "off");
049 writer.attribute("name", getName());
050
051 if (isDisabled())
052 writer.attribute("disabled", "disabled");
053
054 if (value != null)
055 writer.attribute("value", value);
056
057 renderIdAttribute(writer, cycle);
058 renderDelegateAttributes(writer, cycle);
059
060 getTranslatedFieldSupport().renderContributions(this, writer, cycle);
061 getValidatableFieldSupport().renderContributions(this, writer, cycle);
062
063 renderInformalParameters(writer, cycle);
064
065 writer.closeTag();
066
067 renderDelegateSuffix(writer, cycle);
068
069 // Build up options value list
070
071 Locale locale = getPage().getLocale();
072
073 GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(getPage().getLocale());
074 cal.set(Calendar.HOUR, 0);
075 cal.set(Calendar.AM_PM, Calendar.AM);
076
077 StringBuffer optStr = new StringBuffer("[");
078 int selectedIndex = -1;
079
080 for(int i=0, hour=0; i < TIME_SEGMENT_LENGTH; i++)
081 {
082 if (i != 0)
083 {
084 optStr.append(",");
085 }
086
087 if (i == 24)
088 {
089 hour = 0;
090 cal.set(Calendar.AM_PM, Calendar.PM);
091 }
092
093 cal.set(Calendar.HOUR, hour);
094 cal.set(Calendar.MINUTE, (i % 2 > 0) ? 30 : 0);
095
096 String option = getTranslator().format(this, locale, cal.getTime());
097
098 optStr.append("\"").append(option).append("\"");
099
100 if (selectedIndex < 0 && value != null && value.equals(option))
101 {
102 selectedIndex = i;
103 }
104
105 if (i % 2 > 0)
106 {
107 hour++;
108 }
109 }
110
111 optStr.append("]");
112
113 // now create widget parms
114
115 JSONObject json = new JSONObject();
116 json.put("inputNodeId", getClientId());
117 json.put("optionValues", new JSONLiteral(optStr.toString()));
118
119 if (selectedIndex > -1)
120 {
121 json.put("selectedIndex", selectedIndex);
122 }
123
124 Map parms = new HashMap();
125 parms.put("clientId", getClientId());
126 parms.put("props", json.toString());
127 parms.put("widget", this);
128
129 getScript().execute(this, cycle, TapestryUtils.getPageRenderSupport(cycle, this), parms);
130 }
131
132 /**
133 * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
134 */
135 protected void rewindFormWidget(IMarkupWriter writer, IRequestCycle cycle)
136 {
137 String value = cycle.getParameter(getName());
138
139 try
140 {
141 Object translated = getTranslatedFieldSupport().parse(this, value);
142
143 getValidatableFieldSupport().validate(this, writer, cycle, translated);
144
145 setValue(translated);
146 }
147 catch (ValidatorException e)
148 {
149 getForm().getDelegate().record(e);
150 }
151 }
152
153 /**
154 * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
155 */
156 public boolean isRequired()
157 {
158 return getValidatableFieldSupport().isRequired(this);
159 }
160
161 /** Injected. */
162 public abstract IScript getScript();
163
164 /** Injected. */
165 public abstract TranslatedFieldSupport getTranslatedFieldSupport();
166
167 /** Injected. */
168 public abstract ValidatableFieldSupport getValidatableFieldSupport();
169
170 }