Reputation: 5374
Am using PrimeFaces 10.0.0. I need to dynamically set the maxdate
to be 10 years from now when using p:datePicker
with a fixed mindate
.
Utility bean to set maxdate
:
@Named @ApplicationScoped
public class Dates {
public LocalDate getLocalDateNow() {
return LocalDate.now();
}
}
Date picker:
<p:datePicker pattern="MM/dd/yyyy"
mindate="1/1/2011"
maxdate="#{dates.localDateNow.plusYears(10)}"
.../>
Throws this exception:
javax.servlet.ServletException: java.lang.String cannot be cast to java.time.chrono.ChronoLocalDate
...
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.time.chrono.ChronoLocalDate
at java.time.LocalDate.compareTo(LocalDate.java:137)
at org.primefaces.component.api.UICalendar.validateMinMax(UICalendar.java:375)
at org.primefaces.component.calendar.BaseCalendarRenderer.encodeEnd(BaseCalendarRenderer.java:84)
at org.primefaces.component.datepicker.DatePickerRenderer.encodeEnd(DatePickerRenderer.java:89)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:619)
...
When I changed my utility bean to return a String
:
public String getLocalDateNow() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/uuuu");
LocalDate localDateNow = LocalDate.now().plusYears(10);
return localDateNow.format(dtf);
}
And subsequently:
maxdate="#{dates.localDateNow}"
This is what happens:
javax.servlet.ServletException: DatePicker : "form:startDate" minimum date must be less than maximum date.
...
Caused by: javax.faces.FacesException: DatePicker : "form:serviceStart" minimum date must be less than maximum date.
at org.primefaces.component.api.UICalendar.validateMinMax(UICalendar.java:378)
at org.primefaces.component.calendar.BaseCalendarRenderer.encodeEnd(BaseCalendarRenderer.java:84)
at
...
How can I prevent these exceptions?
Upvotes: 2
Views: 3130
Reputation: 20188
Take a look at the source code of UICalendar.validateMinMax
:
public void validateMinMax(FacesContext context) {
Comparable minDate = (Comparable) getMindate();
Comparable maxDate = (Comparable) getMaxdate();
if (minDate != null && maxDate != null && maxDate.compareTo(minDate) < 0) {
String id = getClientId(context);
String component = this.getClass().getSimpleName();
throw new FacesException(component + " : \"" + id + "\" minimum date must be less than maximum date.");
}
}
It simply checks for Comparable
and does not care about the actual type. If you are using LocalDate
for one date and String
for the other, comparing will lead to an error (as shown in your first stack trace).
Using String
for both is also no good, as comparing strings has nothing to do with a date value. It might, if you would use a date pattern like yyyy-MM-dd
, but it's better not to use strings.
You should use the same (non-string) type (for example LocalDate
) for both min and max dates and it will work.
That being said, the current implementation of validateMinMax
is flawed. This has already been reported (and fixed while writing this answer):
Fix will end up in PrimeFaces 11.
By the way, this code is shared with the p:calendar
component, so the same principle applies there. Note though that p:calendar
is deprecated!
Upvotes: 4