I am new to Struts 2 , please help me with the below scenario
I have a table in Jsp using struts2 tag , All I Want to do is to retrieve the selected(checked) table row's value in the action class.
Please let me know how to achieve it .
<s:iterator value="listOfDtos" status="stat">
<tr>
<td><s:checkbox name="delete" value="select" /></td>
<td><s:property value="FirstName"/></td>
<td><s:property value="LastName"/></td>
</tr>
</s:iterator>
<s:submit id="delete" value="delete"/>
}
"listOfDtos" is an array list od dto and is set in the action like the below
ActionContext.getContext().getValueStack().set("listOfDtos", listOfDtos);
Now when the user selects any row to be deleted I want to be able to first of all retrieve this list of dtos in the Action and iterate them to check which of the dtos have the attribute "select" set to true. select" is an attribute of type String in the dto.
How can this be done? Also how will the "listOfDtos" be made available in the Action.
I am not sure i have understood your question properly.but here are few inputs to start with.
There is no need to do ActionContext.getContext().getValueStack().set("listOfDtos", listOfDtos); as this will bind your action class with framework tightly.I suggest you to create a property in your action class with name listOfDtos as ArrayList and provides its getter and setters, framework will place your array-list in the value-stack for you.
You need to provide some unique values to your check-box based on which you can check in your action class which id has been selected as you can perform any desired operation on the ArrayList based on the ID.
Related
I need to iterate through List<String>, each element has s:checkbox.
I have defined one list in Action layer to keep selected elements.
Using my code I can submit my form and capture selected values in action layer. But, some of the checkboxes must be pre-checked. I cannot display pre- checked status when loading the page.
Value1 contains list of String objects.
functionCheckBoxList - The list I have defined to keep checked element
While loading, I added some element to functionCheckBoxList that belongs to Value1.
But still does not show pre-checked status in the page.
<s:iterator value="value1" var ="functionName">
<s:checkbox fieldValue="%{#functionName}" name="functionCheckBoxList"
value="%{#functionName}" theme="simple" >
</s:checkbox>
</s:iterator>
Note: I know how to do it using s:checkboxlist but can't here as I need special format in the iteration.
i could find a solution for my problem, i would like to share it with everyone.
<s:iterator value="value1" var ="functionName">
<s:checkbox fieldValue="%{#functionName}" name="functionCheckBoxList"
value="%{#functionName in functionCheckBoxList}" theme="simple" >
</s:checkbox>
</s:iterator>
Can I preserve object across actions in Struts2 without using session?
I'm working on a Struts2 project and curious if there are some ways to preserving object
value once an action is ended.
What I'm trying to do is:
Calling an action to read from an uploaded file and prepare its contents as a list of objects.
Then I display the list as an example for the user.
Then the user can click on a submit button to call an action to process the list which is created from the first action.
Usually the list would be lost once the action is end. So, I have to store the list as a session, but I think it should have some better methods to achieve the I'm working on.
If you want to preserve data across requests the session is the normal mechanism for doing so.
If you don't use the session you'd need to essentially duplicate its functionality to maintain the data associated with the current user/conversation.
If you need to preserve the List, then you have to use the Session.
But if you (if I've understood your problem) just need to handle the List through
ActionOne (that creates the List) ->
JSPOne (thast shows the List to the user) ->
ACtionTwo (that receives the List from JSPOne and does some business with it)
, without having to worry about the fact that the user can change the List client-side (for example manipulating the web page with FireBug), then you don't need the session.
You just need the List object to be declared on ActionOne and ActionTwo (with getters and setters, at least the getter on ActionOne and at least the setter on ActionTwo), and to include List name and index on name attribute of JSP tags.
If you just draw it (like with <s:property/> tag), instad of using some tag that will post the value, like <s:textfield />, then just use an <s:hidden /> to post te value.
For example, if you have:
List<MyObject> myList //with getters and setters
and assuming that MyObject has id and value fields (with getters and setters),
in JSP instead of
<s:iterator value="myList" >
<s:property value="id"/>
<s:textfield name="value"/>
</s:iterator>
use
<s:iterator value="myList" status="ctr" >
<s:hidden name="myList[#ctr.index].id" value="id"/>
<s:property value="id"/> <!-- no need here, you won't post this -->
<s:textfield name="myList[#ctr.index].value" value="value" />
</s:iterator>
You will eventually validate a List like this throught the Visitor Validator (somewhewre in the future after all the rest is done :)
Enjoy
I have a question regarding struts 2 and s:if tags. As per described on the documentation of s:if the following example was supposed to work:
...
<s:iterator value="questao.alternativas" status="alternativa">
<tr>
<td>
<s:if test="#alternativa.correta == true">Correta!</s:if>
</td>
</tr>
</s:iterator>
...
But this is not working on my case, could you please help? More details:
questao.alternativas is found on the action and it works fine, all "alternativas" are "iterated"!
the getCorreta() method is never call on the example described above.
when using the value true is printed.
Any ideas??
Thanks!
Specifying status in iterator tag will push an instance of IteratorStatus on value stack. You need to consult the documentation of IteratorStatus for valid attributes to use and correta is not a valid attribute. If you want to access the current iteration's object specify a var attribute instead.
Edit for comment:
That's right as Quaternion said you don't need to specify var for accessing current iteration's object. It's already on top of value stack.
Quickly looking at your code I see that you are referencing the status in your conditional(if) statement. Your conditional should directly reference the accessor method of the object in the list your are iterating through, for example:
<s:iterator value="questao.alternativas" status="stat">
<tr>
<td>
// If correta is a boolean value, there is not need to use an
// == operator at all
<s:if test="%{correta}">
Correta!
</s:if>
</td>
</tr>
</s:iterator>
When an iterator traverses a supplied list, assuming questao.alternativas is a list of objects with accessor methods, you directly reference the methods inside your iterator.
The status in an iterator gives you access to the iterator's position. For example, if you want to determine if your loop is at the last element in the list to perform something special you would do something like:
<s:if test="%{#stat.last}">--- END OF LIST ---</s:if>
Or to get the indexed position of the current element in your array or list:
<s:property value=%{#stat.index} />
With struts2,it will automaticlly create the bean in our action through the ognl,it is easy to use it when we create a new object,for example,in user register page,we build a form for use to fill their information,and in the action we get the properties populated bean,we can save it directly(maybe need some validation),it is so easy.
But how about update a existed object in the db?
We can build a form,(prepopulate the properties that can be updated in the page),when user make some modifination,we update it.
But the bean we get in the action is created by struts2(we call this bean as bean_struts2),and what we want to updated is in the db(we call this bean bean_db).
Now the problem is how to copy the modifinations of the bean_struts2 to bean_db?
For a non-nested object,we can iterator all the properties of the bean_struts2,and set it to bean_db.
For example:
bean_db.setPassword(bean_struts2.getPassword());
.....
But it does not so easy when the bean to be updated is a nested object.
In my case,these are the entities:
class Task{
Object non_updatedProperty;
List<TaskSteps> steps;
List<User> managers;
User publisher;
}
class User{
id,name;
}
class TaskStep{
id,name;
List<Operator> operators;
TaskStepStatus status;
}
enum TaskStepStatus{
ongoing,completed.
}
class Operator{
id,name;
}
The bean to be updated is the "Task" object.
In the page:
<s:form action="task_update" namespace="/common" cssStyle="width:95%">
<s:textfield value="%{task.id}" cssStyle="display:none" name="task.id"></s:textfield>
<s:textfield value="%{task.publisher.name}" readonly="true" label="Publisher"></s:textfield>
<s:textfield name="task.name" value="%{task.name}" label="Task Name"/>
<table>
<caption align="left">Steps</caption>
<tr>
<th>Step Name</th>
<th>Operators</th>
<th>Status</th>
<th>Set order</th>
<th><span id="addStep" style="cursor:pointer" >Add a step</span></th>
</tr>
<s:iterator value="task.steps">
<tr class="step">
<td>
<s:textfield name="task.steps[0].name" value="%{#this.name}" theme="simple"/>
<s:textfield name="task.steps[0].id" value="%{#this.id}" theme="simple" cssStyle="display:none"/>
</td>
<td><s:textfield name="task.steps[0].end" value="%{#this.end}" theme="simple"/></td>
<td>
<s:select list="allOpIndb" listKey="id" listValue="name" value="%{#this.operator.{id}}"
name="task.steps[0].operator.id" multiple="true" theme="simple" id="a">
</s:select>
</td>
<td>
<s:select list="#com.zjswkj.location.entity.TaskStepStatus#values()" theme="simple"
name="task.steps[0].status" listValue="cnValue" value="%{#this.status}" id="b"/>
</td>
<td>
<span class="up">up</span>
<span class="down">down</span>
<span class="del">del</span>
</td>
<td></td>
</tr>
</s:iterator>
</table>
</s:form>
Through struts2,I can get the bean_strtus2(Task),its id is the same as the bean_db.
I can easily copy its non-nested propertis to the bean_db. but how about the propertis of its TaskSteps and the operators of its TaskSteps.
Just use :
task_db.setTaskSteps(task_struts2.getTaskSteps());??
Of course not,this may cause some new TaskStep with the same name persisited to the db.
Also,there are some properties can not be updated,for example,the Task's "non_updatedProperty" property can not be updated,it can only be set when the task are created.
So in the update form,I did not provide a UI to update this property,so if we call:
task_db.setNon_updateProperty(task_struts2.getNon_updateProperty);
will miss the exist property,beacuse
task_struts2.getNon_updateProperty==null; !!!
I just wonder if there are some good ideas to handle these types of update?
I am not exactly sure if you guys know what I am meaning,but I have try my best to express it.
If there are more questions,I can update it still.
About the question of transferring efficiently informations from a "structure" (a nested set of beans) managed at the presentation layer (so to say here, populated by Struts2) to another "structure" at the service or the "DB" level, I suggest to have a serious look at http://dozer.sourceforge.net
About the problem of passing on value modification of a "structure" from then to the DB through the presentation layer, it highly depends on the way you map your DB tables (I suppose you're using some kind of relational database) to objects.
When using Hibernate for instance, it is sometimes possible to simply create POJO straight out from your presentation beans, and tell hibernate to "store it"; Hibernate would create / update / delete appropriate records in the table according to the passed structure.
Although most of the times there is no silver bullet, and some kind of structure comparison between the structure mapped from DB content and the structure mapped from the presentation layer (through dozer for example) is required to guess what has to be added, modified or deleted.
In my struts2 application I have an iterator and a list with objects like -
<s:iterator value="listOfObjects">
<tr>
<td><s:property value="item" /></td>
<td><s:property value="category" /></td>
<td><s:property value="quantity" /></td>
<td><s:property value="brand" /></td>
<td><s:checkbox name="deleteRow" onclick="submit()"/></td>
</tr>
</s:iterator>
The above creates a table with a checkbox in the end column of each row. Now, Onclick any checkbox I want to set the values of corresponding row (only) in my bean class. I tried a lot but I am getting values of each row rather that values of only that particuler row whose checkbox user has clicked. Is it possible. If yes then please help. Thanks in advance.
If the value of the deleteRow checkbox is good enough (based on the toString method of your object), then you should be able to just create a deleteRow property in your Action class with a setter method and parse it out.
I suppose you could set a value expression on the deleteRow checkbox, either using the toString() of the current object, or putting some kind of formatted list (comma separated or something) of the values in there by hand. If you gave the s:iterator an id, you could reference that in the value attribute of the s:checkbox.