我们需要向用户呈现两个 p:calendar 组件,分别代表开始日期和结束日期。两个日期时间都有日期、小时和分钟。
PrimeFaces 拥有完美mindate
, maxdate
, minHour
, maxHour
, minMinute
, and minMinute
可用属性。
现在的要求是:
不可能将开始日期时间设置为大于或等于结束日期时间。
不可能将结束日期时间设置为小于或等于结束日期时间。
以下等式应该成立:
begin datetime < end datetime
现在我们尝试了以下 JSF:
<p:calendar id="begin-date"
value="#{debugManager.selectedBeginDate}"
mindate="#{debugManager.minBeginDate}"
maxdate="#{debugManager.maxBeginDate}"
maxHour="#{debugManager.maxBeginHour}"
maxMinute="#{debugManager.maxBeginMinute}"
pattern="yyyy-MM-dd HH:mm"
showButtonPanel="true"
readonlyInput="true"
navigator="true"
showOn="button"
required="true">
<p:ajax event="dateSelect" update="end-date" />
</p:calendar>
<p:calendar id="end-date"
value="#{debugManager.selectedEndDate}"
mindate="#{debugManager.minEndDate}"
minHour="#{debugManager.minEndHour}"
minMinute="#{debugManager.minEndMinute}"
pattern="yyyy-MM-dd HH:mm"
showButtonPanel="true"
readonlyInput="true"
navigator="true"
showOn="button">
<p:ajax event="dateSelect" update="begin-date" />
</p:calendar>
这是一个示例性最小/最大方法(结束日期的中间日期):
public Date getMinEndDate()
{
return this.getSelectedBeginDate();
}
正如您所看到的,最短结束日期是当前 AJAX 选择的开始日期。正确设置结束日期不允许将开始日期设置为超过结束日期。
当将时间纳入方程式时,问题就开始了......
由于 p:calendar 的接口具有单独的方法,因此 bean 必须提供逻辑:
public int getMinEndHour()
{
Date selectedBeginDate = this.getSelectedBeginDate();
Date selectedEndDate = this.getSelectedEndDate();
if ( selectedBeginDate != null && DateUtil.isSameDay( selectedBeginDate, selectedEndDate ) )
{
return DateUtil.getHourOf( selectedBeginDate );
}
return ComplianceConstants.DEFAULT_COMPLIANCE_CASE_MIN_END_HOUR;
}
这基本上只是说如果已经设置了开始日期并且开始日期和结束日期当前相同,则限制可选择的结束时间(minHour
结束日期)到开始时间。
运营:
Set the begin datetime to 2013-04-20 12:34 (legit)
Set the end datetime to 2013-04-22 00:00 (legit)
现在,结束日期的时间为 00:00,并且只要将结束时间以某种方式调整为至少 12:35,就应该允许选择日历日期 2013-04-20。
然而 p:calendar 组件现在无法知道这一点
sets the end datetime to 2013-04-20 00:00 (legit, but false)
...
现在的问题是,当用户按下日历中某个新的结束日期时,mindate/maxdate 属性无法限制用户点击与开始日期相同的日期。如果结束日期time现在恰好是在相同的开始日期时间我们对此无能为力(这是错误的)。
现在的后续问题是用户可以关闭日历并只需按提交按钮即可将虚假数据插入数据库。当然,可以/应该运行验证器,但是我们必须以某种方式在没有验证器的情况下实现这一目标.
我们接下来尝试的是修补setSelectedBeginDate( Date selectedBeginDate )
and setSelectedEndDate( Date selectedEndDate )
调整设定的方法java.util.Date
如果日期在同一天,则时间部分。像这样的事情:
public void adjustSelectedEndDate()
{
if ( this.selectedEndDate != null )
{
this.log.infov( "adjustSelectedEndDate: b-hour = {0}, e-hour = {1}", DateUtil.getHourOf( this.selectedBeginDate ), DateUtil.getHourOf( this.selectedEndDate ) );
if ( DateUtil.isSameDay( this.selectedBeginDate, this.selectedEndDate ) &&
( DateUtil.getHourOf( this.selectedEndDate ) < DateUtil.getHourOf( this.selectedBeginDate ) ) ||
DateUtil.getHourOf( this.selectedEndDate ) == DateUtil.getHourOf( this.selectedBeginDate ) && DateUtil.getMinuteOf( this.selectedEndDate ) <= DateUtil.getMinuteOf( this.selectedBeginDate ) )
{
this.log.info( "Adjusting selected end date!" );
this.selectedEndDate = DateUtil.addOneMinuteTo( DateUtil.copyTime( this.selectedBeginDate, this.selectedEndDate ) );
}
}
}
这需要我们添加@this
to the update
每个的属性p:calendar
这样各个吸气剂(getSelectedBeginDate()
and getSelectedEndDate
+ 最小/最大限制器)将在更新期间被调用。
放置一个@this
然而,更新混淆了 p:calendar 组件,使得时间滑块只能滑动一次。随后的滑块事件将被简单地忽略,表现出损坏。
Q's
- 您通常如何解决这个问题?
- 正在使用
p:remoteCommand
如何实现我们想要的?
可选Q:
- 为什么 PrimeFaces p:calendar 没有被实现来提供单个 minDateTime 和 maxDateTime,这可能会解决当前的问题?
我敢打赌我描述的这个场景以前已经解决过。如果您能描述您设法解决此问题的方法(甚至分享部分解决方案),我将非常感激。