org.apache.tapestry.contrib.link.FormLinkRenderer Maven / Gradle / Ivy
// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.contrib.link;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.*;
import org.apache.tapestry.components.ILinkComponent;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.link.DefaultLinkRenderer;
import org.apache.tapestry.link.ILinkRenderer;
/**
* A link renderer that ensures that the generated link uses POST instead of GET
* request and is therefore no longer limited in size.
*
* Theoretically, browsers should support very long URLs, but in practice they
* often start behaving strangely if the URLs are more than 256 characters. This
* renderer uses JavaScript to generate forms containing the requested link
* parameters and then "post" them when the link is selected. As a result, the
* data is sent to the server using a POST request with a very short URL and
* there is no longer a limitation in the size of the parameters.
*
* In short, simply add the following parameter to your DirectLink
,
* ExternalLink
, or other such link components:
*
*
* renderer = "ognl: @org.apache.tapestry.contrib.link.FormLinkRenderer@RENDERER"
*
*
* and they will automatically start using POST rather than GET requests. Their
* parameters will no longer be limited in size.
* @author mb
* @since 4.0
*/
public class FormLinkRenderer extends DefaultLinkRenderer
{
/**
* A public singleton instance of the FormLinkRenderer
.
*
* Since the FormLinkRenderer
is stateless, this instance can
* serve all links within your application without interference.
*/
public static final ILinkRenderer RENDERER = new FormLinkRenderer();
public void renderLink(IMarkupWriter writer, IRequestCycle cycle,
ILinkComponent linkComponent)
{
IMarkupWriter wrappedWriter = null;
if (cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME) != null)
throw new ApplicationRuntimeException(Tapestry.getMessage("AbstractLinkComponent.no-nesting"),
linkComponent, null, null);
cycle.setAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME,
linkComponent);
String formName = cycle.getUniqueId("LinkForm");
boolean hasBody = getHasBody();
boolean disabled = linkComponent.isDisabled();
if (!disabled && !cycle.isRewinding())
{
ILink l = linkComponent.getLink(cycle);
String anchor = linkComponent.getAnchor();
PageRenderSupport prs = TapestryUtils.getPageRenderSupport(cycle, linkComponent);
String function = generateFormFunction(formName, l, anchor);
prs.addBodyScript(linkComponent, function);
if (hasBody)
writer.begin(getElement());
else
writer.beginEmpty(getElement());
writer.attribute(getUrlAttribute(), "javascript: document."
+ formName + ".submit();");
beforeBodyRender(writer, cycle, linkComponent);
// Allow the wrapped components a chance to render.
// Along the way, they may interact with this component
// and cause the name variable to get set.
wrappedWriter = writer.getNestedWriter();
}
else
wrappedWriter = writer;
if (hasBody)
linkComponent.renderBody(wrappedWriter, cycle);
if (!disabled && !cycle.isRewinding())
{
afterBodyRender(writer, cycle, linkComponent);
linkComponent.renderAdditionalAttributes(writer, cycle);
if (hasBody)
{
wrappedWriter.close();
// Close the tag
writer.end();
}
else writer.closeTag();
}
cycle.removeAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
}
private String generateFormFunction(String formName, ILink link,
String anchor)
{
String[] parameterNames = link.getParameterNames();
StringBuffer buf = new StringBuffer();
buf.append("function prepare" + formName + "() {\n");
buf.append(" var html = \"\";\n");
buf.append(" html += \"\";\n");
String url = link.getURL(anchor, false);
buf.append(" html += \"
© 2015 - 2024 Weber Informatics LLC | Privacy Policy