Как заставить календарь 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.

Другие вопросы по тегам