Re-rendering 3rd field with change event of <rich:calendar>

534 views Asked by At

I am trying to update a duration (difference of two dates being captured by . When I add the fireDrillEvacTime to the rendering of the following stack trace dump:

    JBWEB000309: type JBWEB000066: Exception report

JBWEB000068: message <f:ajax> contains an unknown id 'fireDrillStartTime,fireDrillEvacTime' - cannot locate it in the context of the component fireDrillStartTime

JBWEB000069: description JBWEB000145: The server encountered an internal error that prevented it from fulfilling this request.

JBWEB000070: exception

javax.servlet.ServletException: <f:ajax> contains an unknown id 'fireDrillStartTime,fireDrillEvacTime' - cannot locate it in the context of the component fireDrillStartTime
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
    org.monarchnc.filter.LoginFilter.doFilter(LoginFilter.java:41)
JBWEB000071: root cause

javax.faces.FacesException: <f:ajax> contains an unknown id 'fireDrillStartTime,fireDrillEvacTime' - cannot locate it in the context of the component fireDrillStartTime
    com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getResolvedId(AjaxBehaviorRenderer.java:289)
    com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.appendIds(AjaxBehaviorRenderer.java:276)
    com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.buildAjaxCommand(AjaxBehaviorRenderer.java:218)
    com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getScript(AjaxBehaviorRenderer.java:88)
    javax.faces.component.behavior.ClientBehaviorBase.getScript(ClientBehaviorBase.java:103)

Here is my xhtml file:

                <h:outputLabel for="fireDrillStartTime" value="Fire Drill Start Time:"/>            
                <rich:calendar value="#{fireDrillBean.fireDrill.fireDrillStartTime}" id="fireDrillStartTime"
                        popup="true"  datePattern="yyyy-MM-dd HH:mm:ss"
                        enableManualInput="true" required="true"
                        showApplyButton="true" cellWidth="24px" cellHeight="22px" style="width:200px">
                         <f:ajax event="change" execute="@this"  bypassUpdates="#{true}"  render="fireDrillStartTime,fireDrillEndTime"/>         
                </rich:calendar>
                <h:outputText value="*"/>   

                <h:outputLabel for="fireDrillEndTime" value="Fire Drill End Time:"/>                
                <rich:calendar value="#{fireDrillBean.fireDrill.fireDrillEndTime}" id="fireDrillEndTime"
                        popup="true"  datePattern="yyyy-MM-dd HH:mm:ss"
                        enableManualInput="true" required="true"
                        showApplyButton="true" cellWidth="24px" cellHeight="22px" style="width:200px">
                        <f:ajax event="change" execute="@this"  bypassUpdates="#{true}"  render="fireDrillEndTime,fireDrillEndTime"/>                                                                    
                </rich:calendar>  
                <h:outputText value="*"/>   

                <h:outputLabel for="fireDrillEvacTime" value="Fire Drill Evac Time:"/>
                <h:outputText id="fireDrillEvacTime" value="#{fireDrillBean.evacDuration}" style="width: 175px;"/>                  
                <h:outputText value="" /> 

Here is the setter/getter:

public Long getEvacDuration() {
        return evacDuration;
    }

    public void setEvacDuration(long evacDuration) throws Exception{
        try{
            if (this.fireDrill.getFireDrillStartTime() != null && this.fireDrill.getFireDrillEndTime() != null){
                evacDuration= fireDrill.getFireDrillStartTime().getTime() - fireDrill.getFireDrillEndTime().getTime();
                evacDuration = timeUnit.convert(evacDuration,TimeUnit.SECONDS);
                this.fireDrill.setEvacuationDuration(evacDuration);
            }
        }
        catch (Exception up) {
            throw up;
        }
        this.evacDuration=evacDuration;
    }

I am new to this, and have searched on how to calculate the date, but having a hard time with figuring how to get a rich:calendar to execute an ajax call when either of the dates are changed to rerender the fireEvacTimeTime without having to click a calculation button. What am I doing wrong?

1

There are 1 answers

1
Patrick On BEST ANSWER

Hej Azulitabijou,

i wrote a small example for you. It is working, but you'll have to adapt it to your needs. I left out all the patterns and evaluations..

The Controller Class

package de.professional_webworkx.so.controller;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.enterprise.inject.Model;
import javax.enterprise.inject.Produces;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;

@Model
public class FireCalendarController {

    @Inject
    FacesContext context;

    private Date startDate;
    private Date endDate;
    private long duration;

    @Produces
    @Named
    public Date getStartDate() {
        Logger.getLogger(getClass().getSimpleName()).log(Level.INFO, "MSG");
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    @Produces
    @Named
    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    @Produces
    @Named
    public long getDuration() {
        return duration;
    }

    public void setDuration(long duration) {
        this.duration = duration;
    }

    public void doSomething() {
        duration = endDate.getTime()-startDate.getTime();
        Logger.getLogger(getClass().getSimpleName()).log(Level.INFO, "Start was " + startDate);
    }


}

UPDATE create your own calendar component like this and place it under webapp/resources/emcomp/calendar.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"    
    xmlns:rich="http://richfaces.org/rich"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <!-- INTERFACE -->
    <composite:interface>
        <composite:attribute name="date" />

        <composite:clientBehavior name="date_change" event="change" targets="#{cc.id}"/>
    </composite:interface>

    <!-- IMPLEMENTATION -->
    <composite:implementation>
        <h:panelGrid columns="2">
            <h:outputText value="Startdatum" />
            <rich:calendar id="#{cc.id}" value="#{cc.attrs.date}"  datePattern="dd.MM.yyyy"></rich:calendar>
        </h:panelGrid>  
    </composite:implementation>  

</html>

And use your calendar-component like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:em="http://java.sun.com/jsf/composite/emcomp"> 

<h:head></h:head> 
<h:body>


    <rich:panel>
        <f:facet name="header">
        fireDrill at SO ;9
        </f:facet>
        <h:form>
        <h:panelGrid columns="2">
        <h:outputText value="Startdate:" />

        <!-- 
            <rich:calendar value="#{fireCalendarController.startDate}"></rich:calendar>
         -->
        <em:calendar id="start" date="#{fireCalendarController.startDate}">

        </em:calendar>
        <em:calendar id="end" date="#{fireCalendarController.endDate}">
            <a4j:ajax event="date_change" execute="start,end" render="duration"/>
        </em:calendar>

        <h:outputText value="Duration" />
        <h:outputText id="duration" value="#{fireCalendarController.duration}" />
        </h:panelGrid>
        </h:form>
    </rich:panel>
</h:body> 
</html>

I hope this will help you to go on working.