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    
015    package org.apache.tapestry.form;
016    
017    import org.apache.hivemind.ApplicationRuntimeException;
018    import org.apache.hivemind.util.Defense;
019    import org.apache.tapestry.IComponent;
020    import org.apache.tapestry.IForm;
021    import org.apache.tapestry.IMarkupWriter;
022    import org.apache.tapestry.IRequestCycle;
023    import org.apache.tapestry.engine.DirectServiceParameter;
024    import org.apache.tapestry.json.JSONLiteral;
025    import org.apache.tapestry.json.JSONObject;
026    
027    import java.util.List;
028    
029    /**
030     * Implements a component that submits its enclosing form via a JavaScript link. [ <a
031     * href="../../../../../ComponentReference/LinkSubmit.html">Component Reference </a>]
032     *
033     * @author Richard Lewis-Shell
034     */
035    
036    public abstract class LinkSubmit extends AbstractSubmit
037    {
038    
039        /**
040         * The name of an {@link org.apache.tapestry.IRequestCycle} attribute in which the current
041         * submit link is stored. LinkSubmits do not nest.
042         */
043    
044        public static final String ATTRIBUTE_NAME = "org.apache.tapestry.form.LinkSubmit";
045        
046        /**
047         * Checks the submit name ({@link FormConstants#SUBMIT_NAME_PARAMETER}) to see if it matches
048         * this LinkSubmit's assigned element name.
049         */
050        protected boolean isClicked(IRequestCycle cycle, String name)
051        {
052            String value = cycle.getParameter(FormConstants.SUBMIT_NAME_PARAMETER);
053    
054            return name.equals(value);
055        }
056    
057        /**
058         * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter,
059         *      org.apache.tapestry.IRequestCycle)
060         */
061        protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
062        {
063            boolean disabled = isDisabled();
064    
065            IForm form = getForm();
066            String type = getSubmitType();
067    
068            Defense.notNull(type, "submitType");
069    
070            List update = getUpdateComponents();
071            boolean isAsync = isAsync() || update != null && update.size() > 0;
072    
073            if (!disabled)
074            {
075                writer.begin("a");
076    
077                String js = "tapestry.form." + type + "('" + form.getClientId() + "', '" + getName() + "'";
078                
079                if (isAsync)
080                {
081                    JSONObject json = new JSONObject();
082                    json.put(new JSONLiteral("async"), Boolean.TRUE);
083                    json.put(new JSONLiteral("json"), isJson());
084    
085                    DirectServiceParameter dsp = new DirectServiceParameter(form, null, this);
086                    json.put(new JSONLiteral("url"), new JSONLiteral("this.href"));
087    
088                    writer.attribute("href", getDirectService().getLink(true, dsp).getURL());
089                    writer.attribute("onClick", js + "," + json.toString() + "); return false;");                        
090                }
091                else
092                {
093                    writer.attribute("href", "javascript:" + js + ");");
094                }
095    
096                renderIdAttribute(writer, cycle);
097                renderInformalParameters(writer, cycle);
098            }
099    
100            renderBody(writer, cycle);
101    
102            if (!disabled)
103                writer.end();
104        }
105    
106        
107    
108        /**
109         * @see org.apache.tapestry.AbstractComponent#prepareForRender(org.apache.tapestry.IRequestCycle)
110         */
111        protected void prepareForRender(IRequestCycle cycle)
112        {
113            IComponent outer = (IComponent) cycle.getAttribute(ATTRIBUTE_NAME);
114    
115            if (outer != null)
116                throw new ApplicationRuntimeException(FormMessages.linkSubmitMayNotNest(this, outer),
117                                                      this, getLocation(), null);
118    
119            cycle.setAttribute(ATTRIBUTE_NAME, this);
120        }
121    
122        /**
123         * @see org.apache.tapestry.AbstractComponent#cleanupAfterRender(org.apache.tapestry.IRequestCycle)
124         */
125        protected void cleanupAfterRender(IRequestCycle cycle)
126        {
127            cycle.removeAttribute(ATTRIBUTE_NAME);
128        }
129    
130        /**
131         * Links can not take focus, ever.
132         */
133        protected boolean getCanTakeFocus()
134        {
135            return false;
136        }
137    
138        /**
139         * Returns true; the LinkSubmit's body should render during a rewind, even if the component is
140         * itself disabled.
141         */
142        protected boolean getRenderBodyOnRewind()
143        {
144            return true;
145        }
146    }