Use struts2 iterator or initialize arraylist - struts2

I have a List. The user can add n item number and description.
He will add first and then to add second will press add more button .
I am giving a call to action class storing the data in array and redirecting back to the page to get the next record.
When I am using the iterator the text boxes are getting added again.
If I dont use iterator my arraylist is getting initailized everytime I visit the action class.
I cannot make it static.It will helpful if anyone can help me either to not initailize the arraylist everytime or use iterator and not repeat the textfields.
<table>
<tr align="center">
<s:iterator value="preAdviceDetailsDO" id="preAdviceDetailsDO" status="outerStat">
<s:if test="#outerStat.may be some useful word like even odd first == true">
<td style="background: #CCCCCC">
<s:textfield value="%{itemNumber}" name="preAdviceDetailsDO[%{#outerStat.index}].itemNumber" onblur="checkBarcode();"/>
</td>
<td style="background: #CCCCCC">
<s:textfield value="%{itemDescription}" name="preAdviceDetailsDO[%{#outerStat.index}].itemDescription"/>
</td>
</s:if>
</s:iterator>
</tr>
</table>
<input type="button" value="Add More" onclick="addRow()" />

Thanks Dave Newton for editing. MohanaRao SV, I found the solution on it actually its a tweak.The problem I was facing in the above code was :
When the user see the form for the first time he will see two text field.He will enter the details and to add another record he will press add button. This time the arraylist is incremented. So the text fields on the form will increase to four.That is two earlier one and the new two text fields.And so on...
So now what I did is in the if condition I am checking if the index is last then I am displaying the fields and in the else part I am writing the same code for adding text field but I have set the css property display:none.
If I dont write the else part the arraylist is properly incremented but the details in the arraylist are not persisted.
So now only the required text fields are displayed.

Related

Submit cell data from table in thymeleaf template

I have following code snippet:
<table class="table">
<thead>
<tr>
<th>Type</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr th:if="${list.isEmpty()}">
<td colspan="2">No Media Available</td>
</tr>
<tr th:each="media : ${list}">
<form th:action="#{/pages}" method="post">
<td><span th:text="${media.getType()}">Type</span></td>
<td><span th:text="${media.getTitle()}">Title</span></td>
<td><input name="submit" type="submit" value="add"/></td>
</form>
</tr>
</tbody>
Now to my question: How can I submit the content from the rows?
Another question: Is my approach to creating a form for each row makes sense at all?
If you want to have user-entered data sent to the server, then replace this:
<td><span th:text="${media.getTitle()}">Title</span></td>
with this:
<td><input name="title" th:value="${media.title}"></td>
Assuming the ${media.title} evaluates to "War and Peace" This will use the name field to submit data as title=War and Peace (with URL encoding for the spaces in the title: War%20and%20Peace).
Note the use of ${media.title} instead of ${media.getTitle()}. You should be able to refer to the field name, rather than the get method. Thymeleaf will use the getFoo() method for a field called foo, based on naming conventions.
There are other approaches, for example:
use a visible input field, but styled to look and behave like regular text (cannot be edited, and has no surrounding box).
use JavaScript to replace the default form submission process, and read your row data from the vanilla table, without a form - instead, with a button using a click event handler.
If you create one form for the entire table, you're going to get all the table's data submitted at once (arrays of title data, and so on).
Alternatively, if you have one form per table row, you have to consider what happens if a user edits multiple rows of data before hitting submit for one row. All those other unsent changes will potentially be lost.
A common solution is to avoid this problem, by forcing users to update records one at a time: The table does not use forms. Each row's button click opens a new modal dialog containing the data for only that one row (in a form) - which can then be edited and submitted.

Getting table value from view to controller

I have a domain class, Report, with a referenced child class, prompt.
One the edit Report page you are allowed to reorder the order of prompts in a table. Then when the user goes to run the report, on that page the prompts are in said order.
The table on the Report edit.gsp page uses some jQuery to allow drag and dropping of the row, and it updates the display order number, but only on the UI side, nothing is going back to the database yet.
I would like to be able to pass this new order back to my update command, but cannot figure out how to grab the table row data for the life of me.
When searching almost all of the results are how to get data from the controller to the view, not vice-versa.
Here is the snippet of table code
<table id="prompts">
<thead>
<tr>
<th>${message(code: 'prompt.name.label', default: 'Name')}</th>
<th>${message(code: 'prompt.description.label', default: 'Description')}</th>
<th>${message(code: 'prompt.required.label', default: 'Required')}</th>
<th>${message(code: 'prompt.displaySeqno.label', default: 'Display Order')}</th>
</tr>
</thead>
<tbody>
<g:each in="${reportInstance.prompts.sort{it.displaySeqno}}" status="i" var="prompt">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}" onclick='window.location = "${createLink(controller: "prompt", action: "edit", id: prompt.id)}"'>
<td>${fieldValue(bean: prompt, field: "name")}</td>
<td>${fieldValue(bean: prompt, field: "description")}</td>
<td>${prompt.required}</td>
<td class="displaySeqno">${prompt.displaySeqno}</td>
</tr>
</g:each>
</tbody>
</table>
And then in the controller, I tried
params.list('displaySeqno')
But it would just return an empty array.
How can I get the value of the displaySeqno from within my controller class?
Thanks.
This is one of those time (which happens a lot) where a fundamental understanding of how HTTP / Java EE works would allow you to solve your problem very easily. Forms or no forms, you have to pass a value into the request that goes to the server for it to end up on the server. How is this
<td class="displaySeqno">${prompt.displaySeqno}</td>
ever going to get to the server, form or no form? The answer is, it is not. Assuming a typical form post you would need to store the value in a hidden field
<input type="hidden" name="displaySeqno" value="${prompt.displaySeqno}" />
Then it would make it to the server. If you're processing with Ajax of some sort, you would need to pass it in as a parameter via the API. Assuming jQuery, for example:
pseudo code ahead:
var params = $('#youFormId').serialize();
$.post('some/url/to/post/to', params, function(data) {
});
Bottom line is, if you want to pass something to the server, you have to provide the means for that to happen.

struts2 <s:iterator> with <s:param> not working

I am displaying the list values with tag.At the same time i want to provide a hyperlink for the displaying values to provide action for the displaying value.I am using <s:param> for that.but the values are not passing.I am writing like below
<s:iterator status="stat" value="transactionList">
<s:url id="open" action="openTransaction">
<s:param name="transactionCode" value="<s:property value='monthName'/>"/>
</s:url>
<tr class="gradeB">
<td>
<s:a href="%{open}"><s:property value='transactionCode'/></s:a>
</td>
<td><s:property value="monthName"/></td>
<td><s:property value="transactionDesc"/></td>
</tr>
</s:iterator>
Now the transactionCode property is displaying with hyperlinks and by clicking on that the action is forwarding to openTransaction method.but the value i passed with <s:param> is not going,it is giving null. In iteration for that particular transaction code i want to pass that particular transaction code only. In struts 1.x I used display tag table decorator for this purpose, it takes the current row object.Here also i want to pass the current row values to the action. Please help me.
If you want to use <s:property> tag to put a param inside an url you have to do it like that:
<s:url ...>
<s:param name="foo"><s:property value="bar"/></s:param>
</s:url>
The documentation of <s:param> explains the difference between using this way of putting a param and your way.
Note: When you declare the param tag, the value can be defined in either a value attribute or as text between the start and end tag. Struts behaves a bit different according to these two situations. This is best illustrated using an example:
<param name="color">blue</param> <-- (A) -->
<param name="color" value="blue"/> <-- (B) -->
In the first situation (A) the value would be evaluated to the stack as a java.lang.String object. And in situation (B) the value would be evaluated to the stack as a java.lang.Object object.
For more information see WW-808.
Edit: Also remember that if you are using 2.1.x or higher, the id attribute of <s:url> is deprecated and it has been replaced with var. You can read it here.
<c:url var="search" value="/image/search.action">
<c:forEach items="${filtersMap}" var="map">
<c:param name="filtersMap.${map.key}" value="${map.value}"/>
</c:forEach>
${filtersMap} is a map param from action

Struts2 How to create a table by iterating a list such that each row has a radio button?

I am trying to create a table to display some data using iterator over my list from action class. Each row has the properties of each object in the list.
<table class="TableA" cellpadding="5px" border="1">
<tr class="even">
<th></th>
<th>Col1</th>
<th>Col2</th>
</tr>
<s:iterator value="objectList" status="obj">
<tr
class="<s:if test="#obj.odd == true ">odd</s:if><s:else>even</s:else>">
<td></td>
<td><s:property value="objId" /></td>
<td><s:property value="objValue" /></td>
</tr>
</s:iterator>
I need a radio button in first cell of every row so that a row can be selected for edition or deletion.
I know this can be done using <input type="radio" ...>. But I need to use struts2's radio tag. But problem using this tag is that it generates a row for every radio tag (see here).
Is it possible ? If yes then how ?
I think the following syntax will be better for you as you want to select each row with radio button
<s:radio theme="simple" name="object_radio" list="#{objId:objId}"/>
This way you wont need the objId column too
This syntax will submit objId as the value of selected radio button.You can modify the syntax to change the display property of the radio button or make it blank
anu, your answer helped me a lot.
Also this link was of great help for me:
http://struts.apache.org/2.0.14/docs/how-do-i-render-a-single-radio-button.html
What I needed was a table where two of the columns were radio buttons, but each column was an independent group. Furthermore I did not want to show the key as the label/value for each radio button, since that information was displayed in the other columns. My rows were built iterating over a hashmap, where the key of the hashmap was the radio button value.
<s:iterator value="myHashMap">
<tr>
<td><s:radio name="selectedRadioValueFirstColumn" list="#{key:''}"/></td>
<td><s:radio name="selectedRadioValueSecondColumn" list="#{key:''}"/></td>
<%--....... (my other columns) .... --%>
<tr>
So I am setting the option value as the key of the hashmap, and the selected value will be stored in the string property "selectedRadioValueFirstColumn" and "selectedRadioValueSecondColumn".
Kaillash:
if i understand your requirements completely all you mean to say that when page getting displayed with struts2 radio button struts2 is automatically creating a row for each radio button.
if this is the case than that is default struts2 functionality,struts2 operates on template theme and the default theme (xhtml) will automatically generate some HTML markup for each struts2 tag.
if you want struts2 tags not to generate any extra markup use the theme as simple.it can be done per tag basis something like this
<s:radio key="personBean.gender" list="genders" theme="simple" />
or you can also set theme on the page basis..
create struts2.properties file in the root and put the following entry
struts.ui.theme=simple
i hope this will help you

struts2: problem in assigning a variable value to checkbox

I am working on struts2. In my jsp page I want to assign the value of a string variable to a checkbox (when it is checked by user). I tried it many times like -
<% String code = "decompose"; %>
First example:
<tr><td>
<s:checkbox name="codeCkBox" fieldValue="%{‘code’}" onclick="submit()"/>
</td></tr>
Second example:
<tr><td>
<s:checkbox name="codeCkBox" value="%{‘code’}" onclick="submit()"/>
</td></tr>
Third example:
<tr><td>
<s:set name="setCkBoxValue" value="%{‘code’}"/>
<s:checkbox name="codeCkBox" fieldValue="# setCkBoxValue" onclick="submit()"/>
</td></tr>
But everytime when I tried to get this value by checkbox name it returns variable name i.e “code”.
Looking for a solution.
Thanks in advance.
Have you tried doing ${code} instead of ${'code'}?
did u include your struts directive? i ask because its only showing 'code' which could mean its ignoring the struts
<tr><td> <s:checkbox name="codeCkBox" value="%{#code}"
onclick="submit()"/> </td></tr>
try the above code. since code is the JSP variable therefore it should be accessed with a # in front of its name rather than with a quote. Hope this helps

Resources