Author: rich
Date: Mon Feb 21 22:31:48 2005
New Revision: 154801
URL: http://svn.apache.org/viewcvs?view=rev&rev=154801
Log:
Fix for http://issues.apache.org/jira/browse/BEEHIVE-190 : The prevent double
submit feature does not work if the back button is not using the cached page
The 'preventDoubleSubmit' attribute on @Jpf.Action/@Jpf.SimpleAction works in
conjunction with NetUI tags (anchor, button, etc.) to throw an exception if an
action is raised twice from the same page. This works when the user
double-clicks a link, but it doesn't always work when the user clicks the link,
reaches a success page, goes back using the back button, and clicks the link
again. The specific case where this doesn't work is when the browser is
instructed *not* to cache the original page, so each time you go back to it, a
new one is rendered. By default, pages reached through Page Flow actions
included no-cache headers when the server was not in production mode (to make
iterative development easier).
To mitigate this, I've added the ability to configure action/page caching
(i.e., the headers that are sent to the browser to configure caching). The
default behavior now is *not* to prevent caching on pages, which fixes this
bug. If you *do* still want to prevent caching of pages, you can add either of
the following snippets to netui-config.xml:
<pageflow-config>
<prevent-cache>always</prevent-cache>
</pageflow-config>
-or-
<pageflow-config>
<prevent-cache>inDevMode</prevent-cache>
</pageflow-config>
The "always" value always prevents caching, and the "inDevMode" value prevents
caching when the server is not in production mode.
I also added a 'disableOnClick' attribute to the Anchor, ImageAnchor, and
Button tags. When this is set to true, the button/link can't be clicked twice
-- this eliminates the need for server-side checking in cases where JavaScript
is enabled.
DRT/BVT: netui (WinXP)
BB: self (linux)
Added:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf
(with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/cool.gif
(with props)
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp
(with props)
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml
(with props)
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/JavaControlUtils.java
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/AnchorBase.java
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/Button.java
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/CoreScriptFeature.java
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/ScriptRequestState.java
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/javaScript.properties
incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
(original)
+++
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/PageFlowRequestProcessor.java
Mon Feb 21 22:31:48 2005
@@ -46,6 +46,8 @@
import org.apache.beehive.netui.util.DiscoveryUtils;
import org.apache.beehive.netui.util.FileUtils;
import org.apache.beehive.netui.util.ServletUtils;
+import org.apache.beehive.netui.util.config.ConfigUtil;
+import org.apache.beehive.netui.util.config.bean.PageflowConfig;
import org.apache.beehive.netui.util.logging.Logger;
import org.apache.struts.Globals;
import org.apache.struts.action.Action;
@@ -1907,20 +1909,51 @@
}
/**
- * Set the no-cache headers for all responses. This overrides the base
Struts behavior to
- * prevent caching entirely in iterative dev mode.
+ * Set the no-cache headers. This overrides the base Struts behavior to
prevent caching even for the pages.
*/
protected void processNoCache( HttpServletRequest request,
HttpServletResponse response )
{
- if ( moduleConfig.getControllerConfig().getNocache() || !
_servletContainerAdapter.isInProductionMode() )
+ //
+ // Set the no-cache headers if:
+ // 1) the module is configured for it, or
+ // 2) netui-config.xml has an "always" value for
<pageflow-config><prevent-cache>, or
+ // 3) netui-config.xml has an "inDevMode" value for
<pageflow-config><prevent-cache>, and we're not in
+ // production mode.
+ //
+ boolean noCache = moduleConfig.getControllerConfig().getNocache();
+
+ if ( ! noCache )
+ {
+ PageflowConfig pfConfig =
ConfigUtil.getConfig().getPageflowConfig();
+
+ if ( pfConfig != null )
+ {
+ PageflowConfig.PreventCache.Enum preventCache =
pfConfig.getPreventCache();
+
+ if ( preventCache != null )
+ {
+ switch ( preventCache.intValue() )
+ {
+ case PageflowConfig.PreventCache.INT_ALWAYS:
+ noCache = true;
+ break;
+ case PageflowConfig.PreventCache.INT_IN_DEV_MODE:
+ noCache = !
_servletContainerAdapter.isInProductionMode();
+ break;
+ }
+ }
+ }
+ }
+
+ if ( noCache )
{
//
- // The call to PageFlowJspFilter.preventCache() will cause caching
to be prevented
- // even when we end up forwarding to a JSP. Normally, no-cache
headers are lost
+ // The call to PageFlowPageFilter.preventCache() will cause
caching to be prevented
+ // even when we end up forwarding to a pagee. Normally, no-cache
headers are lost
// when a server forward occurs.
//
ServletUtils.preventCache( response );
- PageFlowJspFilter.preventCache( request );
+ PageFlowPageFilter.preventCache( request );
}
}
Modified:
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/JavaControlUtils.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/JavaControlUtils.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/JavaControlUtils.java
(original)
+++
incubator/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/pageflow/internal/JavaControlUtils.java
Mon Feb 21 22:31:48 2005
@@ -149,7 +149,8 @@
try
{
- Object instance = Controls.instantiate(
Thread.currentThread().getContextClassLoader(), controlClassName, properties,
beanContext, controlID );
+ Object instance = Controls.instantiate(
Thread.currentThread().getContextClassLoader(), controlClassName,
+ properties, beanContext,
controlID );
assert instance instanceof ControlBean :
instance.getClass().getName();
return ( ControlBean ) instance;
}
Modified:
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/AnchorBase.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/AnchorBase.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/AnchorBase.java
(original)
+++
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/AnchorBase.java
Mon Feb 21 22:31:48 2005
@@ -45,6 +45,7 @@
private Form _form; // the nearest form
private boolean _formSubmit = false; // should the anchor submit an
enclosing form?
private PopupSupport _popupSupport = null; // popup support, if the popup
attribute is set to true
+ private boolean _disableOnClick = false; // When clicked, this anchor
will disable itself after being clicked.
/**
* Base support for the attribute tag. This is overridden to prevent
setting the <code>href</code>
@@ -195,8 +196,25 @@
{
_popupSupport = new PopupSupport();
}
+
+
+ /**
+ * When true, this anchor will disable itself after being clicked.
+ * @param disableOnClick - when true, this anchor will disable itself
after being clicked.
+ * @jsptagref.attributedescription Boolean. If
<code>disableOnClick</code> is set to true,
+ * the anchor will disable itself after being clicked.
+ * @jsptagref.databindable true
+ * @jsptagref.attributesyntaxvalue <i>boolean_disableOnClick</i>
+ * @netui:attribute required="false" rtexprvalue="true" type="boolean"
+ * description="When true, this anchor will disable itself after being
clicked."
+ * @netui.tldx:attribute
+ */
+ public void setDisableOnClick(boolean disableOnClick)
+ {
+ _disableOnClick = disableOnClick;
+ }
-
+
/**
* Sets the tabIndex of the rendered html tag.
* @param tabindex - the tab index.
@@ -436,8 +454,8 @@
if (onclick == null) {
if (_formSubmit && formAction != null) {
String realFormName = getFormId();
- String entry =
ScriptRequestState.getString("anchorFormSubmitAction",
- new Object[]{realFormName, _state.href});
+ String key = (_disableOnClick ?
"anchorDisableAndSubmitFormAction" : "anchorFormSubmitAction");
+ String entry = ScriptRequestState.getString(key, new
Object[]{realFormName, _state.href});
_state.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
ONCLICK, entry);
// Jira 299
//_state.onClick =
ScriptRequestState.getString("anchorFormSubmitAction",
@@ -445,6 +463,10 @@
if (_form != null)
_form.insureRealId();
}
+ else if (_disableOnClick) {
+ String entry =
ScriptRequestState.getString("anchorDisableAction", null);
+ _state.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
ONCLICK, entry);
+ }
else if (_popupSupport != null) {
_state.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
ONCLICK, _popupSupport.getOnClick(_state.href));
// Jira 299
@@ -588,6 +610,7 @@
_form = null;
_formSubmit = false;
_popupSupport = null;
+ _disableOnClick = false;
}
public PopupSupport getPopupSupport()
Modified:
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/Button.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/Button.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/Button.java
(original)
+++
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/html/Button.java
Mon Feb 21 22:31:48 2005
@@ -24,6 +24,8 @@
import org.apache.beehive.netui.tags.HtmlUtils;
import org.apache.beehive.netui.tags.IHtmlAccessable;
import org.apache.beehive.netui.tags.javascript.ScriptRequestState;
+import org.apache.beehive.netui.tags.javascript.CoreScriptFeature;
+import org.apache.beehive.netui.tags.javascript.IScriptReporter;
import org.apache.beehive.netui.tags.internal.PageFlowTagUtils;
import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
import org.apache.beehive.netui.tags.rendering.InputSubmitTag;
@@ -84,6 +86,7 @@
private Map _params; // Any parameters to the submit
private String _targetScope; // Target page flow scope; see
comments on setTargetScope()
private PopupSupport _popupSupport = null; // popup support, if the popup
attribute is set to true
+ private boolean _disableOnClick = false; // When clicked, this button
will disable itself before submitting.
/**
* Return the name of the Tag.
@@ -202,13 +205,29 @@
* @jsptagref.databindable true
* @jsptagref.attributesyntaxvalue <i>boolean_popup</i>
* @netui:attribute required="false" rtexprvalue="true" type="boolean"
- * description="If popup is set to true, the button will open a popup
window.
+ * description="If popup is set to true, the button will open a popup
window."
* @netui.tldx:attribute
*/
public void setPopup(boolean popup)
{
_popupSupport = new PopupSupport();
}
+
+ /**
+ * When true, this button will disable itself before submitting.
+ * @param disableOnClick - when true, this button will disable itself
before submitting.
+ * @jsptagref.attributedescription Boolean. If
<code>disableOnClick</code> is set to true,
+ * the button will disable itself before submitting.
+ * @jsptagref.databindable true
+ * @jsptagref.attributesyntaxvalue <i>boolean_disableOnClick</i>
+ * @netui:attribute required="false" rtexprvalue="true" type="boolean"
+ * description="When true, this button will disable itself before
submitting."
+ * @netui.tldx:attribute
+ */
+ public void setDisableOnClick(boolean disableOnClick)
+ {
+ _disableOnClick = disableOnClick;
+ }
/**
* Adds a URL parameter to the generated hyperlink.
@@ -327,27 +346,30 @@
idScript = renderNameAndId(request, _state, null);
}
+ boolean buttonDisableAndSubmit = false;
+ boolean buttonDisable = false;
+
// if the user overrides the onclick we will ignore this
if (getOnClick() == null) {
- if (_popupSupport != null) {
- String href = null;
- if (_action != null) {
- ServletContext servletContext =
pageContext.getServletContext();
- boolean forXML = TagRenderingBase.Factory.isXHTML(request);
- try {
- href =
PageFlowUtils.getRewrittenActionURI(servletContext, request, response, _action,
_params, null, forXML);
- } catch (URISyntaxException e) {
- // report the error...
-
logger.error(Bundle.getString("Tags_URISyntaxException"));
- String s = Bundle.getString("Tags_Button_URLException",
- new Object[]{_action,
e.getMessage()});
- registerTagError(s, e);
- }
+ if (_disableOnClick) {
+ Form parentForm = getNearestForm();
+ String href = getActionUrl(request, response);
+ String entry;
+ if (parentForm != null && href != null && (_state.type == null
|| _state.type == INPUT_SUBMIT)) {
+ entry =
ScriptRequestState.getString("buttonDisableAndSubmitFormAction",
+ new Object[]{parentForm.getRealFormId(), href});
+ buttonDisableAndSubmit = true;
}
else {
- Form parentForm = getNearestForm();
- href = HtmlUtils.addParams(parentForm.getActionUrl(),
_params, response.getCharacterEncoding());
+ entry =
ScriptRequestState.getString("buttonDisableAction", null);
+ buttonDisable = true;
}
+ _state.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
ONCLICK, entry);
+ if (parentForm != null)
+ parentForm.insureRealId();
+ }
+ else if (_popupSupport != null) {
+ String href = getActionUrl(request, response);
if (href != null) {
href = response.encodeURL(href);
@@ -366,11 +388,16 @@
br.doEndTag(writer);
//Emit javascript if this button needs to sumbit the form or open a
popup window
- if (idScript != null || _popupSupport != null) {
+ if (idScript != null || _popupSupport != null || buttonDisable ||
buttonDisableAndSubmit) {
ScriptRequestState srs =
ScriptRequestState.getScriptRequestState(request);
StringBuilder script = new StringBuilder(32);
StringBuilderRenderAppender scriptWriter = new
StringBuilderRenderAppender(script);
+ IScriptReporter sr = getScriptReporter();
+ if (buttonDisableAndSubmit)
+ srs.writeFeature(sr, scriptWriter,
CoreScriptFeature.BUTTON_DISABLE_AND_SUBMIT, true, false, null);
+ if (buttonDisable)
+ srs.writeFeature(sr, scriptWriter,
CoreScriptFeature.BUTTON_DISABLE, true, false, null);
if (_popupSupport != null)
_popupSupport.writeScript(request, srs, getScriptReporter(),
scriptWriter);
if (idScript != null)
@@ -383,6 +410,33 @@
return EVAL_PAGE;
}
+ private String getActionUrl(HttpServletRequest request,
HttpServletResponse response)
+ throws JspException
+ {
+ String href = null;
+
+ if (_action != null) {
+ ServletContext servletContext = pageContext.getServletContext();
+ boolean forXML = TagRenderingBase.Factory.isXHTML(request);
+ try {
+ href = PageFlowUtils.getRewrittenActionURI(servletContext,
request, response, _action, _params, null, forXML);
+ } catch (URISyntaxException e) {
+ // report the error...
+ logger.error(Bundle.getString("Tags_URISyntaxException"));
+ String s = Bundle.getString("Tags_Button_URLException",
+ new Object[]{_action,
e.getMessage()});
+ registerTagError(s, e);
+ }
+ }
+ else {
+ Form parentForm = getNearestForm();
+ if (parentForm != null)
+ href = HtmlUtils.addParams(parentForm.getActionUrl(), _params,
response.getCharacterEncoding());
+ }
+
+ return href;
+ }
+
/**
* Release any acquired resources.
*/
@@ -396,6 +450,7 @@
_params = null;
_targetScope = null;
_popupSupport = null;
+ _disableOnClick = false;
}
/* ==================================================================
Modified:
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/CoreScriptFeature.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/CoreScriptFeature.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/CoreScriptFeature.java
(original)
+++
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/CoreScriptFeature.java
Mon Feb 21 22:31:48 2005
@@ -22,20 +22,22 @@
*/
public enum CoreScriptFeature
{
- LEGACY_LOOKUP (0x0001),
- ID_LOOKUP (0x0002),
- NAME_LOOKUP (0x0004),
- SCOPE_LOOKUP (0x0008),
- ROLLOVER (0x0010),
- ANCHOR_SUBMIT (0x0020),
- POPUP_FUNC (0x0040),
- ALLOCATE_LEGACY (0x0080),
- ALLOCATE_ID (0x0100),
- ALLOCATE_NAME (0x0200),
- LEGACY_SCOPE_LOOKUP (0x0400),
- TREE_INIT (0x0800),
- DIVPANEL_INIT (0x1000),
- DYNAMIC_INIT (0x2000),
+ LEGACY_LOOKUP (0x0001),
+ ID_LOOKUP (0x0002),
+ NAME_LOOKUP (0x0004),
+ SCOPE_LOOKUP (0x0008),
+ ROLLOVER (0x0010),
+ ANCHOR_SUBMIT (0x0020),
+ POPUP_FUNC (0x0040),
+ ALLOCATE_LEGACY (0x0080),
+ ALLOCATE_ID (0x0100),
+ ALLOCATE_NAME (0x0200),
+ LEGACY_SCOPE_LOOKUP (0x0400),
+ TREE_INIT (0x0800),
+ DIVPANEL_INIT (0x1000),
+ DYNAMIC_INIT (0x2000),
+ BUTTON_DISABLE_AND_SUBMIT (0x4000),
+ BUTTON_DISABLE (0x8000),
// These features are not written out once. They are identified by
setting the top bit
SET_FOCUS (0x10000001);
Modified:
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/ScriptRequestState.java
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/ScriptRequestState.java?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/ScriptRequestState.java
(original)
+++
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/ScriptRequestState.java
Mon Feb 21 22:31:48 2005
@@ -292,6 +292,10 @@
return "initDivPanel";
case DYNAMIC_INIT:
return "writeWebAppName";
+ case BUTTON_DISABLE_AND_SUBMIT:
+ return "buttonDisableAndSubmitForm";
+ case BUTTON_DISABLE:
+ return "buttonDisable";
}
assert(false) : "getFeature fell through on feature:" + feature;
return null;
Modified:
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/javaScript.properties
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/javaScript.properties?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/javaScript.properties
(original)
+++
incubator/beehive/trunk/netui/src/tags-html/org/apache/beehive/netui/tags/javascript/javaScript.properties
Mon Feb 21 22:31:48 2005
@@ -30,6 +30,48 @@
legacyAnchorFormSubmitAction=anchor_submit_form("{0}","{1}");return false;
anchorFormSubmitAction=anchor_submit_form(''{0}'',''{1}'');return false;
+# The action event that will call the form submit javascript only if this link
has not been clicked.
+anchorDisableAndSubmitFormAction=if (this.clicked) return false;
anchor_submit_form(''{0}'',''{1}''); \
+this.clicked=true; return false;
+
+# The action event that will disable the anchor after it has been clicked.
+anchorDisableAction=if (this.clicked) return false; this.clicked=true;
+
+# generic method to disable a button and submit a form, used by Button.
+# The following method will be written out once an may be called by
+# multiple buttons. The event JavaScript is defined following it.
+buttonDisableAndSubmitForm=\
+// submit the form from an Button after disabling the Button\n\
+// Search for the form by actionName,\n\
+// Replace the action with the passed in action\n\
+// Submit the form\n\
+function button_disable_and_submit_form(button, netuiName, newAction)\n\
+{\n\
+\ button.disabled = true;\n\
+\ for (var i=0; i<document.forms.length; i++) {\n\
+\ if (document.forms[i].id == netuiName) {\n\
+\ document.forms[i].method = "POST";\n\
+\ document.forms[i].action = newAction;\n\
+\ document.forms[i].submit();\n\
+\ }\n\
+\ }\n\
+}\n
+
+# The action event that will call the form submit javascript
+buttonDisableAndSubmitFormAction=button_disable_and_submit_form(this,''{0}'',''{1}'');return
false;
+
+# generic method to disable a Button, used by Button.
+# The following method will be written out once an may be called by
+# multiple buttons. The event JavaScript is defined following it.
+buttonDisable=\
+function button_disable(button)\n\
+{\n\
+\ button.disabled = true;\n\
+}\n
+
+# The action event that will call the form submit javascript
+buttonDisableAction=button_disable(this);return false;
+
# generic method to open a popup window
popupFunc=\
function netui_popup(url, name, features, replace)\n\
Modified:
incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd?view=diff&r1=154800&r2=154801
==============================================================================
--- incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
(original)
+++ incubator/beehive/trunk/netui/src/util/schema/netui-config/netui-config.xsd
Mon Feb 21 22:31:48 2005
@@ -132,6 +132,15 @@
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
+ <xsd:element name="prevent-cache" minOccurs="0" maxOccurs="1"
default="default">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="default"/>
+ <xsd:enumeration value="always"/>
+ <xsd:enumeration value="inDevMode"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
<xsd:element name="module-config-locators"
type="netui:module-config-locators" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
Added:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf?view=auto&rev=154801
==============================================================================
---
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf
(added)
+++
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf
Mon Feb 21 22:31:48 2005
@@ -0,0 +1,40 @@
+package tags.disableOnClick;
+
+import org.apache.beehive.netui.pageflow.*;
+import org.apache.beehive.netui.pageflow.annotations.*;
+
[EMAIL PROTECTED](
+ simpleActions={
+ @Jpf.SimpleAction(name="begin", path="index.jsp")
+ }
+)
+public class Controller extends PageFlowController
+{
+ private static int count = 0;
+
+ @Jpf.Action(
+ forwards={
+ @Jpf.Forward(name="index", path="index.jsp")
+ }
+ )
+ public Forward someAction()
+ throws InterruptedException
+ {
+ System.err.println( "****** in someAction " + ++count );
+ Thread.sleep( 3000 );
+ return new Forward( "index" );
+ }
+
+ @Jpf.Action(
+ forwards={
+ @Jpf.Forward(name="index", path="index.jsp")
+ }
+ )
+ public Forward anotherAction()
+ throws InterruptedException
+ {
+ System.err.println( "****** in anotherAction " + ++count );
+ Thread.sleep( 3000 );
+ return new Forward( "index" );
+ }
+}
Propchange:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/Controller.jpf
------------------------------------------------------------------------------
svn:eol-style = native
Added:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/cool.gif
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/cool.gif?view=auto&rev=154801
==============================================================================
Binary file - no diff available.
Propchange:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/cool.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp?view=auto&rev=154801
==============================================================================
---
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp
(added)
+++
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp
Mon Feb 21 22:31:48 2005
@@ -0,0 +1,45 @@
+<%@ page language="java" contentType="text/html;charset=UTF-8"%>
+<%@ taglib prefix="netui" uri="http://beehive.apache.org/netui/tags-html-1.0"%>
+<%@ taglib prefix="netui-data"
uri="http://beehive.apache.org/netui/tags-databinding-1.0"%>
+<%@ taglib prefix="netui-template"
uri="http://beehive.apache.org/netui/tags-template-1.0"%>
+
+
+<netui:html>
+ <head>
+ <netui:base/>
+ </head>
+ <netui:body>
+ <h3>${pageFlow.URI}</h3>
+
+ This test merely verifies that the right JavaScript is rendered; it
can't actually test the disabling behavior.
+ <br/>
+ <br/>
+ <netui:form action="someAction">
+ <netui:button value="submit"/>
+ <br/>
+ <netui:button value="submit (disableOnClick)"
disableOnClick="true"/>
+ <br/>
+ <br/>
+ <netui:button value="submit with action override"
action="anotherAction"/>
+ <br/>
+ <netui:button value="submit with action override (disableOnClick)"
action="anotherAction" disableOnClick="true"/>
+ <br/>
+ <br/>
+ <netui:anchor formSubmit="true">submit</netui:anchor>
+ <br/>
+ <netui:anchor formSubmit="true" disableOnClick="true">submit
(disableOnClick)</netui:anchor>
+ </netui:form>
+
+ <netui:anchor action="someAction">non-submit</netui:anchor>
+ <br/>
+ <netui:anchor action="someAction" disableOnClick="true">non-submit
(disableOnClick)</netui:anchor>
+ <br/>
+ <br/>
+ non-submit: <netui:imageAnchor action="someAction" src="cool.gif"/>
+ <br/>
+ non-submit (disableOnClick): <netui:imageAnchor action="someAction"
disableOnClick="true" src="cool.gif"/>
+ </netui:body>
+</netui:html>
+
+
+
Propchange:
incubator/beehive/trunk/netui/test/webapps/drt/coreWeb/tags/disableOnClick/index.jsp
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml?view=diff&r1=154800&r2=154801
==============================================================================
---
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
(original)
+++
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/config/testRecorder-tests.xml
Mon Feb 21 22:31:48 2005
@@ -3252,6 +3252,23 @@
</features>
</test>
<test>
+ <name>DisableOnClick</name>
+ <description>Test of the rendered JavaScript for disabling anchors,
imageAnchors and buttons when they are clicked.</description>
+ <webapp>coreWeb</webapp>
+ <categories>
+ <category>bvt</category>
+ <category>bvt.struts11</category>
+ <category>tags</category>
+ </categories>
+ <features>
+ <feature>Anchor</feature>
+ <feature>Button</feature>
+ <feature>Form</feature>
+ <feature>ImageAnchor</feature>
+ <feature>JavaScript</feature>
+ </features>
+ </test>
+ <test>
<name>DivPanel</name>
<description>Basic test of the DivPanel</description>
<webapp>coreWeb</webapp>
Added:
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml
URL:
http://svn.apache.org/viewcvs/incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml?view=auto&rev=154801
==============================================================================
---
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml
(added)
+++
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml
Mon Feb 21 22:31:48 2005
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ses:recorderSession
xmlns:ses="http://beehive.apache.org/netui/tools/testrecorder/2004/session">
+ <ses:sessionName>DisableOnClick</ses:sessionName>
+ <ses:tester>rich</ses:tester>
+ <ses:startDate>21 Feb 2005, 10:23:51.042 PM MST</ses:startDate>
+ <ses:description>Test of the rendered JavaScript for disabling anchors,
imageAnchors and buttons when they are clicked.</ses:description>
+ <ses:tests>
+ <ses:test>
+ <ses:testNumber>1</ses:testNumber>
+ <ses:request>
+ <ses:protocol>HTTP</ses:protocol>
+ <ses:protocolVersion>1.1</ses:protocolVersion>
+ <ses:host>localhost</ses:host>
+ <ses:port>8080</ses:port>
+ <ses:uri>/coreWeb/tags/disableOnClick/Controller.jpf</ses:uri>
+ <ses:method>GET</ses:method>
+ <ses:parameters/>
+ <ses:cookies>
+ <ses:cookie>
+ <ses:name>JSESSIONID</ses:name>
+ <ses:value>6A62187DDD224AFCABABC688F6FAA7C5</ses:value>
+ </ses:cookie>
+ </ses:cookies>
+ <ses:headers>
+ <ses:header>
+ <ses:name>accept</ses:name>
+
<ses:value>text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>accept-charset</ses:name>
+ <ses:value>ISO-8859-1,utf-8;q=0.7,*;q=0.7</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>accept-encoding</ses:name>
+ <ses:value>gzip,deflate</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>accept-language</ses:name>
+ <ses:value>en-us,en;q=0.5</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>connection</ses:name>
+ <ses:value>keep-alive</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>cookie</ses:name>
+
<ses:value>JSESSIONID=6A62187DDD224AFCABABC688F6FAA7C5</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>host</ses:name>
+ <ses:value>localhost:8080</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>keep-alive</ses:name>
+ <ses:value>300</ses:value>
+ </ses:header>
+ <ses:header>
+ <ses:name>user-agent</ses:name>
+ <ses:value>Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.7.5) Gecko/20041107 Firefox/1.0</ses:value>
+ </ses:header>
+ </ses:headers>
+ </ses:request>
+ <ses:response>
+ <ses:statusCode>200</ses:statusCode>
+ <ses:reason/>
+ <ses:responseBody><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+
+ <head>
+ <base
href="http://localhost:8080/coreWeb/tags/disableOnClick/index.jsp">
+ </head>
+ <body>
+ <h3>/tags/disableOnClick/Controller.jpf</h3>
+
+ This test merely verifies that the right JavaScript is rendered; it
can't actually test the disabling behavior.
+ <br/>
+ <br/>
+ <form name="Netui_Form_0" id="Netui_Form_0"
action="/coreWeb/tags/disableOnClick/someAction.do" method="post">
+ <input type="submit" value="submit">
+ <br/>
+ <input type="submit" value="submit (disableOnClick)"
onclick="button_disable_and_submit_form(this,'Netui_Form_0','/coreWeb/tags/disableOnClick/someAction.do');return
false;">
+ <br/>
+ <br/>
+ <input type="submit" name="actionOverride:anotherAction"
value="submit with action override">
+ <br/>
+ <input type="submit" name="actionOverride:anotherAction"
value="submit with action override (disableOnClick)"
onclick="button_disable_and_submit_form(this,'Netui_Form_0','/coreWeb/tags/disableOnClick/anotherAction.do');return
false;">
+ <br/>
+ <br/>
+ <a href="/coreWeb/tags/disableOnClick/someAction.do"
onclick="anchor_submit_form('Netui_Form_0','/coreWeb/tags/disableOnClick/someAction.do');return
false;">submit</a>
+ <br/>
+ <a href="/coreWeb/tags/disableOnClick/someAction.do"
onclick="if (this.clicked) return false;
anchor_submit_form('Netui_Form_0','/coreWeb/tags/disableOnClick/someAction.do');
this.clicked=true; return false;">submit (disableOnClick)</a>
+ </form>
+
+ <a
href="/coreWeb/tags/disableOnClick/someAction.do">non-submit</a>
+ <br/>
+ <a href="/coreWeb/tags/disableOnClick/someAction.do" onclick="if
(this.clicked) return false; this.clicked=true;">non-submit
(disableOnClick)</a>
+ <br/>
+ <br/>
+ non-submit: <a
href="/coreWeb/tags/disableOnClick/someAction.do"><img
src="/coreWeb/tags/disableOnClick/cool.gif"></a>
+ <br/>
+ non-submit (disableOnClick): <a
href="/coreWeb/tags/disableOnClick/someAction.do" onclick="if (this.clicked)
return false; this.clicked=true;"><img
src="/coreWeb/tags/disableOnClick/cool.gif"></a>
+ <script language="JavaScript" type="text/JavaScript">
+<!--
+
+// **** Start the NetUI Framework Generated JavaScript ****
+
+// submit the form from an Button after disabling the Button
+// Search for the form by actionName,
+// Replace the action with the passed in action
+// Submit the form
+function button_disable_and_submit_form(button, netuiName, newAction)
+{
+ button.disabled = true;
+ 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();
+ }
+ }
+}
+
+// submit the form from an Anchor or ImageAnchor
+// Search for the form by actionName,
+// Replace the action with the passed in action
+// Submit the form
+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();
+ }
+ }
+}
+-->
+</script></body>
+
+</html></ses:responseBody>
+ </ses:response>
+ </ses:test>
+ </ses:tests>
+ <ses:endDate>21 Feb 2005, 10:24:00.566 PM MST</ses:endDate>
+ <ses:testCount>1</ses:testCount>
+</ses:recorderSession>
Propchange:
incubator/beehive/trunk/netui/test/webapps/drt/testRecorder/tests/DisableOnClick.xml
------------------------------------------------------------------------------
svn:eol-style = native