2

this is my xhtml code. I need to validate the input field of arrival time after losing focus and not after using the save button. How can I do that?

 <h:outputLabel for="arrivalTime" value="Arrived at: "/>
            <p:outputLabel styleClass="wrapper">
                <p:outputLabel styleClass="centeredButton">
                    <pe:timePicker id="arrivalTime" value="# 
   {timesheetMB.inputTimesheet.arrivalTime}" converterMessage="Invalid time 
    format! Time format should be HH:mm!" mode="popup" intervalMinutes="5" 
    widgetVar="arrivalTimeWidget"  minHour="7" maxHour="13" > 
                        <f:convertDateTime pattern="HH:mm" />
                        <f:validator validatorId="arrivalTimeValidator"/>
                        <p:ajax event="change" listener="# 
   {timesheetMB.onTimeChange}" update="saveButton totalHours workedHours 
    breakTime statusIndicator" />
                    </pe:timePicker>
                </p:outputLabel>
                <p:commandButton id="arrivalNowButton" 
    styleClass="centeredButton" value="Now" actionListener="# 
   {timesheetMB.onArrivalTimeNowButton}" update="arrivalTime saveButton 
    totalHours workedHours breakTime statusIndicator"/>
                <div class="clearfix"></div>
            </p:outputLabel>

And this is how my validator looks like:

import java.util.Date;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.hibernate.type.descriptor.java.DataHelper;

import com.infobest.vms.utils.DateHelper;

@FacesValidator("arrivalTimeValidator")

public class ArrivalTimeValidator implements Validator{
    private boolean saveButton = true;
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        Date hours = (Date) value;

        DateHelper hour= new DateHelper();
        Date minHour= new Date();
        Date maxHour= new Date();

        minHour.setHours(7); minHour.setMinutes(0);
        maxHour.setHours(13); maxHour.setMinutes(0);

        if( ((hour.getTimeOfDay(hours)).compareTo(hour.getTimeOfDay(minHour))) >= 0 && ((hour.getTimeOfDay(hours)).compareTo(hour.getTimeOfDay(maxHour))) <= 0)
        {
            saveButton = false;
            return;
        }
        else
        {   
            saveButton = true;
            throw new ValidatorException(
                new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Arrival time Error",
                    "Please choose an hour between 7 and 12!"));
        }
    }

    public boolean getSaveButtonState() {
        return saveButton;
    }
}

I would like to send that saveButtonState to the disabled tag in xhtml button, because I observed that my validator actually validate after losing focus on the input field.

2 Answers2

1

Put your time validator in a close event and put a flag to disable button.

So, in your timepicker you should put something like:

<p:ajax event="close" listener="#{timesheetMB.validateTime}" update="growl"/>  

In your button something like:

<p:commandButton id="arrivalNowButton" disabled="#{!(timesheetMB.enabledSave)}"
    styleClass="centeredButton" value="Now" actionListener="# 
   {timesheetMB.onArrivalTimeNowButton}" update="arrivalTime saveButton 
    totalHours workedHours breakTime statusIndicator"/>

In your bean:

boolean enabledSave = false;
void validateTime(){
  // validate time
  enabledSave = validate(timeString);
}

It should work. If the button not disables, you could put a beforeShow event to show the user to input a valid date.

Hope this helps.

Rafael Palomino
  • 318
  • 2
  • 14
-1

With what you have in your xhtml code it should already be working. See the following link for more details: Validate ajax updates.