I have a search box which is displayed on every page. The JSP code for the search box is inserted into every page via tiles.
The search box has a form and an action class SearchAction
which needs to preload some properties for drop down boxes. The SearchAction
class has an input()
method, which does this initialization.
Some pages also have their own form in the main area. Also with their own action class. They also have an input()
method which does some preloading.
Update:
I am adding a trimmed down example, since it's probably not clear what I am trying to do. It's a register page register.jsp
with an RegisterAction
. And the page also contains the search form. (BTW: I left out the getter/setter and other stuff in the action classes to keep it short):
register.jsp
:
<s:form action="executeSearch">
<s:textfield key="name" label="Name"/>
<s:textfield key="age" label="Age"/>
<s:submit/>
</s:form>
<s:form action="executeRegister">
<s:textfield key="firstName" label="First Name"/>
<s:textfield key="lastName" label="Last Name"/>
<s:textfield key="age" label="Age"/>
<s:submit/>
</s:form>
struts.xml
:
<action name="*Search" class="action.SearchAction" method="{1}">
<result name="success">/searchresult.jsp</result>
</action>
<action name="*Register" class="action.RegisterAction" method="{1}">
<result name="input">/register.jsp</result>
<result name="success">/registerOk.jsp</result>
</action>
SearchAction.java
:
public class SearchAction extends ActionSupport {
private String name;
private int age;
@Override
public String input() throws Exception {
// preload the search form with some demo data
name = "test";
age = 20;
return INPUT;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
...
}
RegisterAction.java
:
public class RegisterAction extends ActionSupport {
private String firstName;
private String lastName;
private int age;
@Override
public String input() throws Exception {
// preload the register form with some demo data
firstName = "John";
lastName = "Rambo";
age = 10;
return INPUT;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
...
}
Let's say I call the action inputRegister.action
. Then RegisterAction.input()
is called. The properties are set. And result SUCCESS
causes register.jsp
to be rendered.
But what about my search form. How do I get access to the search action and it's model. Neither of those are on the ValueStack
of course. And neither do I see a way to call any methods of SearchAction
in order to initialize it's model. I deliberately choose age
to be in both action classes. In the rendered page you can see that the search form also accesses the RegisterAction-*.properties
(because that's on top of the ValueStack
). But it needs to access SearchAction
. It must display 20 and not 10.
I am clearly doing it wrong. But even after a lot of googling, I still did't find out the right way to do it.
As I found (please correct me): Two forms need to be initiated in their own actions before be show to user, when you ask for Registration form, the search form does not get initiated, as its action is never called.
This is a common problem which can be easily handled with Ajax, DO NOT LOAD ALL YOUR PAGE DATA. Please have a look at http://struts.jgeppert.com/struts2-jquery-showcase/index.action. There is a Theme selection select box, which has been initiated once. Loading other part of the page, will be done via Ajax and thus the theme selection, action which initiates the select box, does not need to be re-run. You can easily use the struts 2 jquery plugin to achieve it.
If you can not use Ajax (with any reason), then there is no simple way. You should manually initiate the you search form items, in EACH action, to make sure that your struts tag can read search form initiated data. You can think of it as you need to some how, cut and paste the body of your search action in all your actions !!
The concept of the view is used to perform any number of actions, and any action can have any number of results. A result is used to return a view. The action that returns a view is placed on top of the ValueStack
to be easy accessible via evaluating OGNL expressions. The result view could be mapped to any action in any action class. It knows nothing about action which calls it, but it can determine it, again using OGNL. You can map actions to different method of the same action class, so you don't need to have many input()
methods.
EDIT:
You problem is you bounded form fields wrong. Each form should have a separate storage to display it correctly. Fields are bounded by name, and you'd better have a form bean for the search condition variables and put it somewhere in the action context.
<s:form action="executeSearch">
<s:textfield key="searchBean.name" label="Name"/>
<s:textfield key="searchbean.age" label="Age"/>
<s:submit/>
</s:form>
<s:form action="executeRegister">
<s:textfield key="firstName" label="First Name"/>
<s:textfield key="lastName" label="Last Name"/>
<s:textfield key="age" label="Age"/>
<s:submit/>
</s:form>
Note: the key
attribute generates name
, label
, and value
.
Each action needs to initialize a searchBean
, unless it has a session scope. If you put a bean to a session, then you should use #session.
prefix. More about OGNL you can find on the docs page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With