Feature-browser DateField demo now allows user to select a locale from a dropdown list.
ISelect fixes and optimazations.
svn changeset:1842/svn branch:trunk
import java.util.Locale;
import com.itmill.toolkit.data.util.IndexedContainer;
-import com.itmill.toolkit.ui.*;
+import com.itmill.toolkit.data.util.MethodProperty;
+import com.itmill.toolkit.ui.Component;
+import com.itmill.toolkit.ui.DateField;
+import com.itmill.toolkit.ui.Form;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.OrderedLayout;
+import com.itmill.toolkit.ui.Select;
public class FeatureDateField extends Feature {
- static private IndexedContainer localeContainer;
+ static private String[] localeNames;
static {
- localeContainer = new IndexedContainer();
- localeContainer.addContainerProperty("name", String.class, "");
Locale[] locales = Locale.getAvailableLocales();
- for (int i = 0; i < locales.length; i++)
- localeContainer.addItem(locales[i]).getItemProperty("name")
- .setValue(locales[i].getDisplayName());
+ localeNames = new String[locales.length];
+ for (int i = 0; i < locales.length; i++)
+ localeNames[i] = locales[i].getDisplayName();
}
public FeatureDateField() {
OrderedLayout l = new OrderedLayout();
- l.addComponent(new Label("Your locale is: "
+ l.addComponent(new Label("Your default locale is: "
+ this.getApplication().getLocale().toString()
.replace('_', '-')));
DateField df = new DateField();
df.setValue(new java.util.Date());
l.addComponent(df);
-
- // Create locale selector
- // TODO: see #244 (broken for AJAX mode), known issue exists
- /*
- * DISABLE UNTIL WORKS Select selector = new Select("Application
- * Locale", localeContainer); selector.setItemCaptionPropertyId("name");
- * selector.setImmediate(true); selector.setPropertyDataSource(new
- * MethodProperty( this.getApplication(), "locale"));
- * l.addComponent(selector);
- */
-
+
// Properties
propertyPanel = new PropertyPanel(df);
Form ap = propertyPanel
- .createBeanPropertySet(new String[] { "resolution" });
+ .createBeanPropertySet(new String[] { "resolution", "locale" });
ap.replaceWithSelect("resolution", new Object[] {
new Integer(DateField.RESOLUTION_YEAR),
new Integer(DateField.RESOLUTION_MONTH),
new Integer(DateField.RESOLUTION_MSEC) }, new Object[] {
"Year", "Month", "Day", "Hour", "Minute", "Second",
"Millisecond" });
+ ap.replaceWithSelect("locale", Locale.getAvailableLocales(), localeNames);
ap.getField("resolution").setValue(
new Integer(DateField.RESOLUTION_DAY));
+ ap.getField("locale").setValue(Locale.getDefault());
Select themes = (Select) propertyPanel.getField("style");
themes.addItem("text").getItemProperty(
themes.getItemCaptionPropertyId()).setValue("text");
readonly = uidl.getBooleanAttribute("readonly");\r
disabled = uidl.getBooleanAttribute("disabled");\r
multiselect = "multi".equals(uidl.getStringAttribute("selectmode"));\r
+ immediate = uidl.getBooleanAttribute("immediate");\r
\r
UIDL ops = uidl.getChildUIDL(0);\r
\r
protected abstract Object[] getSelectedItems();\r
\r
protected Object getSelectedItem() {\r
- if(getSelectedItems().length > 0)\r
- return getSelectedItems()[0];\r
+ Object[] sel = getSelectedItems();\r
+ if(sel.length > 0)\r
+ return sel[0];\r
else\r
return null;\r
}\r
public void updateFromUIDL(UIDL uidl, Client client) {\r
super.updateFromUIDL(uidl, client);\r
calendar.updateCalendar();\r
+ calendarToggle.setEnabled(enabled);\r
}\r
\r
public void onClick(Widget sender) {\r
protected void buildOptions(UIDL uidl) {
select.setMultipleSelect(multiselect);
- if(multiselect) select.setVisibleItemCount(VISIBLE_COUNT);
+ if(multiselect)
+ select.setVisibleItemCount(VISIBLE_COUNT);
+ else
+ select.setVisibleItemCount(1);
select.setEnabled(!disabled && !readonly);
select.clear();
for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
else if(currentResolution >= IDateField.RESOLUTION_DAY)\r
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY;\r
\r
- format = new SimpleDateFormat(dts.getDateFormat());\r
+ format = new SimpleDateFormat(verifyFormat(dts.getDateFormat()));\r
format.setLocale(dl);\r
\r
String dateText = format.format(date);\r
dateText += " " + (date.getHours()<12? dts.getAmPmStrings()[0] : dts.getAmPmStrings()[1]);\r
\r
text.setText(dateText);\r
+ text.setEnabled(enabled&&!readonly);\r
+ \r
+ if(readonly)\r
+ text.addStyleName("i-readonly");\r
+ else\r
+ text.removeStyleName("i-readonly");\r
}\r
\r
public void onChange(Widget sender) {\r
else if(currentResolution == IDateField.RESOLUTION_DAY)\r
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY;\r
\r
- String f = dts.getDateFormat();\r
+ String f = verifyFormat(dts.getDateFormat());\r
\r
if(currentResolution >= IDateField.RESOLUTION_HOUR)\r
f += " " + (dts.isTwelveHourClock()?\r
buildTime();\r
}\r
}\r
-\r
+ \r
+ private String verifyFormat(String format) {\r
+ // Remove unnecessary d & M if resolution is too low\r
+ if(currentResolution < IDateField.RESOLUTION_DAY)\r
+ format = format.replaceAll("d", "");\r
+ if(currentResolution < IDateField.RESOLUTION_MONTH)\r
+ format = format.replaceAll("M", "");\r
+ \r
+ // Remove unsupported patterns\r
+ // TODO support for 'G', era designator (used at least in Japan)\r
+ format = format.replaceAll("[GzZwWkK]", "");\r
+ \r
+ // Remove extra delimiters ('/' and '.')\r
+ while(format.startsWith("/") || format.startsWith(".") || format.startsWith("-"))\r
+ format = format.substring(1);\r
+ while(format.endsWith("/") || format.endsWith(".") || format.endsWith("-"))\r
+ format = format.substring(0, format.length()-1);\r
+ \r
+ // Remove duplicate delimiters\r
+ format = format.replaceAll("//", "/");\r
+ format = format.replaceAll("\\.\\.", ".");\r
+ format = format.replaceAll("--", "-");\r
+ \r
+ return format.trim();\r
+ }\r
}\r
msec.addChangeListener(this);\r
}\r
\r
- // Update times\r
- if(thc) {\r
- int h = datefield.date.getHours();\r
- ampm.setSelectedIndex(h<12? 0 : 1);\r
- h -= ampm.getSelectedIndex()*12;\r
- hours.setSelectedIndex(h);\r
- } else\r
- hours.setSelectedIndex(datefield.date.getHours());\r
- if(datefield.currentResolution >= IDateField.RESOLUTION_MIN)\r
- mins.setSelectedIndex(datefield.date.getMinutes());\r
- if(datefield.currentResolution >= IDateField.RESOLUTION_SEC)\r
- sec.setSelectedIndex(datefield.date.getSeconds());\r
- if(datefield.currentResolution == IDateField.RESOLUTION_MSEC)\r
- msec.setSelectedIndex(datefield.getMilliseconds());\r
- if(thc)\r
- ampm.setSelectedIndex(datefield.date.getHours()<12?0:1);\r
-\r
- \r
String delimiter = datefield.dts.getClockDelimeter();\r
boolean ro = datefield.readonly;\r
\r
if(ro) return;\r
}\r
\r
+ // Update times\r
+ if(thc) {\r
+ int h = datefield.date.getHours();\r
+ ampm.setSelectedIndex(h<12? 0 : 1);\r
+ h -= ampm.getSelectedIndex()*12;\r
+ hours.setSelectedIndex(h);\r
+ } else\r
+ hours.setSelectedIndex(datefield.date.getHours());\r
+ if(datefield.currentResolution >= IDateField.RESOLUTION_MIN)\r
+ mins.setSelectedIndex(datefield.date.getMinutes());\r
+ if(datefield.currentResolution >= IDateField.RESOLUTION_SEC)\r
+ sec.setSelectedIndex(datefield.date.getSeconds());\r
+ if(datefield.currentResolution == IDateField.RESOLUTION_MSEC)\r
+ msec.setSelectedIndex(datefield.getMilliseconds());\r
+ if(thc)\r
+ ampm.setSelectedIndex(datefield.date.getHours()<12?0:1);\r
+ \r
+ if(datefield.readonly && !redraw) {\r
+ // Do complete redraw when in read-only status\r
+ clear();\r
+ String delimiter = datefield.dts.getClockDelimeter();\r
+ \r
+ int h = datefield.date.getHours();\r
+ if(thc) h -= h<12? 0 : 12;\r
+ add(new ILabel(h<10? "0"+h : ""+h));\r
+ \r
+ if(datefield.currentResolution >= IDateField.RESOLUTION_MIN) {\r
+ add(new ILabel(delimiter));\r
+ int m = mins.getSelectedIndex();\r
+ add(new ILabel(m<10? "0"+m : ""+m));\r
+ }\r
+ if(datefield.currentResolution >= IDateField.RESOLUTION_SEC) {\r
+ add(new ILabel(delimiter));\r
+ int s = sec.getSelectedIndex();\r
+ add(new ILabel(s<10? "0"+s : ""+s));\r
+ }\r
+ if(datefield.currentResolution == IDateField.RESOLUTION_MSEC) {\r
+ add(new ILabel("."));\r
+ int m = datefield.getMilliseconds();\r
+ String ms = m<100? "0"+m : ""+m;\r
+ add(new ILabel(m<10? "0"+ms : ms));\r
+ }\r
+ if(datefield.currentResolution == IDateField.RESOLUTION_HOUR) {\r
+ add(new ILabel(delimiter+"00")); // o'clock\r
+ }\r
+ if(thc) {\r
+ add(new ILabel(" "));\r
+ add(new ILabel(ampm.getItemText(datefield.date.getHours()<12? 0 : 1)));\r
+ }\r
+ }\r
+ \r
boolean enabled = datefield.enabled;\r
hours.setEnabled(enabled);\r
if(mins != null) mins.setEnabled(enabled);\r
\r
import java.util.Date;\r
\r
-import com.itmill.toolkit.terminal.gwt.client.DateTimeService;\r
import com.itmill.toolkit.terminal.gwt.gwtwidgets.util.regex.Pattern;\r
\r
/**\r
int h = Integer.parseInt(text);\r
String token = com.itmill.toolkit.terminal.gwt.client.DateLocale.getPM();\r
String which = input.substring(input.length() - token.length()); // Assumes both AM and PM tokens have same length\r
- if(which.equals(token))\r
+ if(which.equalsIgnoreCase(token))\r
h += 12;\r
date.setHours(h);\r
}\r
-.i-textfield{\r
+.i-textfield {\r
font-size: 1.1em;\r
color: #444;\r
background: #fff url(../img/bg.png) repeat-x;\r
\r
.i-textfield-error {\r
background: #ff9999;\r
+}\r
+\r
+.i-textfield.i-readonly {\r
+ background: transparent;\r
+ color: #222;\r
+ border: none;\r
}
\ No newline at end of file
// Force our locale as JVM default for a while (SimpleDateFormat uses JVM default)
Locale.setDefault(l);
String df = new SimpleDateFormat().toPattern();
- // TODO we suppose all formats separate date and time with a whitespace
- String dateformat = df.substring(0,df.indexOf(" "));
- outWriter.print("\"df\":\"" + dateformat + "\",");
+ int timeStart = df.indexOf("H");
+ if(timeStart < 0)
+ timeStart = df.indexOf("h");
+ int ampm_first = df.indexOf("a");
+ // E.g. in Korean locale AM/PM is before h:mm
+ // TODO should take that into consideration on client-side as well, now always h:mm a
+ if(ampm_first > 0 && ampm_first < timeStart)
+ timeStart = ampm_first;
+ String dateformat = df.substring(0, timeStart-1);
+
+ outWriter.print("\"df\":\"" + dateformat.trim() + "\",");
/*
* Time formatting (24 or 12 hour clock and AM/PM suffixes)
*/
- String timeformat = df.substring(df.indexOf(" ")+1, df.length()); // Doesn't return second or milliseconds
+ String timeformat = df.substring(timeStart, df.length()); // Doesn't return second or milliseconds
// We use timeformat to determine 12/24-hour clock
boolean twelve_hour_clock = timeformat.contains("a");
// TODO there are other possibilities as well, like 'h' in french (ignore them, too complicated)
newsel = new HashSet(newsel);
newsel.removeAll(visible);
newsel.addAll(s);
- super.setValue(newsel);
+ setValue(newsel, true);
}
}
*
* @param newValue
* the New selected item or collection of selected items.
- * @param repaintIsNotNeeded True iff caller is sure that repaint is not needed.
+ * @param repaintIsNotNeeded True if caller is sure that repaint is not needed.
* @see com.itmill.toolkit.ui.AbstractField#setValue(java.lang.Object, java.lang.Boolean)
*/
protected void setValue(Object newValue, boolean repaintIsNotNeeded) throws Property.ReadOnlyException,