简体   繁体   中英

Two primefaces calendar component validation

I've a form in JSF 2 where I'm using a double field to specify a range of dates. The aim of that is not to let the user to pick a first date which is before the second one. So I want to perform a validation before the form is sent, using p:calendar components. What I do is to tie a validator to the second calendar input in order to access the first component internally and compare dates.

Here it is my xhtml page:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<h:head />
<h:body>
    <h:form id="date_form">
        <p:calendar id="date1input" value="#{dateTestBean.date1}" />
        <p:calendar value="#{dateTestBean.date2}" validator="dateValidator">
            <f:attribute name="date1" value="#{date1input}" />
        </p:calendar>
        <p:commandButton value="Submit" action="#{dateTestBean.submit}"
            ajax="false" />
    </h:form>
</h:body>
</html>

My managed bean:

@ManagedBean
@ViewScoped
public class DateTestBean {

    private Date date1;

    private Date date2;

    public Date getDate1() {
        return date1;
    }

    public void setDate1(Date date1) {
        this.date1 = date1;
    }

    public Date getDate2() {
        return date2;
    }

    public void setDate2(Date date2) {
        this.date2 = date2;
    }

    public void submit() {
        System.out.println("Submited " + date1 + " " + date2);
    }

}

My validator class:

@FacesValidator(value = "dateValidator")
public class DateValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component,
            Object value) throws ValidatorException {
        System.out.println(((UIInput) context.getViewRoot().findComponent(
                "date_form:date1input")).getValue());
        UIInput date = (UIInput) component.getAttributes().get("date1");
        System.out.println(date);
        //Will perform date comparison
    }
}

The output I get here sending 2013-10-10 as first date and 2013-10-12 as second one is:

Thu Oct 10 00:00:00 CEST 2013

null

Submited Thu Oct 10 00:00:00 CEST 2013 Sat Oct 12 00:00:00 CEST 2013

Which suggests f:attribute tag is not working for p:calendar component as it does for other input components . However, I can access the first calendar via view root, but enforces me to know the entire path of the client id of the component I want to validate. Both values are set in the managed bean later with no issues.

A workaround would be to use an ajax call when first date changes in order to place it in the model and send it as date itself in the f:attribute instead of sending the UIInput (I'm already doing it that way).

Isn't there a better way? Perhaps I have to join them in a single component like in this case ?

From your code,

<p:calendar id="date1input" ... />
<p:calendar ...>
    <f:attribute name="date1" value="#{date1input}" />
</p:calendar>

The #{date1input} isn't represented by id="date1input" . As shown on those code examples, it's represented by binding="#{date1input}" .

Fix it accordingly:

<p:calendar binding="#{date1input}" ... />
<p:calendar ...>
    <f:attribute name="date1" value="#{date1input}" />
</p:calendar>

See also:

Another solution is to set values to null at startup, and on the initial state of the components the second calendar is disabled, and set its mindate to the value of the first one.

                            <p:calendar
                                id="startdate"
                                value="#{bean.startdate}">
                                <p:ajax
                                    event="dateSelect"
                                    listener="#{origemBean.listener}"
                                    update="@form" />
                            </p:calendar>                   
                            <p:calendar
                                id="enddate"
                                disabled="#{empty bean.startdate}"
                                value="#{bean.enddate}"
                                mindate="#{bean.startdate}">
                                <p:ajax
                                    event="dateSelect"
                                    listener="#{bean.listener}"
                                    update="@form" />
                            </p:calendar>

On the managed bean, just verify if the startdate is after enddate and treat them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM