2

I have a JSF form with 2 dates. Start Date is required.

2 things I would need:

  • When the End date is filled in --> Then the Days should be calculated and filled in.
  • When the Days are filled in (example: 31) --> Then the End date should be filled in.

How can this be done in JSF?

enter image description here

My form:

<h:form id="date">

    <h:panelGrid columns="3">
        <p:outputLabel for="startDate" value="Start Date"/>
        <p:calendar id="startDate" value="#{dateBean.startDate}" required="true" pattern="d MMM yyyy"/>
        <p:message for="startDate"/>

        <p:outputLabel for="endDate" value="End Date"/>
        <p:calendar id="endDate" value="#{dateBean.endDate}" pattern="d MMM yyyy"/>
        <p:message for="endDate"/>

        <p:outputLabel for="days" value="Days"/>
        <p:inputText id="days" value="#{dateBean.days}"/>
        <p:message for="days"/>
    </h:panelGrid>

</h:form>

My Bean:

@Named(value = "dateBean")
@SessionScoped
public class DateBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Date startDate;
    private Date endDate;
    private Integer days;

    //getters and setters
    ...
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Dimitri Dewaele
  • 10,311
  • 21
  • 80
  • 127
  • 1
    According to your date fields, is the format: MM/dd/yyyy? – drgPP May 22 '15 at 07:35
  • Correctly: I used the default format: MM/dd/yyyy – Dimitri Dewaele May 22 '15 at 07:38
  • 1
    Are you writing the dates or are you choosing the dates via the popup calendar? – Magnilex May 22 '15 at 07:53
  • I'm using the primefaces popup calendar, but i can also edit the date manually. – Dimitri Dewaele May 22 '15 at 07:55
  • 1
    for When the End date is filled in --> Then the Days should be calculated and filled in. This link provides exactly what you want : http://jsf.hatemalimam.com/DailyLab/calendar/calc.xhtml – Bhavin Panchani May 22 '15 at 09:08
  • 1
    OmniFaces could really save you a couple of hours with their collection of EL functions about Dates. http://showcase.omnifaces.org/functions/Dates – Mathieu Castets May 22 '15 at 09:55
  • @Magnilex: please don't put [java] tag on the question as long as the problem is not reproducible with a plain Java application class with main() method. [java] users are incapable of understanding and answering JSF questions and would generally only post nonsense comments which confuse the OP, and/or rep hungry nitwits would even post misleading answers based on failed Google attempts and they sometimes even get confusingly upvoted by other [java] users. I removed the [java] tag again. – BalusC May 24 '15 at 06:11

3 Answers3

5

I would rather go with the built-in Primefaces way of doing this. There is an event called dateSelect which will fire when the date has changed:

Calendar provides a dateSelect ajax behavior event to execute an instant ajax selection whenever a date is selected. If you define a method as a listener, it will be invoked by passing an org.primefaces.event.SelectEvent instance.

Using this, endDate would look like (ignoring the date format property, which seems wrong):

<p:calendar id="endDate" value="#{dateBean.endDate}">
    <p:ajax event="dateSelect" listener="#{dateBean.handleDateSelect}" update="days" />
</p:calendar>

This would register a listener to be called once a new date is selected. It would call your backing bean, and then re-render the days input field to display the new value.

In DateBean you would then implement this method to perform the logic to happen upon date selection:

public void handleDateSelect(SelectEvent event) {
    Date date = (Date) event.getObject();
    // the below method would calculate the difference in days between the dates
    calculateDaysIfStartDateIsFilled(date);
}

For the days tag, I would use p:event to trigger an event on change, that is when the value in the field changes:

<p:inputText id="days" value="#{dateBean.days}">
    <p:ajax event="change" update="endDate" listener="#{dateBean.handleDaysChange}" />
</p:inputText>

And add the following method in DateBean to perform the logic:

public void handleDaysChange() {
    calculateToDateIfStartDateIsFilled();
}
Magnilex
  • 11,584
  • 9
  • 62
  • 84
2

Use Javascript onchange event and just update the field with the desired result.

<p:calendar id="endDate" value="#{dateBean.endDate}" onchange="alertDateSelected()"/>

To calculate days between 2 dates in javascript

To get date + days in javascript

Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
-2

One suggestion would be to use JSTL format library

It may guide you to your requirments, so you can do something like this:

<fmt:parseNumber
    value="${(dateBean.endDate - dateBean.startDate) / (1000*60*60*24) }"
    integerOnly="true" var="daysDifference"/>

And set your field value as: (Update via jQuery/javascript triggering the change on the End Date field)

<p:inputText id="days" value="#{daysDifference}"/>
drgPP
  • 926
  • 2
  • 7
  • 22