Skip to content

Commit

Permalink
Fix date ranges for date and datetime fields (#10685)
Browse files Browse the repository at this point in the history
Fixes #9765
  • Loading branch information
Ilia Motornyi authored and tsuoanttila committed Mar 20, 2018
1 parent 803a453 commit ec314ee
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 78 deletions.
1 change: 1 addition & 0 deletions all/src/main/templates/release-notes.html
Expand Up @@ -98,6 +98,7 @@ <h2 id="enhancements">Enhancements in Vaadin Framework @version-minor@</h2>
<h2 id="incompatible">Incompatible or Behavior-altering Changes in @version-minor@</h2>

<li><tt>BindingBuilder</tt> will now automatically mark bound field <i>read-only</i> when bound to a read-only property or a <tt>null</tt> setter.</li>
<li>Date range limits in <tt>AbstractDateFieldState</tt> are now <tt>String</tt>s instead of <tt>Date</tt>s, some client-side method signatures were changed</li>

<h2>For incompatible or behavior-altering changes in 8.3, please see <a href="https://vaadin.com/download/release/8.3/8.3.0/release-notes.html#incompatible">8.3 release notes</a></h2>

Expand Down
11 changes: 11 additions & 0 deletions client/src/main/java/com/vaadin/client/DateTimeService.java
Expand Up @@ -60,6 +60,17 @@ public DateTimeService(String locale) throws LocaleNotLoadedException {
setLocale(locale);
}

/**
* Utility method to format positive int as zero-padded two-digits number
*
* @param i the value
* @return "00".."99"
* @since
*/
public static String asTwoDigits(int i) {
return (i < 10 ? "0" : "") + i;
}

public void setLocale(String locale) throws LocaleNotLoadedException {
if (!LocaleService.getAvailableLocales().contains(locale)) {
throw new LocaleNotLoadedException(locale);
Expand Down
6 changes: 2 additions & 4 deletions client/src/main/java/com/vaadin/client/ui/CalendarEntry.java
Expand Up @@ -20,6 +20,8 @@

import com.vaadin.client.DateTimeService;

import static com.vaadin.client.DateTimeService.asTwoDigits;

public class CalendarEntry {
private final String styleName;
private Date start;
Expand Down Expand Up @@ -137,8 +139,4 @@ public String getStringForDate(Date d) {
return s;
}

private static String asTwoDigits(int i) {
return (i < 10 ? "0" : "") + i;
}

}
Expand Up @@ -60,6 +60,8 @@
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.shared.util.SharedUtil;

import static com.vaadin.client.DateTimeService.asTwoDigits;

/**
* Abstract calendar panel to show and select a date using a resolution. The
* class is parameterized by the date resolution enumeration type.
Expand Down Expand Up @@ -719,21 +721,23 @@ private boolean isAcceptedByRangeStart(Date date, R minResolution) {
return true;
}

Date valueDuplicate = (Date) date.clone();
Date rangeStartDuplicate = (Date) rangeStart.clone();
String dateStrResolution = dateStrResolution(date, minResolution);
return rangeStart.substring(0,dateStrResolution.length())
.compareTo(dateStrResolution) <=0;
}

if (isYear(minResolution)) {
return valueDuplicate.getYear() >= rangeStartDuplicate.getYear();
private String dateStrResolution(Date date, R minResolution) {
String dateStrResolution = (1900 + date.getYear()) + "";
while (dateStrResolution.length() < 4) {
dateStrResolution = "0" + dateStrResolution;
}
if (isMonth(minResolution)) {
valueDuplicate = clearDateBelowMonth(valueDuplicate);
rangeStartDuplicate = clearDateBelowMonth(rangeStartDuplicate);
} else {
valueDuplicate = clearDateBelowDay(valueDuplicate);
rangeStartDuplicate = clearDateBelowDay(rangeStartDuplicate);
if (!isYear(minResolution)) {
dateStrResolution += "-" + asTwoDigits(1 + date.getMonth());
if (!isMonth(minResolution)) {
dateStrResolution += "-" + asTwoDigits(date.getDate());
}
}

return !rangeStartDuplicate.after(valueDuplicate);
return dateStrResolution;
}

/**
Expand All @@ -755,22 +759,9 @@ private boolean isAcceptedByRangeEnd(Date date, R minResolution) {
return true;
}

Date valueDuplicate = (Date) date.clone();
Date rangeEndDuplicate = (Date) rangeEnd.clone();

if (isYear(minResolution)) {
return valueDuplicate.getYear() <= rangeEndDuplicate.getYear();
}
if (isMonth(minResolution)) {
valueDuplicate = clearDateBelowMonth(valueDuplicate);
rangeEndDuplicate = clearDateBelowMonth(rangeEndDuplicate);
} else {
valueDuplicate = clearDateBelowDay(valueDuplicate);
rangeEndDuplicate = clearDateBelowDay(rangeEndDuplicate);
}

return !rangeEndDuplicate.before(valueDuplicate);

String dateStrResolution = dateStrResolution(date, minResolution);
return rangeEnd.substring(0,dateStrResolution.length())
.compareTo(dateStrResolution) >= 0;
}

private static Date clearDateBelowMonth(Date date) {
Expand Down Expand Up @@ -1691,14 +1682,32 @@ public void onMouseUp(MouseUpEvent event) {
* @param date
*/
private Date adjustDateToFitInsideRange(Date date) {
if (rangeStart != null && rangeStart.after(date)) {
date = (Date) rangeStart.clone();
} else if (rangeEnd != null && rangeEnd.before(date)) {
date = (Date) rangeEnd.clone();
if(!isAcceptedByRangeStart(date,resolution)) {
date = parseRangeString(rangeStart);
} else
if(!isAcceptedByRangeEnd(date,resolution)) {
date = parseRangeString(rangeEnd);
}
return date;
}

private Date parseRangeString(String dateStr) {
if(dateStr == null || "".equals(dateStr)) return null;
int year = Integer.parseInt(dateStr.substring(0,4)) - 1900;
int month = parsePart(dateStr, 5, 2,1) - 1;
int day = parsePart(dateStr, 8, 2,1);
int hrs = parsePart(dateStr, 11, 2,0);
int min = parsePart(dateStr, 14, 2,0);
int sec = parsePart(dateStr, 17, 2,0);

return new Date(year,month,day,hrs,min,sec);
}

private int parsePart(String dateStr, int beginIndex, int length, int defValue) {
if(dateStr.length() < beginIndex + length) return defValue;
return Integer.parseInt(dateStr.substring(beginIndex, beginIndex + length));
}

/**
* Sets the data of the Panel.
*
Expand Down Expand Up @@ -1914,9 +1923,9 @@ public void onFocus(FocusEvent event) {
private static final String SUBPART_DAY = "day";
private static final String SUBPART_MONTH_YEAR_HEADER = "header";

private Date rangeStart;
private String rangeStart;

private Date rangeEnd;
private String rangeEnd;

@Override
public String getSubPartName(
Expand Down Expand Up @@ -2070,7 +2079,7 @@ private void setLabel() {
* @param newRangeStart
* - the allowed range's start date
*/
public void setRangeStart(Date newRangeStart) {
public void setRangeStart(String newRangeStart) {
if (!SharedUtil.equals(rangeStart, newRangeStart)) {
rangeStart = newRangeStart;
if (initialRenderDone) {
Expand All @@ -2088,7 +2097,7 @@ public void setRangeStart(Date newRangeStart) {
* @param newRangeEnd
* - the allowed range's end date
*/
public void setRangeEnd(Date newRangeEnd) {
public void setRangeEnd(String newRangeEnd) {
if (!SharedUtil.equals(rangeEnd, newRangeEnd)) {
rangeEnd = newRangeEnd;
if (initialRenderDone) {
Expand Down
Expand Up @@ -599,7 +599,7 @@ public String getDescriptionForAssistiveDevices() {
* @param rangeStart
* - the allowed range's start date
*/
public void setRangeStart(Date rangeStart) {
public void setRangeStart(String rangeStart) {
calendar.setRangeStart(rangeStart);
}

Expand All @@ -610,7 +610,7 @@ public void setRangeStart(Date rangeStart) {
* @param rangeEnd
* - the allowed range's end date
*/
public void setRangeEnd(Date rangeEnd) {
public void setRangeEnd(String rangeEnd) {
calendar.setRangeEnd(rangeEnd);
}

Expand Down
Expand Up @@ -79,8 +79,6 @@ private ListBox createListBox() {
/**
* Constructs the ListBoxes and updates their value
*
* @param redraw
* Should new instances of the listboxes be created
*/
private void buildTime() {
clear();
Expand All @@ -89,11 +87,11 @@ private void buildTime() {
if (getDateTimeService().isTwelveHourClock()) {
hours.addItem("12");
for (int i = 1; i < 12; i++) {
hours.addItem(asTwoDigits(i));
hours.addItem(DateTimeService.asTwoDigits(i));
}
} else {
for (int i = 0; i < 24; i++) {
hours.addItem(asTwoDigits(i));
hours.addItem(DateTimeService.asTwoDigits(i));
}
}

Expand All @@ -109,14 +107,14 @@ private void buildTime() {
if (getResolution().compareTo(DateTimeResolution.MINUTE) <= 0) {
mins = createListBox();
for (int i = 0; i < 60; i++) {
mins.addItem(asTwoDigits(i));
mins.addItem(DateTimeService.asTwoDigits(i));
}
mins.addChangeHandler(this);
}
if (getResolution().compareTo(DateTimeResolution.SECOND) <= 0) {
sec = createListBox();
for (int i = 0; i < 60; i++) {
sec.addItem(asTwoDigits(i));
sec.addItem(DateTimeService.asTwoDigits(i));
}
sec.addChangeHandler(this);
}
Expand All @@ -130,7 +128,7 @@ private void buildTime() {
if (getDateTimeService().isTwelveHourClock()) {
h -= h < 12 ? 0 : 12;
}
add(new VLabel(asTwoDigits(h)));
add(new VLabel(DateTimeService.asTwoDigits(h)));
} else {
add(hours);
}
Expand All @@ -139,7 +137,7 @@ private void buildTime() {
add(new VLabel(delimiter));
if (isReadonly()) {
final int m = mins.getSelectedIndex();
add(new VLabel(asTwoDigits(m)));
add(new VLabel(DateTimeService.asTwoDigits(m)));
} else {
add(mins);
}
Expand All @@ -148,7 +146,7 @@ private void buildTime() {
add(new VLabel(delimiter));
if (isReadonly()) {
final int s = sec.getSelectedIndex();
add(new VLabel(asTwoDigits(s)));
add(new VLabel(DateTimeService.asTwoDigits(s)));
} else {
add(sec);
}
Expand Down Expand Up @@ -308,10 +306,6 @@ public void onChange(ChangeEvent event) {
}
}

private static String asTwoDigits(int i) {
return (i < 10 ? "0" : "") + i;
}

/**
* Dispatches an event when the panel when time is changed.
*/
Expand Down
Expand Up @@ -123,8 +123,8 @@ public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);

getWidget().setTextFieldEnabled(getState().textFieldEnabled);
getWidget().setRangeStart(nullSafeDateClone(getState().rangeStart));
getWidget().setRangeEnd(nullSafeDateClone(getState().rangeEnd));
getWidget().setRangeStart(getState().rangeStart);
getWidget().setRangeEnd(getState().rangeEnd);

getWidget().calendar.setDateStyles(getState().dateStyles);
getWidget().calendar
Expand Down Expand Up @@ -167,13 +167,6 @@ && getWidget().getCurrentDate() != null) {
getWidget().setTextFieldTabIndex();
}

private Date nullSafeDateClone(Date date) {
if (date != null) {
return (Date) date.clone();
}
return null;
}

@Override
protected void setWidgetStyleName(String styleName, boolean add) {
super.setWidgetStyleName(styleName, add);
Expand Down

0 comments on commit ec314ee

Please sign in to comment.