Split java.util.Date over two h:inputText fields representing hour and minute with f:convertDateTime

前端 未结 2 445
清酒与你
清酒与你 2020-11-27 21:22

I would like to set up a Date field in my page like this

|hours| h |minutes|

where hours and minutes are in separated inputText.

Th

相关标签:
2条回答
  • 2020-11-27 21:43

    This particular case is not possible if you want to use a single model value.

    This is however a perfect candidate for a composite component. It allows you to bind a single model value to a group of closely related existing components and perform the processing/conversion in the backing component, fully decoupled from the view and backing bean. One of the examples can be found in this article: composite component with multiple input fields. This example can in for your specific case be altered as follows:

    /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;
        }
    
    }
    

    Usage:

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

    See also:

    • When to use <ui:include>, tag files, composite components and/or custom components?
    0 讨论(0)
  • 2020-11-27 21:46

    You need two separate setter methods in the bean, and then do the merge in the server.

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

    Both must get date values, so then you can operate with a JAVA Calendar setting both fields, in the action invoked by your form.

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

    Be aware of time zones if required.

    0 讨论(0)
提交回复
热议问题