将java.util.Date拆分成表示小时和分钟的两个h:inputText字段,使用f:convertDateTime

8
我希望您能在我的页面上设置一个日期字段,就像这样:
|hours| h |minutes|

输入框中分别输入小时和分钟。

该bean包含此日期

import java.util.Date;
...
private Date myDate;
...

页面是

<h:form>
    ...
    <h:inputText id="myDateHours" maxlength="2" value="#{myBean.myDate}"
        <f:convertDateTime pattern="HH" />
    </h:inputText>

    <h:outputText value=" h " />

    <h:inputText id="myDateMinutes" maxlength="2" value="#{myBean.myDate}"
        <f:convertDateTime pattern="mm" />
    </h:inputText>
    ...
</h:form>

但问题在于,当我提交表单时,只有最后一个元素被保存。例如,如果我输入小时和分钟,那么小时会被覆盖,结果是:
| 00 | h | minutes |

我尝试设置

<h:inputText id="myDateHours" value="#{myBean.myDate.hours}></h:inputText>

<h:inputText id="myDateMinutes" value="#{myBean.myDate.minutes}></h:inputText>

但是我遇到了一个问题。
Cannot convert 01/01/70 01:00 of type class java.util.Date to int

我不想用两个整数字段(小时和分钟)来替换我的日期字段... 你有什么好的想法吗?

谢谢

2个回答

14

如果你想使用单个模型值,那么这种情况是不可能的。

然而,这是一个完美的复合组件示例。它允许你将单个模型值绑定到一组密切相关的现有组件,并在后端组件中执行处理/转换,与视图和后端bean完全分离。其中一个示例可以在此文章中找到:具有多个输入字段的复合组件。对于你的特定情况,可以按照以下方式修改此示例:

/resources/components/inputTime.xhtml

<ui:component
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
>
    <cc:interface componentType="inputTime">
        <cc:attribute name="value" type="java.util.Date" shortDescription="The selected time. Defaults to now." />
    </cc:interface>
    <cc:implementation>
        <span id="#{cc.clientId}" style="white-space:nowrap">
            <h:inputText id="hour" binding="#{cc.hour}" maxlength="2" converter="javax.faces.Integer" />h
            <h:inputText id="minute" binding="#{cc.minute}" maxlength="2" converter="javax.faces.Integer" />
        </span>
    </cc:implementation>
</ui:component>

com.example.InputTime

@FacesComponent("inputTime")
public class InputTime extends UIInput implements NamingContainer {

    private UIInput hour;
    private UIInput minute;

    /**
     * As required by <cc:interface>.
     */
    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }

    /**
     * Set initial hour and minute based on model.
     */
    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        Calendar calendar = Calendar.getInstance();
        Date date = (Date) getValue();

        if (date != null) {
            calendar.setTime(date);
        }

        hour.setValue(calendar.get(Calendar.HOUR_OF_DAY));
        minute.setValue(calendar.get(Calendar.MINUTE));
        super.encodeBegin(context);
    }

    /**
     * Returns the submitted value in HH-mm format.
     */
    @Override
    public Object getSubmittedValue() {
        return hour.getSubmittedValue() + "-" + minute.getSubmittedValue();
    }

    /**
     * Converts the submitted value to concrete {@link Date} instance.
     */
    @Override
    protected Object getConvertedValue(FacesContext context, Object submittedValue) {
        try {
            return new SimpleDateFormat("HH-mm").parse((String) submittedValue);
        }
        catch (ParseException e) {
            throw new ConverterException(e);
        }
    }

    public UIInput getHour() {
        return hour;
    }

    public void setHour(UIInput hour) {
        this.hour = hour;
    }

    public UIInput getMinute() {
        return minute;
    }

    public void setMinute(UIInput minute) {
        this.minute = minute;
    }

}

使用方法:

<html ... xmlns:my="http://java.sun.com/jsf/composite/components">
...
<my:inputTime value="#{bean.date}" />

参见:


抛出带有特定“FacesMessage”的“ConverterException”。注意:您无法针对特定输入进行操作,因为它毕竟是单个组件,因此两个输入都被视为无效。 - BalusC
酷!另一个问题是,是否可以在输入(组件内/外)上使用模糊的 Ajax 事件来渲染 h 消息? - Loric
似乎是完美的解决方案,但找不到标记... “未为名称behaviorHolder定义标记”。 - Loric
抱歉,我又搞混了,应该是 <cc:clientBehavior>:http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/composite/clientBehavior.html - BalusC
非常感谢,现在一切都运行正常了 ;) 非常有帮助。 - Loric
显示剩余4条评论

2

你需要在bean中编写两个独立的setter方法,然后在服务器端进行合并操作。

<h:inputText id="myDateHours" value="#{myBean.hours}></h:inputText>
<h:inputText id="myDateMinutes" value="#{myBean.minutes}></h:inputText>

两个字段都需要获取日期值,然后您可以使用JAVA日历设置两个字段,在表单调用的操作中进行操作。

Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(0);
calendar.set(Calendar.HOUR, getHours().getHours());
calendar.set(Calendar.MINUTE, getMinutes().getMinutes());

如有需要,请注意时区。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接