diff options
author | Johannes Dahlström <johannes.dahlstrom@vaadin.com> | 2012-01-25 14:07:13 +0000 |
---|---|---|
committer | Johannes Dahlström <johannes.dahlstrom@vaadin.com> | 2012-01-25 14:07:13 +0000 |
commit | 7396c309a4699e1e61b03cb17d005084758a25ed (patch) | |
tree | 928e06e9963d8c748fd34f035ac0d1a82615bb93 | |
parent | 4f50c1b2c01728a5dd4e3efbcb157d7094eebbd5 (diff) | |
download | vaadin-framework-7396c309a4699e1e61b03cb17d005084758a25ed.tar.gz vaadin-framework-7396c309a4699e1e61b03cb17d005084758a25ed.zip |
#6718 Extend PopupDateField range - allow selection of the last days of the
preceding month and the first days of the following month without switching
to that month
Changes:
- Internally use Date objects instead of day-of-month integers to track the
selected and focused date
- Keep track of the currently displayed month separately from the currently
focused date
- New CSS class for off-month dates: .v-datefield-calendarpanel-day-offmonth
- Off-month days map to negative or past-the-end-of-month integer ids in
getSubPart functions
- The popup now always shows exactly 6 weeks, so that depending on the month,
1 to 7 days of the preceding month and 4 to 13 days of the following month
are shown
svn changeset:22758/svn branch:6.8
-rw-r--r-- | WebContent/VAADIN/themes/base/datefield/datefield.css | 3 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java | 200 |
2 files changed, 96 insertions, 107 deletions
diff --git a/WebContent/VAADIN/themes/base/datefield/datefield.css b/WebContent/VAADIN/themes/base/datefield/datefield.css index 72d9510c3f..8e2e9aeb2b 100644 --- a/WebContent/VAADIN/themes/base/datefield/datefield.css +++ b/WebContent/VAADIN/themes/base/datefield/datefield.css @@ -60,6 +60,9 @@ .v-datefield-calendarpanel-day-focused { outline: 1px dotted black; } +.v-datefield-calendarpanel-day-offmonth { + color: #666; +} .v-ie6 .v-datefield-calendarpanel-day, .v-ie7 .v-datefield-calendarpanel-day { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java index 3b1ee273d5..3b74232112 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java @@ -103,6 +103,8 @@ public class VCalendarPanel extends FocusableFlexTable implements private static final String CN_SELECTED = "selected";
+ private static final String CN_OFFMONTH = "offmonth";
+
/**
* Represents a click handler for when a user selects a value by using the
* mouse
@@ -117,7 +119,7 @@ public class VCalendarPanel extends FocusableFlexTable implements */
public void onClick(ClickEvent event) {
Day day = (Day) event.getSource();
- focusDay(day.getDay());
+ focusDay(day.getDate());
selectFocused();
onSubmit();
}
@@ -151,6 +153,8 @@ public class VCalendarPanel extends FocusableFlexTable implements private boolean showISOWeekNumbers;
+ private Date displayedMonth;
+
private Date focusedDate;
private Day selectedDay;
@@ -190,18 +194,18 @@ public class VCalendarPanel extends FocusableFlexTable implements * Sets the focus to given day of current time. Used when moving in the
* calender with the keyboard.
*
- * @param day
+ * @param date
* The day number from by Date.getDate()
*/
- private void focusDay(int day) {
+ private void focusDay(Date day) {
// Only used when calender body is present
if (resolution > VDateField.RESOLUTION_MONTH) {
if (focusedDay != null) {
focusedDay.removeStyleDependentName(CN_FOCUSED);
}
- if (day > 0 && focusedDate != null) {
- focusedDate.setDate(day);
+ if (day != null && focusedDate != null) {
+ focusedDate.setTime(day.getTime());
int rowCount = days.getRowCount();
for (int i = 0; i < rowCount; i++) {
int cellCount = days.getCellCount(i);
@@ -209,7 +213,7 @@ public class VCalendarPanel extends FocusableFlexTable implements Widget widget = days.getWidget(i, j);
if (widget != null && widget instanceof Day) {
Day curday = (Day) widget;
- if (curday.getDay() == day) {
+ if (curday.getDate().equals(day)) {
curday.addStyleDependentName(CN_FOCUSED);
focusedDay = curday;
focusedRow = i;
@@ -225,9 +229,9 @@ public class VCalendarPanel extends FocusableFlexTable implements /**
* Sets the selection hightlight to a given date of current time
*
- * @param day
+ * @param date
*/
- private void selectDate(int day) {
+ private void selectDate(Date date) {
if (selectedDay != null) {
selectedDay.removeStyleDependentName(CN_SELECTED);
}
@@ -239,7 +243,7 @@ public class VCalendarPanel extends FocusableFlexTable implements Widget widget = days.getWidget(i, j);
if (widget != null && widget instanceof Day) {
Day curday = (Day) widget;
- if (curday.getDay() == day) {
+ if (curday.getDate().equals(date)) {
curday.addStyleDependentName(CN_SELECTED);
selectedDay = curday;
return;
@@ -278,7 +282,7 @@ public class VCalendarPanel extends FocusableFlexTable implements // it was forced to 1 above.
value.setDate(focusedDate.getDate());
- selectDate(focusedDate.getDate());
+ selectDate(focusedDate);
} else {
VConsole.log("Trying to select a the focused date which is NULL!");
}
@@ -467,97 +471,62 @@ public class VCalendarPanel extends FocusableFlexTable implements }
}
- // The day of month that is selected, -1 if no day of this month is
- // selected (i.e, showing another month/year than selected or nothing is
- // selected)
- int dayOfMonthSelected = -1;
- // The day of month that is today, -1 if no day of this month is today
- // (i.e., showing another month/year than current)
- int dayOfMonthToday = -1;
-
- boolean initiallyNull = value == null;
-
- if (!initiallyNull && value.getMonth() == focusedDate.getMonth()
- && value.getYear() == focusedDate.getYear()) {
- dayOfMonthSelected = value.getDate();
- }
- final Date today = new Date();
- if (today.getMonth() == focusedDate.getMonth()
- && today.getYear() == focusedDate.getYear()) {
- dayOfMonthToday = today.getDate();
- }
+ // today must have zeroed hours, minutes, seconds, and milliseconds
+ final Date tmp = new Date();
+ final Date today = new Date(tmp.getYear(), tmp.getMonth(),
+ tmp.getDate());
final int startWeekDay = getDateTimeService().getStartWeekDay(
focusedDate);
- final int daysInMonth = DateTimeService
- .getNumberOfDaysInMonth(focusedDate);
-
- int dayCount = 0;
- final Date curr = new Date(focusedDate.getTime());
+ final Date curr = (Date) focusedDate.clone();
+ // Start from the first day of the week that at least partially belongs
+ // to the current month
+ curr.setDate(-startWeekDay);
// No month has more than 6 weeks so 6 is a safe maximum for rows.
for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {
- boolean weekNumberProcessed[] = new boolean[] { false, false,
- false, false, false, false, false };
-
for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
- if (!(weekOfMonth == 1 && dayOfWeek < startWeekDay)) {
-
- if (dayCount >= daysInMonth) {
- // All days printed and we are done
- break;
- }
-
- final int dayOfMonth = ++dayCount;
-
- curr.setDate(dayCount);
- // Actually write the day of month
- Day day = new Day(dayOfMonth);
+ // Actually write the day of month
+ Day day = new Day((Date) curr.clone());
- if (dayOfMonthSelected == dayOfMonth) {
- day.addStyleDependentName(CN_SELECTED);
- selectedDay = day;
+ if (curr.equals(value)) {
+ day.addStyleDependentName(CN_SELECTED);
+ selectedDay = day;
+ }
+ if (curr.equals(today)) {
+ day.addStyleDependentName(CN_TODAY);
+ }
+ if (curr.equals(focusedDate)) {
+ focusedDay = day;
+ focusedRow = weekOfMonth;
+ if (hasFocus) {
+ day.addStyleDependentName(CN_FOCUSED);
}
+ }
+ if (curr.getMonth() != focusedDate.getMonth()) {
+ day.addStyleDependentName(CN_OFFMONTH);
+ }
- if (dayOfMonthToday == dayOfMonth) {
- day.addStyleDependentName(CN_TODAY);
- }
+ days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);
- if (dayOfMonth == focusedDate.getDate()) {
- focusedDay = day;
- focusedRow = weekOfMonth;
- if (hasFocus) {
- day.addStyleDependentName(CN_FOCUSED);
- }
- }
+ // ISO week numbers if requested
+ days.getCellFormatter().setVisible(weekOfMonth, weekColumn,
+ isShowISOWeekNumbers());
+ if (isShowISOWeekNumbers()) {
+ final String baseCssClass = VDateField.CLASSNAME
+ + "-calendarpanel-weeknumber";
+ String weekCssClass = baseCssClass;
- days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek,
- day);
-
- // ISO week numbers if requested
- if (!weekNumberProcessed[weekOfMonth]) {
- days.getCellFormatter().setVisible(weekOfMonth,
- weekColumn, isShowISOWeekNumbers());
- if (isShowISOWeekNumbers()) {
- final String baseCssClass = VDateField.CLASSNAME
- + "-calendarpanel-weeknumber";
- String weekCssClass = baseCssClass;
-
- int weekNumber = DateTimeService
- .getISOWeekNumber(curr);
-
- days.setHTML(weekOfMonth, 0, "<span class=\""
- + weekCssClass + "\"" + ">" + weekNumber
- + "</span>");
- weekNumberProcessed[weekOfMonth] = true;
- }
+ int weekNumber = DateTimeService.getISOWeekNumber(curr);
- }
+ days.setHTML(weekOfMonth, 0, "<span class=\""
+ + weekCssClass + "\"" + ">" + weekNumber
+ + "</span>");
}
+ curr.setDate(curr.getDate() + 1);
}
}
-
}
/**
@@ -621,6 +590,7 @@ public class VCalendarPanel extends FocusableFlexTable implements while (focusedDate.getMonth() != requestedMonth) {
focusedDate.setDate(focusedDate.getDate() - 1);
}
+ displayedMonth.setMonth(displayedMonth.getMonth() + 1);
renderCalendar();
}
@@ -640,6 +610,7 @@ public class VCalendarPanel extends FocusableFlexTable implements while (focusedDate.getMonth() == currentMonth) {
focusedDate.setDate(focusedDate.getDate() - 1);
}
+ displayedMonth.setMonth(displayedMonth.getMonth() - 1);
renderCalendar();
}
@@ -649,6 +620,7 @@ public class VCalendarPanel extends FocusableFlexTable implements */
private void focusPreviousYear(int years) {
focusedDate.setYear(focusedDate.getYear() - years);
+ displayedMonth.setYear(displayedMonth.getYear() - years);
renderCalendar();
}
@@ -657,6 +629,7 @@ public class VCalendarPanel extends FocusableFlexTable implements */
private void focusNextYear(int years) {
focusedDate.setYear(focusedDate.getYear() + years);
+ displayedMonth.setYear(displayedMonth.getYear() + years);
renderCalendar();
}
@@ -905,7 +878,7 @@ public class VCalendarPanel extends FocusableFlexTable implements if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
// Month did not change, only move the selection
- focusDay(focusedDate.getDate() + 1);
+ focusDay(newCurrentDate);
} else {
// If the month changed we need to re-render the calendar
focusedDate.setDate(focusedDate.getDate() + 1);
@@ -924,7 +897,7 @@ public class VCalendarPanel extends FocusableFlexTable implements if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
// Month did not change, only move the selection
- focusDay(focusedDate.getDate() - 1);
+ focusDay(newCurrentDate);
} else {
// If the month changed we need to re-render the calendar
focusedDate.setDate(focusedDate.getDate() - 1);
@@ -944,10 +917,10 @@ public class VCalendarPanel extends FocusableFlexTable implements if (newCurrentDate.getMonth() == focusedDate.getMonth()
&& focusedRow > 1) {
// Month did not change, only move the selection
- focusDay(focusedDate.getDate() - 7);
+ focusDay(newCurrentDate);
} else {
// If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() - 7);
+ focusedDate = newCurrentDate;
renderCalendar();
}
@@ -963,10 +936,10 @@ public class VCalendarPanel extends FocusableFlexTable implements if (newCurrentDate.getMonth() == focusedDate.getMonth()) {
// Month did not change, only move the selection
- focusDay(focusedDate.getDate() + 7);
+ focusDay(newCurrentDate);
} else {
// If the month changed we need to re-render the calendar
- focusedDate.setDate(focusedDate.getDate() + 7);
+ focusedDate = newCurrentDate;
renderCalendar();
}
@@ -1210,27 +1183,28 @@ public class VCalendarPanel extends FocusableFlexTable implements return;
}
- Date oldFocusedValue = focusedDate;
+ Date oldDisplayedMonth = displayedMonth;
value = currentDate;
if (value == null) {
- focusedDate = null;
+ focusedDate = displayedMonth = null;
} else {
focusedDate = (Date) value.clone();
+ displayedMonth = (Date) value.clone();
}
// Re-render calendar if month or year of focused date has changed
- if (oldFocusedValue == null || value == null
- || oldFocusedValue.getYear() != value.getYear()
- || oldFocusedValue.getMonth() != value.getMonth()) {
+ if (oldDisplayedMonth == null || value == null
+ || oldDisplayedMonth.getYear() != value.getYear()
+ || oldDisplayedMonth.getMonth() != value.getMonth()) {
renderCalendar();
} else {
- focusDay(currentDate.getDate());
+ focusDay(currentDate);
selectFocused();
}
if (!hasFocus) {
- focusDay(-1);
+ focusDay((Date) null);
}
}
@@ -1555,17 +1529,17 @@ public class VCalendarPanel extends FocusableFlexTable implements private class Day extends InlineHTML {
private static final String BASECLASS = VDateField.CLASSNAME
+ "-calendarpanel-day";
- private final int day;
+ private final Date date;
- Day(int dayOfMonth) {
- super("" + dayOfMonth);
+ Day(Date date) {
+ super("" + date.getDate());
setStyleName(BASECLASS);
- day = dayOfMonth;
+ this.date = date;
addClickHandler(dayClickHandler);
}
- public int getDay() {
- return day;
+ public Date getDate() {
+ return date;
}
}
@@ -1648,7 +1622,7 @@ public class VCalendarPanel extends FocusableFlexTable implements public void onBlur(final BlurEvent event) {
if (event.getSource() instanceof VCalendarPanel) {
hasFocus = false;
- focusDay(-1);
+ focusDay(null);
}
}
@@ -1665,7 +1639,7 @@ public class VCalendarPanel extends FocusableFlexTable implements // Focuses the current day if the calendar shows the days
if (focusedDay != null) {
- focusDay(focusedDay.getDay());
+ focusDay(focusedDate);
}
}
}
@@ -1696,7 +1670,15 @@ public class VCalendarPanel extends FocusableFlexTable implements // Day, find out which dayOfMonth and use that as the identifier
Day day = Util.findWidget(subElement, Day.class);
if (day != null) {
- return SUBPART_DAY + day.getDay();
+ Date date = day.getDate();
+ int id = date.getDate();
+ if (date.getMonth() < displayedMonth.getMonth()) {
+ id -= DateTimeService.getNumberOfDaysInMonth(date);
+ } else if (date.getMonth() > displayedMonth.getMonth()) {
+ id += DateTimeService
+ .getNumberOfDaysInMonth(displayedMonth);
+ }
+ return SUBPART_DAY + id;
}
} else if (time != null) {
if (contains(time.hours, subElement)) {
@@ -1762,14 +1744,18 @@ public class VCalendarPanel extends FocusableFlexTable implements return time.ampm.getElement();
}
if (subPart.startsWith(SUBPART_DAY)) {
+ // can be less than 1 or greater than the number of days in the current month
+ // these map to the "off-month" days
int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY
.length()));
+ Date date = new Date(displayedMonth.getYear(),
+ displayedMonth.getMonth(), dayOfMonth);
Iterator<Widget> iter = days.iterator();
while (iter.hasNext()) {
Widget w = iter.next();
if (w instanceof Day) {
Day day = (Day) w;
- if (day.getDay() == dayOfMonth) {
+ if (day.getDate().equals(date)) {
return day.getElement();
}
}
|