/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. * * $Header:$ */ package org.apache.beehive.netui.tags.html; import org.apache.beehive.netui.tags.ByRef; import org.apache.beehive.netui.tags.rendering.AbstractHtmlState; import org.apache.beehive.netui.tags.rendering.TagRenderingBase; import org.apache.beehive.netui.tags.rendering.WriteRenderAppender; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; /** *
* Generates a URL-encoded hyperlink to a specified URI. * Also adds support for URL re-writing and JavaScript-based form submission. * An anchor must have one of the following attributes to correctly create the hyperlink: *
* Generates an anchor that can link to another document or invoke an action method in the Controller file. * The <netui:anchor> tag also supports JavaScript-based form submission and URL re-writing. *
* An anchor must have one of the following attributes to correctly create the hyperlink: *
** **
*- *
action
- the action method invoked by clicking the hyperlink- *
href
- the URL to go to- *
linkName
- an internal place in the page to move to- *
clientAction
- the action to run on the client- *
tagId
- the ID of the tag- *
formSubmit
- indicates whether or not the enclosing Form should be submitted
* The Anchor tag can accept NetUI parameter tags that implement the * {@link IUrlParams} interface. When parameter tags are contained inside of * the Anchor tag, they add URL parameters onto the rendered href. For * example: *
* <netui:anchor href="foo.jsp" value="Go To Foo"> * <netui:parameter name="paramKey" value="paramValue"/> * </netui:anchor> ** will render: *
* <a href="foo.jsp?paramKey=paramValue">Go To Foo</a> ** * @example Submitting Form Data *
In this sample, clicking on this anchor submits the form data and invokes the method
* submitForm
.
*
* <netui:form action="formSubmit"> * Firstname: * <netui:textBox dataSource="actionForm.firstname"/> * Lastname: * <netui:textBox dataSource="actionForm.lastname"/> * <netui:anchor formSubmit="true">Submit</netui:anchor> * </netui:form>*
If the formSubmit
attribute is set to true
and no
* onClick
attribute is set, the following JavaScript function will be written to the HTML page.
* This JavaScript function will be referenced by the onclick
attribute of the generated anchor tag.
* function anchor_submit_form(netuiName, newAction) * { * for (var i=0; i<document.forms.length; i++) { * if (document.forms[i].id == netuiName) { * document.forms[i].method = "POST"; * document.forms[i].action = newAction; * document.forms[i].submit(); * } * } * }*
The JavaScript function will be invoked by the generated HTML anchor tag as follows: *
* <a href="/WebApp/tagSamples/anchor/formSubmit.do" * onClick='anchor_submit_form("Netui_Form_0","/WebApp/tagSamples/anchor/formSubmit.do");return false;'>Submit</a>*
* Custom JavaScript Functions *
*It is possible to write a custom onClick
JavaScript event handler that would
* do additional work, for example form validation, and still POST the form correctly. To
* accomplish this, add the custom JavaScript method to the page:
*
* function SubmitFromAnchor() * { * // implement custom logic here * * for(var i=0; i<document.forms.length; i++) * { * // submit to the action /aWebapp/formPost.do * if (document.forms[i].action == "/aWebapp/formPost.do") * { * document.forms[i].method="POST"; * document.forms[i].action="/aWebapp/formPost.do"; * document.forms[i].submit(); * } * } * }* Then reference the JavaScript method from the <netui:anchor> tag: *
* <netui:anchor formSubmit="true" onClick="SubmitFromAnchor(); return false;">Submit</netui:anchor>* @netui:tag name="anchor" description="Generates a URL-encoded hyperlink to a specified URI." * @see Attribute * @see java.lang.String */ public class Anchor extends AnchorBase { private String _text; // The body content of this tag (if any). private String _value; /** * Returns the name of the Tag. */ public String getTagName() { return "Anchor"; } /** * This method will return the state associated with the tag. This is used by this * base class to access the individual state objects created by the tags. * @return a subclass of the
AbstractHtmlState
class.
*/
public AbstractHtmlState getState()
{
return _state;
}
/**
* Sets the onClick javascript event.
* @param onclick the onClick event.
* @jsptagref.attributedescription The onClick JavaScript event.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_onClick
* @netui:attribute required="false" rtexprvalue="true"
* description="The onClick JavaScript event."
*/
public void setOnClick(String onclick)
{
_state.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, ONCLICK, setNonEmptyValueAttribute(onclick));
// Jira 299
//_state.onClick = setNonEmptyValueAttribute(onclick);
}
/**
* Set a client action to run on the client. When set on an anchor, a NetUI JavaScript action
* will be run. This attribute may not be set if href
or action
is set.
* @param action an action to run on the client.
* @jsptagref.attributedescription The action (NetUI JavaScript) to run on the client.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_clientAction
* @netui:attribute required="false" rtexprvalue="true" description="The client action."
* description="The action (NetUI JavaScript) to run on the client."
*/
public void setClientAction(String action)
throws JspException
{
_clientAction = setRequiredValueAttribute(action, "clientAction");
}
/**
* Sets the link name of the Anchor. The link name is treated as a fragment
* identifier and may or may not contain the "#" character. If it does, the
* link name will not be qualified into a ScriptContainer. If the link name
* does not contain the "#" the normal tagId qualification will take place
* to produce the actual fragment identifier.
* @param linkName the link name for the Anchor.
* @jsptagref.attributedescription An internal place on the page to go to.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_linkName
* @netui:attribute required="false" rtexprvalue="true"
* description="An internal place on the page to go to."
*/
public void setLinkName(String linkName)
throws JspException
{
_linkName = setRequiredValueAttribute(linkName, "linkName");
}
/**
* Sets charset
attribute for the anchor.
* @param charSet the window target.
* @jsptagref.attributedescription The character set.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_charset
* @netui:attribute required="false" rtexprvalue="true"
* description="The character set."
*/
public void setCharSet(String charSet)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, CHARSET, charSet);
}
/**
* Sets type
attribute for the anchor.
* @param type the window target.
* @jsptagref.attributedescription The type.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_type
* @netui:attribute required="false" rtexprvalue="true"
* description="The type."
*/
public void setType(String type)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TYPE, type);
}
/**
* Sets hreflang
attribute for the anchor.
* @param hreflang the window target.
* @jsptagref.attributedescription The HREF lang.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_hreflang
* @netui:attribute required="false" rtexprvalue="true"
* description="The HREF lang."
*/
public void setHrefLang(String hreflang)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HREFLANG, hreflang);
}
/**
* Sets rel
attribute for the anchor.
* @param rel the window target.
* @jsptagref.attributedescription The relationship between the current document and the target Url.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_rel
* @netui:attribute required="false" rtexprvalue="true"
* description="The rel."
*/
public void setRel(String rel)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, REL, rel);
}
/**
* Sets rev
attribute for the anchor.
* @param rev the window target.
* @jsptagref.attributedescription Describes a reverse link from the anchor specified to the current document.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_rev
* @netui:attribute required="false" rtexprvalue="true"
* description="The rev."
*/
public void setRev(String rev)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, REV, rev);
}
/**
* Sets the window target.
* @param target the window target.
* @jsptagref.attributedescription The window target.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_action
* @netui:attribute required="false" rtexprvalue="true"
* description="The window target."
*/
public void setTarget(String target)
{
_state.registerAttribute(AbstractHtmlState.ATTR_GENERAL, TARGET, target);
}
/**
* This will set the text of the anchor. If there is body content, this
* will override that value.
* @param value the text of the anchor.
* @jsptagref.attributedescription Set the text of the anchor, overriding the body content.
* @jsptagref.databindable false
* @jsptagref.attributesyntaxvalue string_value
* @netui:attribute required="false" rtexprvalue="true"
* description="Set the text of the anchor overriding the body content"
*/
public void setValue(String value)
{
_value = setNonEmptyValueAttribute(value);
}
/**
* Prepare the hyperlink for rendering
* @throws JspException if a JSP exception has occurred
*/
public int doStartTag() throws JspException
{
if (hasErrors())
return SKIP_BODY;
return EVAL_BODY_BUFFERED;
}
/**
* Save the body content of the Anchor.
* @throws JspException if a JSP exception has occurred
*/
public int doAfterBody() throws JspException
{
if (bodyContent != null && _value == null) {
String value = bodyContent.getString().trim();
bodyContent.clearBody();
if (value.length() > 0)
_text = value;
}
return SKIP_BODY;
}
/**
* Render the hyperlink.
* @throws JspException if a JSP exception has occurred
*/
public int doEndTag() throws JspException
{
// report errors that may have occurred when the required attributes are being set
if (hasErrors())
return reportAndExit(EVAL_PAGE);
if (_value != null) {
_text = _value;
}
// build the anchor into the results
ByRef script = new ByRef();
WriteRenderAppender writer = new WriteRenderAppender(pageContext);
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
TagRenderingBase trb = TagRenderingBase.Factory.getRendering(TagRenderingBase.ANCHOR_TAG, request);
if (!createAnchorBeginTag(request, script, trb, writer, REQUIRED_ATTR)) {
if (!script.isNull())
write(script.getRef().toString());
return reportAndExit(EVAL_PAGE);
}
if (_text != null)
write(_text);
assert(trb != null) : "trb is null";
trb.doEndTag(writer);
if (!script.isNull())
write(script.getRef().toString());
// Render the remainder to the output stream
localRelease();
return EVAL_PAGE;
}
@Override
protected void localRelease() {
super.localRelease();
_text = null;
_value = null;
}
}