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 }