Problem with <f: validator> and ajax in JSF

I want to validate two dates on a form before the user takes an action. So I got f: validator inside p: calendar working with ajax, the problem is with the f: attribute. I am passing the start date as a parameter and the validator does not receive this date. However, if you click the action button, the date parameter will be set in the validation. I am using this post as a guide. My xhtml:

    <p:column >
                        <p:calendar  id="txtStartDate" binding="#{txtStartDate}"
                            pattern="dd/MM/yyyy"
                            value="#{myBean.bean.startDate}">                               
                        </p:calendar>
                    </p:column>
                    <p:column>
                        <p:calendar id="txtEndDate"
                            pattern="dd/MM/yyyy"
                            value="#{myBean.bean.endDate}">
                            <f:validator validatorId="validator.dateRangeValidator" />
                            <f:attribute name="fromDate" value="#{txtStartDate.value}" />                                
                            <p:ajax event="dateSelect" execute="@Form" update=":formHeader:messages" />
                        </p:calendar>
                    </p:column>

      

And the validator:

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (value == null || component.getAttributes().get("fromDate") == null) return;

    Date endDate   = (Date) value; 
    Date startDate = (Date) component.getAttributes().get("fromDate");

    if (!endDate.after(startDate)) {
        FacesMessage message = new FacesMessage("End date before the start date.");
        message.setSeverity(FacesMessage.SEVERITY_ERROR);
        addMessageOnSession(FacesMessage.SEVERITY_ERROR, "Invalid dates");
        throw new ValidatorException(message);
    }
}

      

Appreciate any help with this.

+5


source to share


3 answers


Anyway, the quick solution for me was to add listener = "" to the ajax tag, so I'm doing the check on the bean. I don't know if this is the best way to do it, but it solved my problem.



0


source


There are several problems I see here:

execute="@Form"

      



The above is not correct. If you want to complete the whole form, the correct meaning is here @form

.

After fixing this component txtStartDate

should update its binding value and can be set as an attribute for txtEndDate

.

+1


source


If you are using Primefaces there is a problem sending the parameter. They don't support the date.

Your code:

Date startDate = (Date) component.getAttributes().get("fromDate");

      

You should get the date as UIInput and parse it.

final UIInput startDate = (UIInput) component.getAttributes().get("fromDate");
final String dateFromString = (String) String.valueOf(startDate.getValue());
final SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
final Date parsedDateTo = parseDate(parserSDF, dateFromString);

      

To update your form use:

execute="@this" render="yourFormId"

      

Next tip:

You can change f:ajax event="dateSelect"

to f:ajax event="change"

to manually enter the change date. It also works like a date picker too.

0


source







All Articles