boolean rewinding = form.isRewinding();
String name = form.getElementId(this);
IMarkupWriter wrappedWriter;
if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
throw new ApplicationRuntimeException(
Tapestry.getMessage("LinkSubmit.may-not-nest"),
this,
null,
null);
cycle.setAttribute(ATTRIBUTE_NAME, this);
boolean disabled = isDisabled();
if (!disabled)
{
if (!rewinding)
{
Body body = Body.get(cycle);
if (body == null)
throw new ApplicationRuntimeException(
Tapestry.format("must-be-contained-by-body", "LinkSubmit"),
this,
null,
null);
// make sure the submit function is on the page (once)
if (cycle.getAttribute(ATTRIBUTE_FUNCTION_NAME) == null)
{
body.addBodyScript(
"function submitLink(form, elementId) { form._linkSubmit.value = elementId; if (form.onsubmit == null || form.onsubmit()) form.submit(); }");
cycle.setAttribute(ATTRIBUTE_FUNCTION_NAME, this);
}
// one hidden field per form:
String formHiddenFieldAttributeName = ATTRIBUTE_FUNCTION_NAME + formName;
if (cycle.getAttribute(formHiddenFieldAttributeName) == null)
{
body.addInitializationScript("document." + formName + "._linkSubmit.value = null;");
writer.beginEmpty("input");
writer.attribute("type", "hidden");
writer.attribute("name", "_linkSubmit");
cycle.setAttribute(formHiddenFieldAttributeName, this);
}
}
else
{
// How to know which Submit link was actually
// clicked? When submitted, it sets its elementId into a hidden field
String value = cycle.getRequestContext().getParameter("_linkSubmit");
// If the value isn't the elementId of this component, then this link wasn't
// selected.
if (value != null && value.equals(name))
{
IBinding selectedBinding = getSelectedBinding();
if (selectedBinding != null)
selectedBinding.setObject(getTag());
IActionListener listener = getListener();
if (listener != null)
listener.actionTriggered(this, cycle);
}
}
writer.begin("a");
writer.attribute(
"href",
"javascript:submitLink(document." + formName + ",\"" + name + "\");");
// 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;
renderBody(wrappedWriter, cycle);
if (!disabled)
{
// Generate additional attributes from informal parameters.
renderInformalParameters(writer, cycle);
// Dump in HTML provided by wrapped components
wrappedWriter.close();
// Close the <a> tag
writer.end();
}