I have as:iterator which is iterating a property list, For each item in the list has the properties key,value and category.On the basis of category,I need to populate the values to divs defined inside the iterator. I am using jquery tabs. Here the iterator not iterating properly.Please look the code it is easy to understand
<div id="tabs">
<ul>
<li><a href="#channel">Channel</a></li>
<li><a href="#connection">Connection</a></li>
</ul>
<s:iterator value="property" status="rowstatus">
<div id="channel">
<s:if test="(property[#rowstatus.index].category=='Channel')">
<table>
<tr><s:hidden name="property[%{#rowstatus.index}].key" />
<td><s:label value="%{property[#rowstatus.index].key}"> </s:label></td>
<td> <s:textfield name="property[%{#rowstatus.index}].value">
</s:textfield>
</td>
</tr>
</table>
</s:if>
</div>
<div id="connection">
<s:if test="(property[#rowstatus.index].category=='Connection')">
<table>
<tr><s:hidden name="property[%{#rowstatus.index}].key" />
<td><s:label value="%{property[#rowstatus.index].key}"></s:label></td>
<td> <s:textfield name="property[%{#rowstatus.index}].value">
</s:textfield>
</td>
</tr>
</table>
</s:if>
</div>
</s:iterator>
</div>
Change JSP
<div id="tabs">
<ul>
<li><a href="#channel">Channel</a></li>
<li><a href="#connection">Connection</a></li>
</ul>
<div id="channel">
<table>
<s:subset source="property" decider="channelDecider">
<s:iterator var="channel">
<tr><s:hidden name="property[%{property.indexOf(#channel)}].key" />
<td><s:label value="%{#channel.key}"> </s:label></td>
<td> <s:textfield name="property[%{property.indexOf(#channel)}].value" value="%{#channel.value}">
</s:textfield>
</td>
</tr>
</s:iterator>
</s:subset>
</table>
</div>
<div id="connection">
<table>
<s:subset source="property" decider="connectionDecider">
<s:iterator var="connection">
<tr><s:hidden name="property[%{property.indexOf(#connection)}].key" />
<td><s:label value="%{#connection.key}"> </s:label></td>
<td> <s:textfield name="property[%{property.indexOf(#connection)}].value" value="%{#connection.value}">
</s:textfield>
</td>
</tr>
</s:iterator>
</s:subset>
</table>
</div>
</div>
Create deciders
public Decider getChannelDecider() {
return new Decider() {
public boolean decide(Object element) throws Exception {
return ((MyElement)element).category.equals("Channel");
}
};
}
public Decider getConnectionDecider() {
return new Decider() {
public boolean decide(Object element) throws Exception {
return ((MyElement)element).category.equals("Connection");
}
};
}
Note, MyElement
is a list element type that has corresponding properties.
The iterator works fine.
You're creating a div for each item in the collection, not each group of like items.
While <s:subset>
will work, as an alternative, I'd propose a simpler, less-S2-centric solution.
Additional MyElement
code:
public class MyElement {
public boolean isChannel() { return category.equals("Channel"); }
public boolean isConnection() { return category.equals("Connection"); }
}
I'm not a fan of using strings to indicate types.
There are a number of ways the list could be broken apart; manually in the action, which is easy and quick; via a utility class, nice if you need this functionality in several places; etc.
A possible utility class:
public class MyElementSplitter {
// Also getters for both of these; possibly wrapped with an immutable collection.
private List<MyElement> channels = new ArrayList<>();
private List<MyElement> connections = new ArrayList<>();
public MyElementSplitter(List<MyElement> elements) {
for (MyElement element: elements) {
if (element.isChannel()) {
channels.add(element);
} else if (element.isConnection()) {
connections.add(element);
}
}
}
}
Notes: this could be enhanced significantly, especially if you have additional types. If the types aren't determined by strings, you can play a lot of nice games with making the code general-purpose to expose other types as well.
In the action you categorize the elements and expose the splitter to the view:
private MyElementSplitter elements; // And getter.
public String execute() {
// And any additional processing, list retrieval, etc.
elements = new MyElementSplitter(allElements);
return SUCCESS;
}
Then in the view:
<div id="channel">
<s:iterator value="elements.channels" status="stat">
<table>
<tr>
<s:hidden name="property[%{#stat.index}].key" />
<td><s:label value="%{property[#stat.index].key}" /></td>
<td><s:textfield name="property[%{#stat.index}].value" /></td>
</tr>
</table>
</s:iterator>
</div>
<div id="connection">
<s:iterator value="elements.connections" status="stat">
<table>
<tr>
<s:hidden name="property[%{#stat.index}].key" />
<td><s:label value="%{property[#stat.index].key}" /></td>
<td><s:textfield name="property[%{#stat.index}].value" /></td>
</tr>
</table>
</s:iterator>
</div>
If these sections will always be identical then I'd wrap them up in a JSP-based custom tag.
That would leave us with the following:
<div id="tabs">
<ul>
<li><a href="#channel">Channel</a></li>
<li><a href="#connection">Connection</a></li>
</ul>
<app:elementTab id="channel" values="elements.channels" />
<app:elementTab id="connection" values="elements.connections" />
</div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.