使用 p:calendar 相互限制开始和结束日期时间(无验证)
我们需要向用户呈现两个 p:calendar 组件,分别表示一个开始日期和结束日期。两个日期时间都有日期、小时和分钟。PrimeFaces 具有完美的 、、 、 和可用的属性。mindate
maxdate
minHour
maxHour
minMinute
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:日历组件无法知道这一点,现在
sets the end datetime to 2013-04-20 00:00 (legit, but false)
...
现在的问题是,当用户在日历中按某个新的结束日期时,mindate/maxdate 属性无法限制用户点击与开始日期相同的日期。如果结束日期时间现在恰好在同一开始日期的时间之前,那么我们对此无能为力(这是错误的)。
现在的后续问题是,用户能够关闭日历,只需按提交按钮即可将虚假数据插入数据库。当然,可以/应该运行验证器,但是我们必须在没有验证器的情况下以某种方式实现这一目标。
我们接下来要尝试的是修补 和 方法,以调整设定的时间部分(如果日期在同一天)。像这样:setSelectedBeginDate( Date selectedBeginDate )
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 ) );
}
}
}
这要求我们添加每个属性,以便在更新期间调用相应的 getter(和 + 最小/最大限制器)。@this
update
p:calendar
getSelectedBeginDate()
getSelectedEndDate
但是,在更新上放置 a 会混淆 p:calendar 组件,使时间滑块只能滑动一次。后续滑块事件将被忽略,行为已损坏。@this
问
- 您通常如何解决这个问题?
- 使用方法是否实现了我们想要的?
p:remoteCommand
可选 Q:
- 为什么PrimeFaces p:calendar没有被实现来提供一个minDateTime和maxDateTime,这可能会解决手头的问题?
我敢打赌,我描述的这种情况之前已经解决了。如果您能描述一下您设法解决这个问题的方法(甚至分享部分解决方案),我将不胜感激。