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 }