使用 <rich:calendar> 的更改事件重新渲染第三个字段

Posted

技术标签:

【中文标题】使用 <rich:calendar> 的更改事件重新渲染第三个字段【英文标题】:Re-rendering 3rd field with change event of <rich:calendar> 【发布时间】:2014-01-04 05:43:08 【问题描述】:

我正在尝试更新持续时间(由 捕获的两个日期的差异。当我将 fireDrillEvacTime 添加到以下堆栈跟踪转储的呈现中时:

    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)

这是我的 xhtml 文件:

                <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="" /> 

这里是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;
    

我对此并不陌生,并且已经搜索了如何计算日期,但是很难弄清楚如何获得一个丰富的日历来执行 ajax 调用,因为其中一个日期被更改为重新渲染 fireEvacTimeTime 而没有必须单击计算按钮。我做错了什么?

【问题讨论】:

【参考方案1】:

Hej Azulitabijou,

我为你写了一个小例子。它正在工作,但您必须根据您的需要对其进行调整。 我省略了所有的模式和评估..

控制器类

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);
    



更新 像这样创建自己的日历组件并将其放在 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>

并像这样使用您的日历组件:

<!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>

我希望这能帮助你继续工作。

【讨论】:

感谢您的帮助,但计算按钮是我想要避免的。我希望 a4j 脚本在任一日期模糊时触发持续时间计算。

以上是关于使用 <rich:calendar> 的更改事件重新渲染第三个字段的主要内容,如果未能解决你的问题,请参考以下文章

<q>、<blockquote> 和 <cite> 的有效使用

如何使用js 删除<ul>下第一个<li>

何时使用 Mono<List<Object>> 以及何时使用 Flux<Object> 用于 RestController 方法

闭包在DOM中的使用

我应该使用 <colgroup> 和 <col>,如果是,为啥以及如何使用?

选项卡的使用