array as hidden variable - java

can array be used as hidden variable on jsp.....like I have a form i.e a simple java
class,I want it to be as hidden variable can I do it..
Thanks in advance

HTTP request parameters can only be strings. So you either have to convert it to a single string (maybe a commaseparated string?), but you need to convert it back yourself, or you have to use multiple hidden input values (all with the same name), which is generally a much better solution. In plain JSP/Servlet you can get them back using HttpServletRequest#getParameterValues() and Struts is smart enough to see that.
<logic:iterate id="foo" name="bean" property="arrayOrList">
<html:hidden name="paramName" property="propertyName" indexed="true" />
</logic:iterate>

just write multiple hidden elements with the same name en different values. struts will see that it is supposed to be an array

agree with BalusC in addition to that
you can try following
adding [] at the end of the name , keeping name and property same and adding multiple values.
for example
<html:hidden name="name1[]" property="status" value="value1" />
<html:hidden name="name1[]" property="status" value="value2" />
<html:hidden name="name1[]" property="status" value="value3" />

Related

Mixing index and unindexed list elements in a form?

I have a handler like
#RequestMapping(...)
public String get(#RequestParam List<Cmd> rows) {...}
And I use Spring forms tags to generate the inputs. So the JSP code
<c:forEach var="i" begin="0" end="${fn:length(rows)}" >
<form:input path="rows[${i}].name" />
...
</c:forEach>
generates
<input name="rows[0].name" value="...' />
This is all good, but I also want to allow the user to add rows dynamically, so template inputs needs to be written. However, neither name="rows.name" nor name="rows[].name" works, so I have to write code to generate indexes, which is annoying.
Am I missing something here? Is there any better way to do this?
Edit:
BTW, I tried to use Javascript to generate name="rows[n].name" dynamically, but it becomes a problem if the user deletes a row in the middle. A code to rewrite all the indexes seems to be unreasonable.
You can use Javascript to insert new input. Spring generates following
<input name="rows[0].name" value="...' />
Now you want user to enter new value then your Javascript code should generate following line
<input name="rows[1].name" value="...' />
and suppose user wants one more value then,
<input name="rows[2].name" value="...' />
Remember to handle index while generating inputs using Javascript.
try this,
<form:input path="${rows[i].name}" />
instead of
<form:input path="rows[${i}].name" />

How to bind a comma separated string to a Java collection (List) in Spring form?

I'm stuck in a situation where I've an input element in a JSP where user enters tags. E.g. java, foo, bar, anotherTag..etc
<c:url var="saveUrl" value="/create" />
<form:form modelAttribute="myAttribute" method="POST"
action="${saveUrl}">
<form:input path="myTitle" />
<form:textarea path="myPost" />
<form:input type="text" id="tagInput"path="???" />
<input type="submit" value="create" />
</form:form>
Now in my domain model corresponding to this input is a
private List<Tag> listOfTags
How to bind a csv to a List. If I enter listOfTags in the path(which is wrong for obvious reasons), I get incorrect binding exception.
How do I convert(or bind) a csv to a List so that the Spring form is submitted properly and the listOfTags get the tags entered in the JSP.
What is the best way to achieve it?
Please help.
I'm not sure but try this. Do a simple html input :
<input type="text" id="tagInput" name="myTags" />
And then in your controller do something like :
#RequestMapping(value="/create", method=RequestMethod.POST)
public void create(..., #ModelAttribute("myAttribute") MyClass myAttribute,
#RequestParam("myTags") String myTags, ...) {
...
myAttribute.setListOfTags(Arrays.asList(myTags.split(",")));
...
}
Note : for more generic ways to bind and convert objects, you may want to take a look at PropertyEditors and Converters.
I suggest try to bind it directly to listOfTags property. And to make it work just add contructor with one argument of String type (or define static method valueOf(String)) to Tag class.
Pretty sure you could do something like this:
<c:forEach var="i" begin="1" end="10">
<form:input type="text" path="listOfTags" />
</c:forEach>
Where you get the user to enter each tag into a separate text input. This is because Spring will automagically bind multiple inputs with the same form name to a List, when it does its binding.
You could use some jQuery sugar to only show one or two and then provide a widget to show more tag inputs. Or even write some cool JS to populate the inputs from a single text input just like StackOverflow does when you add tags.

Struts Nested Tag with Dynamic Parameters

I have a legacy Struts 1 application which uses the nested tag. Can I inject a dynamic parameter into the nested tag? For example,
<nested:select disabled="<c:out value='${requestScope.disableSelectBox}' />" />
I also tried doing:
<nested:select disabled="${requestScope.disableSelectBox}" />
In both of the above examples, the disabled attribute was not properly set and it was ignored. If I printout the value with a c:out, the correct value of disableSelectBox is displayed:
<c:out value="${requestScope.disableSelectBox}" />
A colleague suggested that I should use:
<nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
The trouble is that it is considered bad practice to use java scriplets in a JSP page. Is there any way to embed a dynamic variable into a Struts 1 nested tag? Switching to Struts 2 is not an option.
Thanks!
Struts 1 (as far as I can remember) cannot allow you to do:
<nested:select disabled="<c:out value='${requestScope.disableSelectBox}' />" />
As it can't process JSP tags inside any of their attribute declarations, Check what nested:select disabled attribute required needs.
But Struts do support EL and JSP Scriplets (so your colleague is correct). JSP Scriptlet will "render" the value of the <%=request.getAttribute("disableSelectBox"); %> and assign it to the <nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
So (if I assume that the values returns a true or false,
<nested:select disabled="${requestScope.disableSelectBox}" />
and
<nested:select disabled="<%=request.getAttribute("disableSelectBox"); %>" />
will be rendered as (if results returns true)
<nested:select disabled="true" />
before it is sent to Struts to render the nested tag (sorry for using the word "render", you can use translate if you want).

Processing Dynamic forms on the Server Side

I've seen a lot of questions around here about implementing dynamic forms in jQuery or other javascript libraries, and I think I managed to get up and running in setting up a dynamic form for my test purposes.
My question is whats the best practice in naming my form fields and processing them on the server side.
I am trying to implement a contact like form where the user can add multiple phone numbers (and types) as well as multiple addresses (and types) something similar to the code below, this is the code block that will be duplicated dynamically.
<div id="phones">
<label>Phone Number</label><input type="text" name="phone1" value="" />
<label>Type</label><input type="text" name="type1" value="" />
</div>
Then I will have a +/- link or button to add another phone or remove a phone. When I submit the form, whats the best way to handle the combo of name/type
Should I have the names like indicated above with a postfix of an id like phone1 / type1 or should I use the array naming like phone[] / type[] and match the pairs on the server according to the index.
I am using java (not sure if it makes a difference if it is java or php or whatever) but what would be a best practice of doing this.
Thanks
Square brackets with indexes seem to be what most frameworks expect, but it does completely depend on your framework. In the Java world, given that there are about a million different frameworks, you have to start from what your framework expects, and adapt your Javascript code appropriately.
The only Java framework I'm familiar enough with to know the answer is Stripes, and it would want square brackets. If your bean had a property
private List<Address> addresses;
public List<Address> getAddresses() { return addresses; }
public void setAddresses(final List<Addresses>) { this.addresses = addresses; }
then the inputs would need names like "addresses[0].street1", "addresses[0].street2", etc. When you add a new block for a new address, you'd have the same fields with "1" instead of "0".
A different Java framework, however, might do things in completely different ways.
In your case, you should number the field specifically. Don't use array naming convention, which caused me big headache in the past.
If you use arrays, you will run risk of mismatching type and phone values when parameters are missing. Some browsers simply ignore empty values.
To help server retrieve all the parameters, I normally put the number of fields in a hidden field. For the form will look like this,
<div id="phones">
<input type-"hidden" name="count" value="3" />
<ul>
<li>
<label>Phone Number</label><input type="text" name="phone1" value="" />
<label>Type</label><input type="text" name="type1" value="" />
</li>
<li>
<label>Phone Number</label><input type="text" name="phone2" value="" />
<label>Type</label><input type="text" name="type2" value="" />
</li>
<li>
<label>Phone Number</label><input type="text" name="phone3" value="" />
<label>Type</label><input type="text" name="type3" value="" />
</li>
</ul>
</div>

Format number in Struts 2 <s:property/> tag

I would like to format number displayed by <s:property value="summary.total"/> tag in Struts 2. There is a double value. How can I do that? Should I use OGNL?
Or maybe I must use <s:text/> tag and define my format in resuource file?
The way more fast
<s:property value="getText('{0,number,#,##0.00}',{summary.total})"/>
Lucky!!
You need to use <s:text/> with <s:param/>.
Property file:
summary.cost= € {0,number,##0.00}
JSP:
<s:text name="summary.cost">
<s:param name="value" value="summary.total"/>
</s:text>
This answer explains how to use # and 0 in the format mask.
This one is quicker:
<s:property value="getText('struts.money.format', {summary.cost})" />
And in your properties file this:
struts.money.format= {0,number,\u00A4##0.00}
Hope this help
i had this problem to format a number in this way 1.234,56
so i prefered both tags struts tag and fmt tag(fmt because s:number don't exist)
so i used the following syntaxe:
<s:label label="mylabel">
<s:param name="value">
<s:text name="">
<fmt:formatNumber maxFractionDigits="2" pattern="#.###" >1234.56</fmt:formatNumber>
</s:text>
</s:param>
</s:label>
and it's work
If your property is not number in your action then the getText will not work on it. The pattern accept numbers only. In this case you can go with fmt as mentioned by #sarie
<fmt:formatNumber groupingUsed="true" type="currency" value="${amount}" />
The most quickiest and easiest way is to use <s:number /> tag.
Example:
<s:number name="%{summary.total}" minimumFractionDigits="2" type="currency" currency="USD" />
More about tag here https://struts.apache.org/maven/struts2-core/apidocs/org/apache/struts2/components/Number.html

Categories