3

I am having some trouble implementing an ajax listener event which detects when a date is changed on a form. I have a datatable and inside one of the columns I have an <ace:dateTimeEntry> which holds a start date field which is stored in the bean. (Note: alliance is the name of the variable used for the datatable).

<ace:column headerText="Start Date" rendered="#{not alliance.deletePending}">
    <ace:dateTimeEntry id="startDateField" value="#{alliance.allianceStartDate}" pattern="dd/MMM/yyyy" renderAsPopup="true" effect="fadeIn">
        <ace:ajax execute="@this" render="@this" event="dateSelect" listener="#{allianceViewBean.changeAllianceActiveIndicator}"/>
        <ace:ajax execute="@this" render="@this" event="dateTextChange" listener="#{allianceViewBean.changeAllianceActiveIndicator}"/>
    </ace:dateTimeEntry>
</ace:column>

I am using an tag which calls a listener method in the bean called

#{allianceViewBean.changeAllianceActiveIndicator}

This is the bean value change method:

public void changeAllianceActiveIndicator(AjaxBehaviorEvent event) {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    Calendar c = Calendar.getInstance();
    c.setTimeZone(TimeZone.getTimeZone("UTC"));

    java.util.Date currentDate = c.getTime();

    for (AllianceBean bean : carrierAllianceDetails) {
        if ((bean.getAllianceStartDate().compareTo(currentDate) < 0)
            && (bean.getAllianceEndDate().compareTo(currentDate) > 0)) {
            bean.setActive(true);
        } else {
            bean.setActive(false);
        }
    }
}

However, when I debug this method errors occur. The listener correctly reaches the method but the start date value in the bean is not the updated value and it still refers to the old value before the change. If i enter a new value on the form, the value in the bean is always referring to the previously entered date value. The logic is correct in the method but the values being checked are not.

I am not sure how to ensure that the listener method picks up the latest value from the form.

Thanks

nutfox
  • 484
  • 3
  • 13
LiamWilson94
  • 458
  • 2
  • 7
  • 26
  • It seems like the "dateTextChange" listener works for when the date is typed in. However the "dateSelect" listener does not update the bean value when a date is selected form the . – LiamWilson94 May 01 '15 at 12:57
  • Basically, I would like to set the bean property before the ajax listener. – LiamWilson94 May 01 '15 at 14:15

1 Answers1

1

This is due to the lifecycle phase you are in. Check the lifecycle phase in which this event comes in. If it is before the UPDATE_MODEL_VALUES phase (e.g. in the PROCESS_VALIDATIONS phase) then your bean values are simply not updated yet. In that case I would recommend to set the phaseId to INVOKE_APPLICATION on the event, queue it and return the method:

public void changeAllianceActiveIndicator(AjaxBehaviorEvent event) {
    if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION) {
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        return;
    }

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    Calendar c = Calendar.getInstance();
    c.setTimeZone(TimeZone.getTimeZone("UTC"));

    java.util.Date currentDate = c.getTime();

    for (AllianceBean bean : carrierAllianceDetails) {
        if ((bean.getAllianceStartDate().compareTo(currentDate) < 0)
            && (bean.getAllianceEndDate().compareTo(currentDate) > 0)) {
            bean.setActive(true);
        } else {
            bean.setActive(false);
        }
    }
}

Apart from that the code of your method is not ideal either. Setting the default timeZone is pretty obsolete - as well the whole Calendar block. You could just do

Date currentDate = new Date();

I would also recommend to convert the date that is set on the bean to the server timeZone's date - otherwise you are comparing apples and oranges.

nutfox
  • 484
  • 3
  • 13