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 org.apache.tapestry.IMarkupWriter;
017    import org.apache.tapestry.IRequestCycle;
018    import org.apache.tapestry.IScript;
019    import org.apache.tapestry.TapestryUtils;
020    import org.apache.tapestry.form.TranslatedField;
021    import org.apache.tapestry.form.TranslatedFieldSupport;
022    import org.apache.tapestry.form.ValidatableFieldSupport;
023    import org.apache.tapestry.form.translator.DateTranslator;
024    import org.apache.tapestry.json.JSONObject;
025    import org.apache.tapestry.valid.ValidatorException;
026    
027    import java.util.HashMap;
028    import java.util.Map;
029    
030    /**
031     * Implementation of the dojo DropdownDatePicker widget as a tapestry
032     * component. Wraps a form input field with a date picker icon next to it
033     * that when clicked on reveals a calendar to choose date values from. 
034     * 
035     * @author jkuhnert
036     */
037    public abstract class DropdownDatePicker extends AbstractFormWidget implements TranslatedField
038    {
039        
040        /** parameter. */
041        public abstract Object getValue();
042        
043        public abstract void setValue(Object value);
044        
045        public abstract boolean isDisabled();
046        
047        /** Alt html text for the date icon, what is displayed when mouse hovers over icon. */
048        public abstract String getIconAlt();
049    
050        public abstract int getDisplayWeeks();
051    
052        public abstract boolean isAdjustWeeks();
053    
054        public abstract Object getStartDate();
055    
056        public abstract Object getEndDate();
057    
058        public abstract int getWeekStartsOn();
059    
060        public abstract boolean isStaticDisplay();
061        
062        /**
063         * {@inheritDoc}
064         */
065        protected void renderFormWidget(IMarkupWriter writer, IRequestCycle cycle)
066        {
067            // dojo dates are in POSIX style formats so we format the value manually
068            DateTranslator translator = (DateTranslator) getTranslator();
069            
070            renderDelegatePrefix(writer, cycle);
071            
072            // the html output doesn't matter very much as dojo
073            // will create an inline input field for us anyways, but we do need
074            // a node to reference
075            writer.begin(getTemplateTagName());
076            renderIdAttribute(writer, cycle);
077            
078            renderDelegateAttributes(writer, cycle);
079            
080            getValidatableFieldSupport().renderContributions(this, writer, cycle);
081            
082            renderInformalParameters(writer, cycle);
083            
084            writer.print(" ");
085            
086            writer.end();
087            renderDelegateSuffix(writer, cycle);
088            
089            // now create widget parms
090            JSONObject json = new JSONObject();
091            json.put("inputId", getClientId());
092            json.put("inputName", getName());
093            json.put("iconAlt", getIconAlt());
094            json.put("displayFormat", translator.getPattern(getPage().getLocale()));
095            json.put("saveFormat", translator.getPattern(getPage().getLocale()));
096            
097            if (getValue() != null) {
098                json.put("value", translator.formatRfc3339(getValue()));
099            }
100            
101            json.put("disabled", isDisabled());
102            if (getDisplayWeeks() > 0)
103                json.put("displayWeeks", getDisplayWeeks());
104            if (isAdjustWeeks())
105                json.put("adjustWeeks", isAdjustWeeks());
106            if (getStartDate() != null)
107                json.put("startDate", translator.formatRfc3339(getStartDate()));
108            if (getEndDate() != null)
109                json.put("endDate", translator.formatRfc3339(getEndDate()));
110            if (getWeekStartsOn() > -1)
111                json.put("weekStartsOn", getWeekStartsOn());
112            if (isStaticDisplay())
113                json.put("staticDisplay", isStaticDisplay());
114    
115            Map parms = new HashMap();
116            parms.put("clientId", getClientId());
117            parms.put("props", json.toString());
118            parms.put("widget", this);
119            
120            getScript().execute(this, cycle, TapestryUtils.getPageRenderSupport(cycle, this), parms);
121        }
122        
123        /**
124         * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
125         */
126        protected void rewindFormWidget(IMarkupWriter writer, IRequestCycle cycle)
127        {
128            String value = cycle.getParameter(getName());
129            
130            try
131            {
132                Object translated = getTranslatedFieldSupport().parse(this, value);
133                
134                getValidatableFieldSupport().validate(this, writer, cycle, translated);
135                
136                setValue(translated);
137            }
138            catch (ValidatorException e)
139            {
140                getForm().getDelegate().record(e);
141            }
142        }
143        
144        /**
145         * @see org.apache.tapestry.form.AbstractFormComponent#isRequired()
146         */
147        public boolean isRequired()
148        {
149            return getValidatableFieldSupport().isRequired(this);
150        }
151        
152        /** Injected. */
153        public abstract IScript getScript();
154        
155        /** Injected. */
156        public abstract TranslatedFieldSupport getTranslatedFieldSupport();
157        
158        /** Injected. */
159        public abstract ValidatableFieldSupport getValidatableFieldSupport();
160        
161    }