001    // Copyright Jun 10, 2006 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    package org.apache.tapestry.dojo.form;
015    
016    import java.text.DateFormat;
017    import java.util.Date;
018    import java.util.HashMap;
019    import java.util.Map;
020    
021    import org.apache.tapestry.IMarkupWriter;
022    import org.apache.tapestry.IRequestCycle;
023    import org.apache.tapestry.IScript;
024    import org.apache.tapestry.TapestryUtils;
025    import org.apache.tapestry.form.TranslatedField;
026    import org.apache.tapestry.form.TranslatedFieldSupport;
027    import org.apache.tapestry.form.ValidatableFieldSupport;
028    import org.apache.tapestry.form.translator.DateTranslator;
029    import org.apache.tapestry.json.JSONObject;
030    import org.apache.tapestry.util.Strftime;
031    import org.apache.tapestry.valid.ValidatorException;
032    
033    /**
034     * Implementation of the dojo DropdownTimePicker widget as a tapestry
035     * component. Wraps a form input field with a date picker icon next to it
036     * that when clicked on reveals a pane to choose time values from. 
037     * 
038     * @author jkuhnert
039     */
040    public abstract class DropdownTimePicker extends AbstractFormWidget
041        implements TranslatedField
042    {
043        
044        /** parameter. */
045        public abstract Date getValue();
046        
047        public abstract void setValue(Date value);
048        
049        public abstract boolean isDisabled();
050        
051        /** Alt html text for the date icon, what is displayed when mouse hovers over icon. */
052        public abstract String getIconAlt();
053        
054        /**
055         * {@inheritDoc}
056         */
057        protected void renderFormWidget(IMarkupWriter writer, IRequestCycle cycle)
058        {
059            // dojo dates are in POSIX style formats so we format the value manually
060            DateTranslator translator = (DateTranslator) getTranslator();
061            
062            renderDelegatePrefix(writer, cycle);
063            
064            // the html output doesn't matter very much as dojo
065            // will create an inline input field for us anyways, but we do need
066            // a node to reference
067            writer.begin("div");
068            renderIdAttribute(writer, cycle);
069            
070            renderDelegateAttributes(writer, cycle);
071            
072            getValidatableFieldSupport().renderContributions(this, writer, cycle);
073            
074            renderInformalParameters(writer, cycle);
075            
076            writer.end();
077            renderDelegateSuffix(writer, cycle);
078            
079            // now create widget parms
080            JSONObject json = new JSONObject();
081            json.put("inputId", getClientId());
082            json.put("inputName", getName());
083            json.put("iconAlt", getIconAlt());
084            json.put("timeFormat", Strftime.convertToPosixFormat(translator.getPattern()));
085            
086            if (getValue() != null) {
087                json.put("time", DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, 
088                        getPage().getLocale()).format(getValue()));
089            }
090            
091            Map parms = new HashMap();
092            parms.put("clientId", getClientId());
093            parms.put("props", json.toString());
094            
095            getScript().execute(this, cycle, TapestryUtils.getPageRenderSupport(cycle, this), parms);
096        }
097        
098        /**
099         * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
100         */
101        protected void rewindFormWidget(IMarkupWriter writer, IRequestCycle cycle)
102        {
103            String value = cycle.getParameter(getName());
104            
105            try
106            {
107                Date date = (Date) getTranslatedFieldSupport().parse(this, value);
108    
109                getValidatableFieldSupport().validate(this, writer, cycle, date);
110    
111                setValue(date);
112            }
113            catch (ValidatorException e)
114            {
115                getForm().getDelegate().record(e);
116            }
117        }
118        
119        /**
120         * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
121         */
122        public boolean isRequired()
123        {
124            return getValidatableFieldSupport().isRequired(this);
125        }
126        
127        /** Injected. */
128        public abstract IScript getScript();
129        
130        /** Injected. */
131        public abstract TranslatedFieldSupport getTranslatedFieldSupport();
132        
133        /** Injected. */
134        public abstract ValidatableFieldSupport getValidatableFieldSupport();
135        
136    }