PrimeFaces - Cancelable Date Range Picker with second selectable date always starts from the first one

[Updated: Jun 15, 2017, Created: Jun 14, 2017]

In the last example, we saw how to restrict second Calendar minimum selectable date value always starts from the first calendar selected date. In this case, we will extend the same idea but we will also provide the option for canceling the current selected values in the dialog.

JSF page

src/main/webapp/index.xhtml

<h:body>
    <h2>Primefaces Date Range Picker example</h2>
    <p:outputPanel id="mainPanel">
        <p:outputLabel value="#{dateRange.dateRangeString}"/>
    </p:outputPanel>
    <p:commandButton value="Select new date range" type="button"
                     onclick="PF('dateRangeDlg').show();"/>

    <p:dialog id="theDialog" closable="false"
              header="Date Range Picker" resizable="false" widgetVar="dateRangeDlg"
              minHeight="40" modal="true" dynamic="true">
        <p:outputPanel>
            <h:form>
                <p:calendar id="idStartDate" widgetVar="varStartDate"
                            value="#{dateEditor.startDate}" readonlyInput="true">
                 <p:ajax event="dateSelect" update="idEndDate"/>
                </p:calendar>
                <p:calendar id="idEndDate" widgetVar="varEndDate"
                            value="#{dateEditor.endDate}" readonlyInput="true"
                            mindate="#{dateEditor.startDate}">
                </p:calendar>
                <br/>

                <p:commandButton value="Save" icon="ui-icon-close"
                                 update=":mainPanel"
                                 actionListener="#{dateEditor.saveSelection}"
                                 onclick="PF('dateRangeDlg').hide();"/>
                <p:commandButton value="Cancel" icon="ui-icon-close"
                                 actionListener="#{dateEditor.reset}"
                                 update="idStartDate idEndDate"
                                 onclick="PF('dateRangeDlg').hide();" />
            </h:form>
        </p:outputPanel>
    </p:dialog>
</h:body>

The manage beans

As seen in above JSF code, we are referencing two beans. One is a container for start/end dates with session scope and other is for editing the date range with view scope:

public class DateRangeBean {

  private Date startDate;
  private Date endDate;

  public Date getStartDate() {
      return startDate;
  }

  public void setStartDate(Date startDate) {
      this.startDate = startDate;
      if (endDate != null && endDate.before(startDate)) {
          endDate = startDate;
      }
  }

  public Date getEndDate() {
      return endDate;
  }

  public void setEndDate(Date endDate) {
      this.endDate = endDate;
  }
}
@ManagedBean(name = "dateRange")
@SessionScoped
public class DateRangeSessionBean extends DateRangeBean {

  private DateFormat formatter = new SimpleDateFormat("MM-dd-yyyy");

  public DateRangeSessionBean() {
      Calendar c1 = Calendar.getInstance();
      setEndDate(c1.getTime());
      Calendar c2 = Calendar.getInstance();
      c2.set(Calendar.YEAR, c1.get(Calendar.YEAR));
      c2.set(Calendar.DAY_OF_YEAR, 1);
      setStartDate(c2.getTime());
  }

  public String getDateRangeString() {
      return String.format("From: %s To: %s%n",
              formatter.format(getStartDate()), formatter.format(getEndDate()));
  }
}
@ManagedBean(name = "dateEditor")
@ViewScoped
public class DateRangeEditorBean extends DateRangeBean {

  @ManagedProperty("#{dateRange}")
  private DateRangeSessionBean dateRangeSessionBean;

  @PostConstruct
  public void init() {
      setEndDate(dateRangeSessionBean.getEndDate());
      setStartDate(dateRangeSessionBean.getStartDate());
  }

  public void saveSelection(ActionEvent ae) {
      dateRangeSessionBean.setStartDate(getStartDate());
      dateRangeSessionBean.setEndDate(getEndDate());
  }

  public void reset(ActionEvent ae) {
      init();
  }


  public DateRangeSessionBean getDateRangeSessionBean() {
      return dateRangeSessionBean;
  }

  public void setDateRangeSessionBean(DateRangeSessionBean dateRangeSessionBean) {
      this.dateRangeSessionBean = dateRangeSessionBean;
  }
}

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

Example Project

Dependencies and Technologies Used :

  • primefaces 6.1 primefaces
  • jsf-api 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • jsf-impl 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • datafactory 0.8: Library to generate data for testing.
  • JDK 1.8
  • Maven 3.3.9

Cancelable Date Range Picker With End Date Restriction Select All Download
  • date-range-picker-cancelable
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp

See Also