blob: 6ccba88f4a569cb9844b972d1305e074c7e035b2 [file] [log] [blame]
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 2.0.0 from src/site/xdoc/howto/action-event-howto.xml at 17 Jun 2025
| Rendered using Apache Maven Fluido Skin 2.1.0
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Apache Maven Doxia Site Renderer 2.0.0" />
<title>Action Events Howto – Apache Turbine</title>
<link rel="stylesheet" href="../css/apache-maven-fluido-2.1.0.min.css" />
<link rel="stylesheet" href="../css/site.css" />
<link rel="stylesheet" href="../css/print.css" media="print" />
<script src="../js/apache-maven-fluido-2.1.0.min.js"></script>
<link rel="icon" type="image/png" sizes="48x48" href="./images/favicon.ico">
<link rel="icon" type="image/png" sizes="48x48" href="../images/favicon.ico">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style>.github-fork-ribbon:before { background-color: orange; }</style>
</head>
<body>
<a class="github-fork-ribbon right-top" href="https://github.com/apache/turbine-build" data-ribbon="Fork me on GitHub">Fork me on GitHub</a>
<div class="container-fluid container-fluid-top">
<header>
<div id="banner">
<div class="pull-left"><div id="bannerLeft"><h1><a href="https://turbine.apache.org/"><img src="../images/turbine-project-apache-separate.png" alt="Apache Turbine" /></a></h1></div></div>
<div class="pull-right"><div id="bannerRight"><h1><a href="https://turbine.apache.org/"><img src="../images/logo.gif" /></a></h1></div></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li id="publishDate">Last Published: 01 Apr 2025<span class="divider">|</span>
</li>
<li id="projectVersion">Version: 7.0</li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://turbine.apache.org/fulcrum/">Fulcrum</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://turbine.apache.org/">Turbine</a></li>
<li class="pull-right"><a href="https://www.apache.org">Apache</a></li>
</ul>
</div>
</header>
<div class="row-fluid">
<header id="leftColumn" class="span2">
<nav class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header">General Information</li>
<li><a href="../index.html">Overview</a></li>
<li><a href="../features.html">Features</a></li>
<li><a href="../fsd.html">Specification</a></li>
<li><a href="../getting-started.html">Getting Started</a></li>
<li><a href="../how-to-build.html">Howto Build Turbine</a></li>
<li><a href="../changes-report.html">Changes</a></li>
<li class="nav-header">Documentation</li>
<li><a href="../services/index.html"><span class="icon-chevron-right"></span>Services</a></li>
<li><a href="../howto/index.html"><span class="icon-chevron-down"></span>Howtos</a>
<ul class="nav nav-list">
<li class="active"><a>Action Events Howto</a></li>
<li><a href="../howto/annotations.html">Annotations Howto</a></li>
<li><a href="../howto/configuration-howto.html">Configuration Howto</a></li>
<li><a href="../howto/extend-user-howto.html">Extend User Howto</a></li>
<li><a href="../howto/hibernate-howto.html">Hibernate OM Howto</a></li>
<li><a href="../howto/intake-howto.html">Intake Howto</a></li>
<li><a href="../howto/jsp-howto.html">JSP Howto</a></li>
<li><a href="../howto/migrate-from-2_1-howto.html">Migrating from 2.1 to 2.2</a></li>
<li><a href="../howto/migrate-from-2_2-howto.html">Migrating from 2.2 to 2.3</a></li>
<li><a href="../howto/migrate-from-2_3-howto.html">Migrating from 2.3 to 4.0</a></li>
<li><a href="../howto/migrate-from-4_0-howto.html">Migrating from 4.0 to 5.0</a></li>
<li><a href="../howto/pullmodel-howto.html">Pull Model Howto</a></li>
<li><a href="../howto/python-howto.html">Python Howto</a></li>
<li><a href="../howto/security-howto.html">Security Howto</a></li>
<li><a href="../howto/services-howto.html">Services Howto</a></li>
<li><a href="../howto/url-mapper-howto.html">URL Mapper Howto</a></li>
<li><a href="../howto/url-rewriting-howto.html">URL Rewriting Howto</a></li>
<li><a href="../howto/context-howto.html">Velocity Context Howto</a></li>
<li><a href="../howto/velocity-site-howto.html">Velocity Site Howto</a></li>
<li><a href="../howto/velocityonlylayout-howto.html">VelocityOnlyLayout Howto</a></li>
</ul></li>
<li><a href="https://cwiki.apache.org/confluence/display/TURBINE">Wiki</a></li>
<li><a href="../apidocs/index.html">JavaDocs</a></li>
<li class="nav-header">Development</li>
<li><a href="../proposals.html">Proposals</a></li>
<li><a href="../how-to-help.html">How To Help</a></li>
<li><a href="../todo.html">Todo</a></li>
<li class="nav-header">Project Documentation</li>
<li><a href="../project-info.html"><span class="icon-chevron-right"></span>Project Information</a></li>
<li><a href="../project-reports.html"><span class="icon-chevron-right"></span>Project Reports</a></li>
<li class="nav-header">Apache</li>
<li><a href="https://www.apache.org/">Apache Website</a></li>
<li><a href="https://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/foundation/how-it-works.html">How the ASF works</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
<li><a href="https://www.apache.org/security/">Security</a></li>
</ul>
</nav>
<div class="well sidebar-nav">
<form id="search-form" action="https://www.google.com/search" method="get" >
<input value="http://turbine.apache.org/turbine/turbine-7-0" name="sitesearch" type="hidden" />
<input class="search-query" name="q" id="query" type="text" placeholder="Search with Google..." />
</form>
<div id="poweredBy">
<div class="clear"></div>
<div class="clear"></div>
<a href="https://maven.apache.org/" class="builtBy" target="_blank"><img class="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a>
</div>
</div>
</header>
<main id="bodyColumn" class="span10">
<section><a id="Action_Events"></a>
<h1>Action Events</h1>
<p>
Turbine has a very useful feature that makes handling form submission
much more painless for the developer. In order to understand this, you
need to be familiar with the way that Turbine handles Actions. What happens
is that when a URI has the action= variable defined, a class is executed
before all of your other Screen classes by your Page class. So, consider
the following URI (I'm using the
<a href="velocity-site-howto.html">VelocitySite Howto</a> example):
</p>
<p>
<code>http://www.server.com/servlet/Turbine/template/AddUser/action/NewUser</code>
What happens is that Turbine will first execute the Java class file Action
named NewUser. Then, any class that extends the ActionEvent class instead
of the Action class will be able to take advantage of what happens next...
</p>
<pre class="prettyprint"><code>
public class NewUser extends VelocityAction
{
public void doAdd (PipelineData data, Context context) throws Exception
{
// put code here to add the user to the system
context.put (&quot;username&quot;, username );
getRunData(data).setMessage(&quot;User Added!&quot;);
}
@TurbineActionEvent(&quot;save&quot;)
public void saveUser (PipelineData data, Context context) throws Exception
{
// put code here to save the modified user to persistent storage
getRunData(data).setMessage(&quot;User Saved!&quot;);
}
public void doPerform(PipelineData data, Context context) throws Exception
{
getRunData(data).setMessage(&quot;Button not found!&quot;);
}
}
</code></pre>
<p>
Then, write your HTML tags specially like this:
</p>
<pre class="prettyprint"><code>
&lt;input type=&quot;submit&quot; name=&quot;eventSubmit_doAdd&quot; value=&quot;Add User&quot;&gt;
&lt;input type=&quot;submit&quot; name=&quot;eventSubmit_save&quot; value=&quot;Save User&quot;&gt;
</code></pre>
<p>
When your Action is executed, an &quot;event&quot; is sent to it by attempting
to execute a &quot;doAdd()&quot; method in your Action or a method annotated with the
event name &quot;save&quot;, respectively. The cool thing about this
is that each of your &quot;actions&quot; that are performed within your Action class
now are componentized into a single method that can be javadoc'ed individually.
The annotation adds the possibility to name your events and methods any way you
like.
</p>
<p>
This new functionality does not mean that you should write all of your
actions in one single class, what it means is that if you have a screen
with many buttons on it that are very specific to that screen, it might
be a good idea to place all those methods into a single class. This allows
you to do it easily and also prevents you from having to do a &quot;if then
elseif&quot; tree to figure out which button was clicked.
</p>
<p>
For a catchall, the doPerform() method will be executed if no other
method or button could be found.
</p>
<p>
Because all keys processed by ParameterParser are subject to URL
case folding, (in default mode lowercase), we have
to do some work to format the string into a method name. For example, a
button name eventSubmit_doDelete gets converted into eventsubmit_dodelete.
Thus, we need to form some sort of naming convention so that dodelete can
be turned into doDelete.
</p>
<p>
Thus, the convention is this:
</p>
<ul>
<li>The variable name MUST have the prefix &quot;eventSubmit_&quot;.</li>
<li>The variable name after the prefix MUST begin with the letters &quot;do&quot;.</li>
<li>The first letter after the &quot;do&quot; will be capitalized and the rest will be
lowercase</li>
</ul>
<p>
If you follow these conventions, then you should be ok with your method
naming in your Action class. If you make use of the <code>@TurbineActionEvent</code>
annotation, you can get rid of the latter two limitations and name your events
methods as you like. Note that the event names are still subject to URL
case folding, so that by default, <code>@TurbineActionEvent(&quot;save&quot;)</code>
and <code>@TurbineActionEvent(&quot;Save&quot;)</code> are identical - unless you
run the ParameterParser with URL case folding set to NONE.
</p>
<p>
There is a property in the TurbineResources.properties file, called &quot;action.eventsubmit.needsvalue&quot;.
If you set this to &quot;true&quot;, only the events that contain a non-empty, non-zero value will be
executed. This is useful if you have a form with multiple, different events, that need to be executed
and the form is submitted by client-side code, e.g. JavaScript.
</p>
<p>
If you want to trigger an action event from an html link, versus a button, then just add a parameter with the name eventSubmit_doMyaction.
The value can be anything as the name is all that is important.
</p>
</section>
</main>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
<p>© 2000–2025
<a href="https://www.apache.org/">The Apache Software Foundation</a>
</p>
</div>
</div>
</footer>
</body>
</html>