Как заставить календарь Primefaces обновляться после того, как событие Ajax изменения проверяет новое значение?
Я модифицирую страницу с двумя компонентами календаря, чтобы выбрать дату начала и дату окончания. Я должен заставить их проверять, что дата начала предшествует дате окончания, когда вы изменяете любую из них; если начало установлено после конца или наоборот, код изменяет дату окончания на максимальную и выдает предупреждение.
Слушатели событий работают правильно, но календарь даты окончания не обновляется, чтобы отразить новое значение; дело не в том, что он обновляется до того, как слушатель изменит значение - он вообще не обновляется.
Проект работает на Primefaces 5.3 и Java 1.6. Это xhtml (без стилей для удобства чтения):
<p:outputPanel id="fl83">
<p:outputPanel id="fl83c3">
<h:outputLabel value="Start date" for="fechaInicioMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaInicioMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaInicio}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaInicioTextChange}"
render="@this" update="@form" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaInicioClickChange}"
update="@form" />
</p:calendar>
</p:outputPanel>
<p:outputPanel id="fl83c4">
<h:outputLabel value="End date" for="fechaFinMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaFinMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaFin}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaFinTextChange}"
render="@this" update=":fl83" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaFinClickChange}"
update=":fl83" />
</p:calendar>
</p:outputPanel>
</p:outputPanel>
И это слушатели:
public void fechaFinTextChange() {
if(fechaFin.after(fechaMaxFin)) {
fechaFin = fechaMaxFin;
addErrorMessage(FFIN_AFTER_FMAX);
}
compareInicioBeforeFin();
}
public void fechaFinClickChange(SelectEvent event) {
setFechaFin((Date)event.getObject()); // I couldn't find out why this is here given that
// the setter has already been called
compareInicioBeforeFin();
if (updateMetodoEntreBB != null) {
ajaxActualiza(event, OpcionesAjax.F_FIN);
}
}
// fechaInicioTextChange and fechaInicioClickChange do pretty much the same as these two
private void compareInicioBeforeFin() {
if(fechaInicio.after(fechaFin)) {
fechaFin = fechaMaxFin;
addErrorMessage(FINI_AFTER_FFIN);
}
}
Существует два события Ajax, потому что событие изменения JSF не срабатывает при нажатии на календарь, а PrimeFaces dateSelect не срабатывает при вводе даты.
Я пробовал onSelectUpdate из календаря, а также рендеринг и обновление из обоих событий ajax, устанавливая для них значение @this, @form, идентификатор календаря конечной даты, идентификаторы обоих календарей, идентификатор outputPanel календаря и общий идентификатор outputPanel, а также чертовски календари просто. Не будет обновлять
Я сошел с ума, и мой Google Fu не находит решения, которое также работает.
2 ответа
Вам нужно установить событие ajax по щелчку календаря начальной даты:
<p:calendar id="start_date" pattern="dd/MM/yyyy HH:mm" value="#{managedBean.startDate}" size="20" >
<p:ajax event="dateSelect" listener="#{managedBean.OnSelectDate()}" update=":form:end_date" />
</p:calendar>
<p:calendar id="end_date" pattern="dd/MM/yyyy HH:mm" mindate="#{managedBean.startDate}" value="#{managedBean.endDate}" size="20" />
Когда вы выбираете startDate, который запускает метод, в котором для endDate задано значение null, и вы обновляете календарь endDate, который ограничен mindate="#{managedBean.startDate}"
public void OnSelectDateSouhaite() {
this.setEndDate(null);
}
Прежде всего: f:ajax не имеет атрибута обновления, в f: ajax вам нужно использовать атрибут render.
P:remoteCommand с атрибутом ajax oncomplete должен решить проблему:
<p:outputPanel id="fl83">
<p:remoteCommand name="updateCalendar" update="fl83" />
<p:outputPanel id="fl83c3">
<h:outputLabel value="Start date" for="fechaInicioMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaInicioMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaInicio}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaInicioTextChange}"
oncomplete="updateCalendar()" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaInicioClickChange}"
oncomplete="updateCalendar()" />
</p:calendar>
</p:outputPanel>
<p:outputPanel id="fl83c4">
<h:outputLabel value="End date" for="fechaFinMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaFinMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaFin}"
onSelectUpdate="f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaFinTextChange}"
oncomplete="updateCalendar()" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaFinClickChange}"
oncomplete="updateCalendar()" />
</p:calendar>
</p:outputPanel>
</p:outputPanel>
Если это не решает проблему: есть ли у вас форма, которая изменяет идентификаторы? Если у вас без prependId="false" form1, prepend к каждому идентификатору внутри формы. Поэтому вам нужно получить доступ к панели с помощью exampleForm:fl83.