access data of struts2 nested iterator in action - struts2

<s:iterator var="parent" value="studentList">
<s:iterator var="child1" value="#parent.subjectList">
<s:property value="%{subjectName}" />:
<s:textfield id="subject" name="%parent.subject.id}" theme="simple" />
</s:iterator>
</s:iterator>
I have a jsp page with the above code. I have two lists i) studentList, ii) subjectList.
For each student there is a subjectList. Now I have to save the marks. How can I get these values in my action ? I am using Struts2.
Thanx in advance.

This is how the JSP code will look like:
<s:form action="saveaction" >
<s:iterator value="lstBean" id="lstBean" status="outerStat">
<s:textfield value="%{name}" name="lstBean[%{#outerStat.index}].name"/>
<s:textfield value="%{amt}" name="lstBean[%{#outerStat.index}].amt"/>
<s:textfield value="%{id}" name="lstBean[%{#outerStat.index}].id"/>
<s:iterator value="%{lstString}" status="myStat">
<s:textfield name="lstBean[%{#outerStat.index}].lstString[%{#myStat.index}]"/>
</s:iterator>
</s:iterator>
<s:submit value="Click me to submit lstBean"/>
</s:form>
Following is the bean(XBean) whose List is used in the JSP:
public class XBean
{
private ArrayList<String> lstString=new ArrayList<String>();
private String name;
private Double amt;
private Integer id;
//Getters and setters of fields
}
Now you can simply have a field lstBean with setters in your submitting action (saveaction) and hey you are done.

Related

Unable to get struts2 s:select tag value to the action class where action class is called from a s:url [duplicate]

I want to iterate over a list of strings containing names for <s:select> list source, but the HTML output is not as expected : it's the name of the list that is display, not the content.
My Action code:
public class DescriptionTabArchiveAction extends ActionSupport {
private List<String> vegetables = new ArrayList<String>();
private List<String> devices = new ArrayList<String>();
// contain "vegetables" and "devices".
private List<String> selectList = new ArrayList<String>();
#Action("multipleSelect")
public String multipleSelect() {
vegetables.add("tomato");
vegetables.add("potato");
devices.add("mouse");
devices.add("keyboard");
selectList.add("vegetables");
selectList.add("devices");
return SUCCES;
}
// getters and setters
}
JSP:
<s:iterator value="selectList" var="listName">
<s:select list="%{#listName}" />
<!-- I tried with this line too : same behaviour. -->
<%-- <s:select list="#listName" /> --%>
</s:iterator>
What I get (html ouput):
<select name="" id="">
<option value="vegetables">vegetables</option>
</select>
<select name="" id="">
<option value="devices">devices</option>
</select>
What I expect (html output):
<select name="" id="">
<option value="tomato">tomato</option>
<option value="potato">potato</option>
</select>
<select name="" id="">
<option value="mouse">mouse</option>
<option value="keyboard">keyboard</option>
</select>
My Question:
How can I dynamically iterate over a list of string to have multiple <s:select> with different list source?
Use a Map instead of List
private Map<String, List<String>> selectMap = new HashMap<>();
//getter and setter here
#Action("multipleSelect")
public String multipleSelect() {
vegetables.add("tomato");
vegetables.add("potato");
devices.add("mouse");
devices.add("keyboard");
selectMap.put("vegetables", vegetables);
selectMap.put("devices", devices);
return SUCCESS;
}
modify iterator to use a map
<s:iterator value="selectMap">
<s:select list="%{value}" />
...
</s:iterator>

Set color for even rows using <s:set> - Struts2 [duplicate]

This question already has an answer here:
Using <s:iterator> to populate a dynamic arraylist over multiple columns
(1 answer)
Closed 4 years ago.
I want to give dynamic color/style for even rows of the table. Below is my code but it is not giving me required output.
<table>
<s:iterator value="allMonths" status="incr">
<style>
.evenRow{background-color: yellow;}
.oddRow{background-color: orange;}
</style>
<tr>
<s:if test="#incr.count%2 ==0">
<s:set var="clr" value="evenRow"></s:set>
</s:if>
<s:else>
<s:set var="clr" value="oddRow"></s:set>
</s:else>
<td class="%{#clr}">Month:</font> <s:property/></td>
<%-- <td class="%{clr}">Month:</font> <s:property/></td> --%>
<%-- <td class="clr">Month:</font> <s:property/></td> --%>
</tr>
</s:iterator>
</table>
index.jsp
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<body>
<s:form action="clickAction">
<s:textfield name="beanobject.uname" label="Enter Username" /><br>
<s:textfield name="beanobject.age" label="Enter Age" /><br>
<s:textfield name="beanobject.sex" label="sex" /><br>
<s:submit value="Submit" align="center" />
<s:submit value="Clear" align="center" action="clearAction"/>
</s:form>
</body>
</html>
MyAction.java
---imports---
public class MyAction extends ActionSupport{
private MyBean beanobject;
private List<String> allMonths;
//Getters & Setters
public String execute(){
System.out.println("execute");
return SUCCESS;
}
public String click()
{
allMonths = new ArrayList<String>();
allMonths.add("Jan");
allMonths.add("Feb");
allMonths.add("Mar");
return SUCCESS;
}
public String clear(){
return SUCCESS;
}
}
I also tried using "bgcolor" attribute but with no success. What am I missing?
Provided required code. I am just hardcoding values in list in ActionClass
You're assuming JSP understands OGNL; it does not. JSP understands JSP EL.
OGNL is strictly within S2 custom tags, not generic JSP.

how to understad a form is submitted in struts actions

In struts2 actions the injection is used for setting the property values of an action class, so the properties are updated by form fields on the form submission. To discover which form is submitted I create a method calling isFormSubmitted() and in there I check a redundant property created only for this motive. The property is updated in a hidden field. But I find this workout so dirty! I think that there must be a better way to solve this problem.
What I do is:
<s:form name="form1">
<s:hidden name="submit" value="10" />
...other fields go here
</s:form>
in the action class I have getSubmit, setSubmit methods and the following method:
public boolean isFormSubmitted(){
return (submit == 10);
}
Your can call different action methods in your action, not only "execute" method. Just put the parameter with the name like "method:actionMethodName" in your request. Here is example:
public class MyAction extends ActionSupport {
public String execute() {
// Base code
return SUCCESS;
}
public String one() {
// Code one
return SUCCESS;
}
public String two() {
// Code two
return SUCCESS;
}
}
And here is jsp:
<s:form action="MyAction">
<input type="submit" value="Call execute"/>
<input type="submit" name="method:one" value="Call method one"/>
<input type="submit" name="method:two" value="Call method two"/>
</s:>
Or you can do it like this:
<s:form action="MyAction" name="form0">
<!-- call execute-->
</s:>
<s:form action="MyAction" name="form1">
<!-- call method one-->
<input type="hidden" name="method:one"/>
</s:>
<s:form action="MyAction" name="form2">
<!-- call method two-->
<input type="hidden" name="method:two"/>
</s:>
You should use <s:form> tag action attribute to submit to specific action.
<s:form action="action1">
...
</s:form>
<s:form action="action2">
...
</s:form>
See the <s:form> tag documentation: http://struts.apache.org/2.x/docs/form.html.
Update
Then just use separate actions for loading and saving the user.
you should do the submission of the form something like this.
<s:form name="form1">
<s:hidden name="submit" value="10" />
</s:form>
create a java script function
function onclick()
{
document.form1.submit();
}
then create getters & setters in action for hidden field
and in execute method
public String execute()
{
setSubmit(10);
return SUCCESS;
}
Update :
or
<s:a href="your_action"></a>

Map multiple objects in to action class in struts2

I have jsp page with multiple item objects. and gives action to Shop_shopCart.action.
inside action class there are cart object with multiple item objects. How it is possible to directly mapping from jsp to action class with multiple list objects.
Demo classes are given below.
<s:form action="Shop_shopCart.action">
// multiple items in cart object
</form>
class ShoppingAction extends ActionSupport{
Cart cart = new Cart();
//getters and setters
//action methods
String shopCart( ) {
// do some
}
}
class Cart{
List<Item> items = new ArrayList<Item>();
//getters and setters
}
class Item{
String name;
int id;
//getters and setters
}
See the type conversion collection and map support docs.
Nutshell: array or map notation (square brackets with an index or key value inside them) is the easiest way to submit a collection of objects in a form.
this example should help
<s:form action="saveaction" theme="css_xhtml">
<s:textfield name="carlist[0].cartid" label="Cart Id"/>
<s:textfield name="carlist[0].items[0].id" label="Item id"/>
<s:textfield name="carlist[0].items[0].name" label="Item Name"/>
<s:textfield name="carlist[1].cartid" label="Cart Id"/>
<s:textfield name="carlist[1].items[0].id" label="Item id"/>
<s:textfield name="carlist[1].items[0].name" label="Item Name"/>
<s:submit value="Click me to submit Cart List"/>
</s:form>

Struts2 with Nested Iterator dynamic column and rows

I want to display grid in Struts2 which include dynamic rows and columns, it also provide that data should be save in database.
so i have created one list for columns and other map for that values in one bean.
I have included code also.
My bean looks like
public class Annexure{
private List<String> columnsList = new ArrayList<String>(1);
private Map<String,List<String>> columnsValues = new HashMap<String,List<String>>(1);
... setter/getter methods
}
Action class
package com.eks.ias.web.annexure.action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.eks.ias.web.annexure.vo.Annexure;
import com.opensymphony.xwork2.ActionSupport;
public class AnnexureAction extends ActionSupport {
private static final long serialVersionUID = -8819437646232339486L;
private Annexure annexure = new Annexure();
public String execute()throws Exception {
List<String> columnsList = new ArrayList<String>();
columnsList.add("STNNo");
columnsList.add("EAN");
columnsList.add("ArticleCode");
annexure.setColumnsList(columnsList);
annexure.setTotalColumns(3);
annexure.setName("Stock Pending for Inward in SAP");
annexure.setDescription("Details of all merchandise physically received");
annexure.setSiteName("XXX");
Map<String,List<String>> columnsValues = new HashMap<String,List<String>>();
columnsValues.put("0", columnsList);
columnsValues.put("1", columnsList);
annexure.setColumnsValues(columnsValues);
return SUCCESS;
}
public void setAnnexure(Annexure annexure) {
this.annexure = annexure;
}
public Annexure getAnnexure() {
return annexure;
}
}
JSP page
<s:iterator value="annexure.columnsValues" status="rows">
<tr>
<s:iterator value="annexure.columnsList" status="columns">
<td><s:textfield name="annexure.columnsValues[%{#rows.index}][%{#columns.index}]" theme="simple"/></td>
</s:iterator>
</tr>
</s:iterator>
Html code generated looks like
<tr>
<td>
<input type="text" name="annexure.columnsValues[0][0]" value="STNNo"
id="annexure_annexure_columnsValues_0__0_"/>
</td>
<td>
<input type="text" name="annexure.columnsValues[0][1]" value="EAN"
id="annexure_annexure_columnsValues_0__1_"/>
</td>
<td>
<input type="text" name="annexure.columnsValues[0][2]" value="ArticleCode"
id="annexure_annexure_columnsValues_0__2_"/>
</td>
</tr>
when i submit data then i am not able to get those data in action
I am not able to understand the problem if data populate then data should get in action also.
Sorry I don't have enough rep to post a comment, and I'm not sure whether I understand your problem fully. However, there is one thing that I noted with the row index.
shouldn't this
<s:textfield name="annexure.columnsValues[%{#rows.index}][%{#columns.index}]" theme="simple"/>
rather be
<s:textfield name="annexure.columnsValues['%{#rows.index}'][%{#columns.index}]" theme="simple"/>
Note the single quotes. This should set the string key correctly in the map.
Code will be something like this
<s:iterator value="lstBean" id="lstBean" status="outerStat">
<s:textfield value="%{name}" name="lstBean[%{#outerStat.index}].name"/>
<s:textfield value="%{amt}" name="lstBean[%{#outerStat.index}].amt"/>
<s:textfield value="%{id}" name="lstBean[%{#outerStat.index}].id"/>
<s:iterator value="%{lstString}" status="myStat">
<s:textfield name="lstBean[%{#outerStat.index}].lstString[%{#myStat.index}]"/>
</s:iterator>
</s:iterator>
Here's the complete example on Nested Iterator in Struts2

Resources