Struts 2 List of List access - struts2

I wonder if someone can help.
Background Architecture:
I have an application which contians many areas which have many specific questions, where these questions contian progress
So at a high-level view there can be many applications. A user is associated to maybe many applications.
So I have a list of applications and I can quite easliy iterate my way through and get its relevant details. But when it comes to accessing each specific area to get question progress for some reason it does not work out form me.
So here is logic I want:
for the applications
display its details
for each area(applicaitonId)
display each its completion progress
so to translate to struts I have this
<s:iterator id="app" value="appList" status="row">
<s:iterator id="qsp" value="questionProgessList[%{#row.index}]" status="status">
so applist is the list of all applications with its own getter/setter && questionSetProgress is defined by:
List<ApplicationQuestionSetProgress> getQuestionProgressList(final int index)
or
List> getQuestionProgressList()
So trying in many ways to access the list has proved futile I have tried:
<s:iterator id="qsp" value="questionProgessList">
<s:property />
</s:iterator>
with this:
List<List<ApplicationQuestionSetProgress>> getQuestionProgressList()
but no joy
I've also tried using the iterator index to call the method but it just does not work out.
List<ApplicationQuestionSetProgress> getQuestionProgressList(final int index)
i.e.
<s:iterator id="qsp" value="questionProgessList[%{#row.index}]" status="status"> or <s:iterator id="qsp" value="questionProgessList(%{#row.index})" status="status">
any hints or tips??
TIA

Considering you have something like
List<ApplicationQuestionSetProgress> getQuestionProgressList(final int index)
Use this
<s:iterator var="qsp" value="questionProgessList[#row.index]" status="status">

You mentioned the following method:
List<List<ApplicationQuestionSetProgress>> getQuestionProgressList()
But you mentioned that the action needed to get a list of "applications" where each contained among its properties a list of "areas".
As such I would name that method:
List Applications getApplications(){
return this.applications;
}
The form of a JSP to extract all properties would be:
<s:iterator value="applications">
<s:property value=applicationsProperty1"/>
<s:property value="applicationsProperty2"/>
...
<s:iterator value="areas">
<s:property value="areasProperty1"/>
<s:property value="areasProperty2"/>
...
<s:iterator value="progress">
<s:property value="progressProperty1"/>
<s:property value="progressProperty2"/>
...
</s:iterator>
</s:iterator>
</s:iterator>

Related

Numbers not formatted properly in Struts 2

I am using following syntax to display a value in a proper number format, e.g. 1,250.00.
<s:property value="%{getText('{0,number,#,##0.00}',#plan.amount)}" />
However, it is not working. The plan is an object with a property amount.
First of all, if you want to display multiple values from a list, you need an iterator;
second, if plan is a list in the action with a getter method
public List<Something> getPlan() { return plan; }
then you don't have to put the # ahead of the variable.
The right code for your case would be:
<s:iterator value="plan">
<s:property value="getText('{0,number,#,##0.00}',{amount})" />
</s:iterator>
There's a related Q&A on the topic.
EDIT
Since you have
<s:iterator value="list" var="plan" status="status">
<div class="values">
$ <s:property value="%{getText('{0,number,#,##0.00}',#plan.amount)}"/>
</div>
</s:iterator>
Then it should be:
<s:iterator value="list">
<s:property value="getText('{0,number,#,##0.00}',{amount})" />
</s:iterator>
If the value is printed like 1250.00 then it's not formatted properly. The method getText() has many overloaded methods and which method is used is determined by the parameter's types and count.
To pass arguments to the getText() method you can use OGNL list construction {}. And the arguments should be listed as single values, not "list of object". Perfectly it should be list of Double with one element inside the list.
<s:set var="amount" value="%{1250.0}"/>
<s:property value="%{getText('{0,number,#,##0.00}',{#amount})}" />

How to display pre-checked checkboxes inside iterator in Struts 2

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>

Struts 2 s:iterator: How to avoid name clashes?

As far as I see, s:iterator always pushes the current item into the OGNL Value Stack, even if I use the var attribute. This means that all the members of the current item become top-level OGNL variables inside the loop, potentially hiding the properties of the Action:
<s:property value="owner" /> <%-- From the Action --%>
<s:iterator value="projects" var="project">
<s:property value="#project.owner" /> <%-- From the project, obviously --%>
<s:property value="owner" /> <%-- Ops, also from the project! --%>
</s:iterator>
<%-- (Fun(?) fact: #project.owner is still accessible here) --%>
The objects we iterate through (often with multiple levels of nesting) has many properties, and their number can grow later. The danger of accidentally hiding properties is very real, and worse, adding properties to JavaBeans can break pages that were once working.
Am I missing something here? How do you iterate through complex objects with Struts 2 + JSP?

struts2 iterator tag - iterating over a collection of collections

I am new to struts 2 and am losing my mind over iterating a collection of collections in my JSP using the iterator tag.
My action class exposes a List (parent) which in turn contains 4 more lists (children). Each child list contains 5 domain objects (e.g. User).
In my JSP, i need to display the User.Name after iterating over the collections. I am able to iterate over the parent collection but cannot get to the child lists. They are anonymous lists and are not exposed by a specific name (i.e. a getter is not available).
<s:iterator value="usrList" var="refParent">
<ul>
<s:iterator value="#refParent.columns" var="usr">
<li>
<s:property value="#usr.Name"/>
</li>
</s:iterator>
</ul>
</s:iterator>
The outer iterator results in 4 <ul> tags but each of those tags are empty i.e. none of the <li> tags are displayed.
All the examples that i see are accessing specific named Collections (e.g. User.PhoneList) but none of them seem to demonstrate this particular behavior.
Any help is greatly appreciated
I think i finally figured it out from one of the Iterator-tag examples (thanks to Umesh and Quaternion). I totally missed that one and did not read through the entire example using top.
<s:iterator value="usrList">
<ul>
<s:iterator value="top">
<li>
<s:property value="Name"/>
</li>
</s:iterator>
</ul>
</s:iterator>
Please try this example from this link
<table>
<s:iterator value="allCities" id="cities">
<s:iterator value="#city.phoneNumbers" id="number">
<tr>
<td>
<!-- Accessing the city name through the city variable -->
<s:property value="#city.name" />
</td>
<td>
<!-- Accessing the objects inside the phone number object through the number variable -->
<s:property value="#number.prefix" />
</td>
<td>
<s:property value="#number.rate" />
</td>
</tr>
</s:iterator>
</s:iterator>
</table>
Struts2 Iterator tag a simple enough and work in a very simple manner.So if you have Collection of Collection or what ever structure think how you will iterator them in a simple Java application , same will apply for the S2 iterator tag, but at same time it will give you more flexibility as well configurations.
In Short you need nested iterator tag.When S2 iterator tag iterate objects it will place current object on the top of value stack and you can easily access that tag in your JSP code.
Since in your code Top level object will be a Collection you need to iterate that again like
<s:iterator value="firstCollection">
<s:iterator value="firstCollection>
/ do what you want here
</iterator>
Since while iterating object will be at top of stack you can refer to that tag directly without any reference.
i Suggest you to have look at following official documents
iterator
iterator-tag-examples

Struts 2: s:if inside s:iterator not working

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} />

Resources