
eu.webtoolkit.jwt.WDatePicker Maven / Gradle / Ivy
Show all versions of jwt Show documentation
/*
* Copyright (C) 2009 Emweb bvba, Leuven, Belgium.
*
* See the LICENSE file for terms of use.
*/
package eu.webtoolkit.jwt;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.lang.ref.*;
import java.util.concurrent.locks.ReentrantLock;
import javax.servlet.http.*;
import javax.servlet.*;
import eu.webtoolkit.jwt.*;
import eu.webtoolkit.jwt.chart.*;
import eu.webtoolkit.jwt.utils.*;
import eu.webtoolkit.jwt.servlet.*;
/**
* A date picker.
*
*
* A date picker shows a line edit and an icon which when clicked popups a
* {@link WCalendar} for editing the date. Any date entered in the line edit is
* reflected in the calendar, and vice-versa.
*
* Each of these widgets may be accessed individually (
* {@link WDatePicker#getLineEdit() getLineEdit()},
* {@link WDatePicker#getCalendar() getCalendar()}, and
* {@link WDatePicker#getDisplayWidget() getDisplayWidget()}) and there is a
* constructor that allows you to specify an existing line edit and display
* widget.
*
* The date format used by default is "dd/MM/yyyy"
and
* can be changed using {@link WDatePicker#setFormat(String format) setFormat()}
* . At any time, the date set may be read using {@link WDatePicker#getDate()
* getDate()}, or can be changed using {@link WDatePicker#setDate(WDate date)
* setDate()}.
*
*
i18n
*
* Internationalization of {@link WDatePicker} is mostly handled through the
* internationalization mechanism of {@link eu.webtoolkit.jwt.WDate}. The
* 'Close' button can be internationalized by overriding the default
* value for the localization key Wt.DatePicker.Close.
*
*
CSS
*
* The date picker is styled by the current CSS theme. The look can be
* overridden using the Wt-datepicker
and Wt-outset
* CSS class; the calendar itself can be styled as documented in
* {@link WCalendar}.
*
*
*
*
*
* Example of a WDatePicker (default theme)
*
*
*
*
* Example of a WDatePicker (polished theme)
*
*
*
*
*/
public class WDatePicker extends WCompositeWidget {
/**
* Create a new date picker.
*
* This constructor creates a line edit with an icon that leads to a popup
* calendar. A {@link WDateValidator} is configured for the line edit.
*/
public WDatePicker(WContainerWidget parent) {
super(parent);
this.format_ = "";
this.positionJS_ = new JSlot();
this.createDefault();
}
/**
* Create a new date picker.
*
* Calls {@link #WDatePicker(WContainerWidget parent)
* this((WContainerWidget)null)}
*/
public WDatePicker() {
this((WContainerWidget) null);
}
/**
* Create a new date picker for existing line edit and with custom display
* widget.
*
* The displayWidget
is a button or image which much be clicked
* to open the date picker. This widget will become owned by the picker.
*
* The forEdit
argument is the lineEdit that works in
* conjunction with the date picker. This widget does not become part of the
* date picker, and may be located anywhere else.
*/
public WDatePicker(WInteractWidget displayWidget, WLineEdit forEdit,
WContainerWidget parent) {
super(parent);
this.format_ = "";
this.positionJS_ = new JSlot();
this.create(displayWidget, forEdit);
}
/**
* Create a new date picker for existing line edit and with custom display
* widget.
*
* Calls
* {@link #WDatePicker(WInteractWidget displayWidget, WLineEdit forEdit, WContainerWidget parent)
* this(displayWidget, forEdit, (WContainerWidget)null)}
*/
public WDatePicker(WInteractWidget displayWidget, WLineEdit forEdit) {
this(displayWidget, forEdit, (WContainerWidget) null);
}
/**
* Destructor.
*/
public void remove() {
WApplication.getInstance().doJavaScript(
"Wt3_1_11.remove('" + this.popup_.getId() + "');");
super.remove();
}
/**
* Sets the format used for parsing or writing the date in the line edit.
*
* Sets the format used for representing the date in the line edit. If the
* line edit has a {@link WDateValidator} configured for it, then also there
* the format is updated.
*
* The default format is 'dd/MM/yyyy'
.
*
*
* @see WDatePicker#getFormat()
* @see WDate#toString()
*/
public void setFormat(String format) {
this.format_ = format;
WDateValidator dv = ((this.forEdit_.getValidator()) instanceof WDateValidator ? (WDateValidator) (this.forEdit_
.getValidator())
: null);
if (dv != null) {
dv.setFormat(format);
}
}
/**
* Returns the format.
*
*
* @see WDatePicker#setFormat(String format)
*/
public String getFormat() {
return this.format_;
}
/**
* The calendar widget.
*
* Returns the calendar widget.
*/
public WCalendar getCalendar() {
return this.calendar_;
}
/**
* The line edit.
*
* Returns the line edit which works in conjunction with this date picker.
*/
public WLineEdit getLineEdit() {
return this.forEdit_;
}
/**
* The display widget.
*
* Returns the widget which is displayed to activate the calendar.
*/
public WInteractWidget getDisplayWidget() {
return this.displayWidget_;
}
/**
* The current date.
*
* Reads the current date from the {@link WDatePicker#getLineEdit()
* getLineEdit()}.
*
* Returns null
if the date could not be parsed using the
* current {@link WDatePicker#getFormat() getFormat()}.
*
*
* @see WDatePicker#setDate(WDate date)
* @see WDate#fromString(String s)
* @see WLineEdit#getText()
*/
public WDate getDate() {
return WDate.fromString(this.forEdit_.getText(), this.format_);
}
/**
* Sets the current date.
*
* Does nothing if the current date is Null
.
*
*
* @see WDatePicker#getDate()
*/
public void setDate(WDate date) {
if (!(date == null)) {
this.forEdit_.setText(date.toString(this.format_));
this.calendar_.select(date);
this.calendar_.browseTo(date);
}
}
/**
* Sets whether the widget is enabled.
*
* This is the oppositie of {@link WDatePicker#setDisabled(boolean disabled)
* setDisabled()}.
*/
public void setEnabled(boolean enabled) {
this.setDisabled(!enabled);
}
public void setDisabled(boolean disabled) {
this.forEdit_.setDisabled(disabled);
this.displayWidget_.setHidden(disabled);
}
/**
* Hide/unhide the widget.
*/
public void setHidden(boolean hidden, WAnimation animation) {
super.setHidden(hidden, animation);
this.forEdit_.setHidden(hidden, animation);
this.displayWidget_.setHidden(hidden, animation);
}
/**
* Sets the bottom of the valid date range.
*/
public void setBottom(WDate bottom) {
WDateValidator dv = ((this.forEdit_.getValidator()) instanceof WDateValidator ? (WDateValidator) (this.forEdit_
.getValidator())
: null);
if (dv != null) {
dv.setBottom(bottom);
this.calendar_.setBottom(bottom);
}
}
/**
* Returns the bottom date of the valid range.
*/
public WDate getBottom() {
WDateValidator dv = ((this.forEdit_.getValidator()) instanceof WDateValidator ? (WDateValidator) (this.forEdit_
.getValidator())
: null);
if (dv != null) {
return dv.getBottom();
} else {
return null;
}
}
/**
* Sets the top of the valid date range.
*/
public void setTop(WDate top) {
WDateValidator dv = ((this.forEdit_.getValidator()) instanceof WDateValidator ? (WDateValidator) (this.forEdit_
.getValidator())
: null);
if (dv != null) {
dv.setTop(top);
this.calendar_.setTop(top);
}
}
/**
* Returns the top date of the valid range.
*/
public WDate getTop() {
WDateValidator dv = ((this.forEdit_.getValidator()) instanceof WDateValidator ? (WDateValidator) (this.forEdit_
.getValidator())
: null);
if (dv != null) {
return dv.getTop();
} else {
return null;
}
}
/**
* Signal emitted when the value has changed.
*
* This signal is emitted when a new date has been entered (either through
* the line edit, or through the calendar popup).
*/
public Signal changed() {
return this.calendar_.selectionChanged();
}
/**
* Controls how the calendar popup is positioned.
*
* When global
is true
, then the popup will
* position itself globally. This avoids that the popup is affected by
* enclosing parents with overflow settings that clip the popup. This makes
* the popup however no longer follow the popup button when this button
* moves.
*
* The default is false
.
*/
public void setGlobalPopup(boolean global) {
this.positionJS_.setJavaScript("function() { Wt3_1_11.getElement('"
+ this.popup_.getId()
+ "').style.display = '';Wt3_1_11.positionAtWidget('"
+ this.popup_.getId() + "','" + this.displayWidget_.getId()
+ "', Wt3_1_11.Horizontal, " + (global ? "true" : "false")
+ ");}");
}
/**
* Shows or hides the popup.
*/
public void setPopupVisible(boolean visible) {
this.popup_.setHidden(!visible);
}
private String format_;
private WInteractWidget displayWidget_;
private WLineEdit forEdit_;
private WContainerWidget layout_;
private WTemplate popup_;
private WCalendar calendar_;
private JSlot positionJS_;
private void createDefault() {
WImage icon = new WImage(WApplication.getResourcesUrl()
+ "calendar_edit.png");
icon.setVerticalAlignment(AlignmentFlag.AlignMiddle);
WLineEdit lineEdit = new WLineEdit();
this.create(icon, lineEdit);
this.layout_.insertWidget(0, lineEdit);
lineEdit.setValidator(new WDateValidator(this.format_, this));
}
private void create(WInteractWidget displayWidget, WLineEdit forEdit) {
this.setImplementation(this.layout_ = new WContainerWidget());
this.displayWidget_ = displayWidget;
this.forEdit_ = forEdit;
this.forEdit_.setVerticalAlignment(AlignmentFlag.AlignMiddle);
this.forEdit_.changed().addListener(this, new Signal.Listener() {
public void trigger() {
WDatePicker.this.setFromLineEdit();
}
});
this.format_ = "dd/MM/yyyy";
this.layout_.setInline(true);
this.layout_.addWidget(displayWidget);
String TEMPLATE = "${shadow-x1-x2}${calendar}
${close}";
this.layout_.addWidget(this.popup_ = new WTemplate(
new WString(TEMPLATE)));
this.calendar_ = new WCalendar();
this.calendar_.activated().addListener(this.popup_,
new Signal1.Listener() {
public void trigger(WDate e1) {
WDatePicker.this.popup_.hide();
}
});
this.calendar_.selectionChanged().addListener(this,
new Signal.Listener() {
public void trigger() {
WDatePicker.this.setFromCalendar();
}
});
WPushButton closeButton = new WPushButton(tr("Wt.WDatePicker.Close"));
closeButton.clicked().addListener(this.popup_,
new Signal1.Listener() {
public void trigger(WMouseEvent e1) {
WDatePicker.this.popup_.hide();
}
});
this.popup_.bindString("shadow-x1-x2", WTemplate.DropShadow_x1_x2);
this.popup_.bindWidget("calendar", this.calendar_);
this.popup_.bindWidget("close", closeButton);
this.popup_.hide();
this.popup_.setPopup(true);
this.popup_.setPositionScheme(PositionScheme.Absolute);
this.popup_.setStyleClass("Wt-outset Wt-datepicker");
this.popup_.escapePressed().addListener(this.popup_,
new Signal.Listener() {
public void trigger() {
WDatePicker.this.popup_.hide();
}
});
displayWidget.clicked().addListener(this.popup_,
new Signal1.Listener() {
public void trigger(WMouseEvent e1) {
WDatePicker.this.popup_.show();
}
});
displayWidget.clicked().addListener(this.positionJS_);
displayWidget.clicked().addListener(this,
new Signal1.Listener() {
public void trigger(WMouseEvent e1) {
WDatePicker.this.setFromLineEdit();
}
});
this.setGlobalPopup(false);
}
private void setFromCalendar() {
if (!this.calendar_.getSelection().isEmpty()) {
WDate calDate = this.calendar_.getSelection().iterator().next();
this.forEdit_.setText(calDate.toString(this.format_));
this.forEdit_.changed().trigger();
}
}
private void setFromLineEdit() {
WDate d = WDate.fromString(this.forEdit_.getText(), this.format_);
if ((d != null)) {
if (this.calendar_.getSelection().isEmpty()) {
this.calendar_.select(d);
this.calendar_.selectionChanged().trigger();
} else {
WDate j = this.calendar_.getSelection().iterator().next();
if (!(j == d || (j != null && j.equals(d)))) {
this.calendar_.select(d);
this.calendar_.selectionChanged().trigger();
}
}
this.calendar_.browseTo(d);
}
}
}