001    // Copyright 2004, 2005 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.html;
015    
016    import org.apache.hivemind.ApplicationRuntimeException;
017    import org.apache.tapestry.*;
018    import org.apache.tapestry.dojo.AbstractWidget;
019    import org.apache.tapestry.engine.DirectServiceParameter;
020    import org.apache.tapestry.engine.IEngineService;
021    import org.apache.tapestry.json.JSONObject;
022    
023    import java.util.Collections;
024    import java.util.HashMap;
025    import java.util.List;
026    import java.util.Map;
027    
028    
029    /**
030     * Wraps a dojo InlineEditBox widget. 
031     * 
032     * <p>
033     * Manages a single string value that when hovered over can be edited "inline" in the document
034     * wherever it is referenced. Supports various modes of operation (ie disable/enabled), as well as 
035     * textarea or single line style edits.
036     * </p>
037     *
038     *
039     * <p>
040     * Some of the commonly used widget functions to listen to are:<br/>
041     * <ul>
042     *  <li><b>onSave - </b>When the save button is clicked. Default function listened to when updating
043     *  server side managed value.
044     *  </li>
045     *  <li><b>onUndo - </b>When cancel button is clicked.</li>
046     *  <li><b>onMouseOver - </b>Mouse moved over editable region.</li>
047     *  <li><b>onMouseOut - </b>Mouse moved away from editable region.</li>
048     * </ul>
049     * </p>
050     * 
051     */
052    public abstract class InlineEditBox extends AbstractWidget implements IDirect
053    {
054        /** 
055         * Default single line editing text mode. Use as one of two possible
056         * parameters to the <code>mode</code> parameter.
057         */
058        public static final String TEXT_MODE = "text";
059        
060        /** 
061         * Multi line editing text mode. Use as one of two possible
062         * parameters to the <code>mode</code> parameter.
063         */
064        public static final String TEXT_AREA_MODE = "textarea";
065        
066        public abstract String getValue();
067        public abstract void setValue(String value);
068        
069        public abstract String getMode();
070        
071        public abstract int getMinWidth();
072        
073        public abstract int getMinHeight();
074        
075        public abstract boolean getDoFade();
076        
077        public abstract boolean isDiabled();
078        
079        /**
080         * {@inheritDoc}
081         */
082        public void renderWidget(IMarkupWriter writer, IRequestCycle cycle)
083        {
084            if (!cycle.isRewinding()) {
085                
086                writer.begin(getTemplateTagName()); // use whatever template tag they specified
087                renderInformalParameters(writer, cycle);
088                renderIdAttribute(writer, cycle);
089            }
090            
091            renderBody(writer, cycle);
092            
093            if (!cycle.isRewinding()) {
094                
095                writer.end();
096            }
097            
098            if(!TEXT_MODE.equals(getMode())
099                    && !TEXT_AREA_MODE.equals(getMode())) {
100                throw new ApplicationRuntimeException(WidgetMessages.invalidTextMode(getMode()));
101            }
102            
103            if (cycle.isRewinding()) {
104                return;
105            }
106            
107            JSONObject prop = new JSONObject();
108            prop.put("widgetId", getClientId());
109            prop.put("value", getValue());
110            prop.put("mode", getMode());
111            prop.put("minWidth", getMinWidth());
112            prop.put("minHeight", getMinHeight());
113            prop.put("doFade", getDoFade());
114            
115            Map parms = new HashMap();
116            parms.put("component", this);
117            parms.put("props", prop.toString());
118            
119            PageRenderSupport prs = TapestryUtils.getPageRenderSupport(cycle, this);
120            getScript().execute(this, cycle, prs, parms);
121        }
122        
123        /**
124         * Callback url used by client side widget to update server component.
125         */
126        public String getUpdateUrl()
127        {
128            DirectServiceParameter dsp =
129                new DirectServiceParameter(this);
130            
131            return getEngine().getLink(false, dsp).getURL();
132        }
133        
134        /**
135         * {@inheritDoc}
136         */
137        public List getUpdateComponents()
138        {
139            return Collections.EMPTY_LIST;
140        }
141    
142        /**
143         * {@inheritDoc}
144         */
145        public boolean isAsync()
146        {
147            return true;
148        }
149    
150        /**
151         * {@inheritDoc}
152         */
153        public boolean isJson()
154        {
155            return false;
156        }
157        
158        /**
159         * {@inheritDoc}
160         */
161        public void trigger(IRequestCycle cycle)
162        {
163            String newValue = cycle.getParameter(getClientId());
164            
165            setValue(newValue);
166        }
167        
168        /** Injected. */
169        public abstract IEngineService getEngine();
170        
171        /** Injected. */
172        public abstract IScript getScript();
173    }