Validate programatically generated form fields on client side and server side - java

I have a struts2 form that is programatically generated upon request. The element names for all the fields are the same namely idA and paramValue because I am passing the form values as array and looping through it for database inserts. Inserts are now OK, but I am still finding out how to validate the form.
Here's the form:
<s:iterator value="sysParamList" var="sysParam">
<tr>
<td>
<strong><s:property value="paramName" /></strong>
<input type="hidden" name="idA" value="<s:property value="id" />" />
</td>
<td>
<input type="text" name="paramValue" />
</td>
</tr>
</s:iterator>
The properties in my action are declared like
private String[] idA;
private String[] paramValue;
And I pass these in my DAO as-is. The DAO does the looping through the array for database insert.
I can validate forms using jquery.validate IF the form is hard coded in the JSP.

Related

Retrieve an array of parameters from a servlet [duplicate]

I am able to display an ArrayList of beans in a JSP form using JSTL by looping through the list and outputting the bean properties in a HTML input tag.
<c:forEach items="${listOfBeans}" var="bean">
<tr>
<td><input type="text" id="foo" value="${bean.foo}"/></td>
<td><input type="text" id="bar" value="${bean.bar}"/></td>
</tr>
</c:forEach>
How do I code the JSP so that when the page submits then the updated values are in the appropriate item of the the ArrayList?
Given this simplified model:
public class Item {
private Long id;
private String foo;
private String bar;
// ...
}
Here's how you can do it provided ${items} is List<Item>:
<c:forEach items="${items}" var="item">
<tr>
<td>
<input type="hidden" name="id" value="${item.id}" />
<input name="foo_${item.id}" value="${fn:escapeXml(item.foo)}" />
</td>
<td>
<input name="bar_${item.id}" value="${fn:escapeXml(item.bar)}" />
</td>
</tr>
</c:forEach>
(note the importance of fn:escapeXml() as XSS attack prevention)
So, basically, you need to set the item's unique identifier as a hidden input field in each row as shown in above snippet:
<input type="hidden" name="id" value="${item.id}" />
And you should in turn use this id as suffix of name of all input fields in the same row such as:
<input name="foo_${item.id}" ... />
In the servlet, you can collect all values of <input type="hidden" name="id" ...> from all rows by request.getParameterValues(). Just loop over it and then grab the individual inputs by id.
for (String id : request.getParameterValues("id")) {
String foo = request.getParameter("foo_" + id);
String bar = request.getParameter("bar_" + id);
// ...
}
You can also do this all without that id and grab all inputs by name as an array like so name="foo" and request.getParameterValues("foo"), but the ordering of request parameters is not under your control. HTML forms will send it in order, but the enduser can easily manipulate the order.
No need for JavaScript mess here.
See also:
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
ServletRequest.getParameterMap() returns Map<String, String[]> and ServletRequest.getParameter() returns String?
Send an Array with an HTTP Get

Servlet Request Parameter return null

My code is as follows:
<c:forEach items="${cashInList}" var="list" varStatus="stat">
<tr>
<td>${list.dateandtime}
</td>
<td><fmt:formatNumber type="number" pattern="###,###,###,##0.00" value="${list.cashAmount}" />
</td>
<td>
<input id="checkBoxID" type="checkbox" name="checkBoxValues" value="${list.checkBoxValue}" />
${list.checkBoxValue}
</td>
</tr>
</c:forEach>
in the controller bean
String[] checkedValues = req.getParameterValues("checkBoxValues");
However I got a null value.
When an HTML page is submitted, no parameters are sent on the HTTP request for inputs of type "checkbox" if they are not checked.
Try a simple sample with a static HTMl page containing a simple form with two checkboxes, one checked and the other one not checked. In the development tools of your browser you should see that only a parameter for one input is added on the request.
There is also a problem in your code, you have several inputs with the same ID. You should have a different ID for each checkbox.

How to edit fields of a table?

I have a table to show a long list of items, I am wondering how I can edit the fields and submit the form to update them?
<form name="edit" method="POST" action="edit">
<table border="4">
<tbody>
<c:forEach items="${basket.items}" var="item">
<tr>
<td>
<input name="item.id" value="${item.id}"/>
</td>
<td>
<input label="Price" value="${item.product.price}"/>
<br/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
this is a new one
<input id="edit" type="submit" name="edit" value="Edit"/>
</form>
You are using Struts2, with JSTL and EL instead of Struts Tags and OGNL... is there a particular reason that forces you to drop most of the framework mechanics ?
That said, your inputs aren't valid (no type specified) and the "this is a new one" sentence in the HTML seems to indicate the willing to insert a new row, instead of editing the existing entres. Your description and your code seem to ask two different things... to insert a new one, just make a call to another method of the action (or another action) called "add" instead of "edit", sending one single element and adding it to the collection. No need to use AJAX here...
If instead, the question is really:
how I can edit the fields and submit the form to update them ?
this is the way:
<s:form method="POST" action="edit">
<table border="4">
<tbody>
<s:iterator value="basket.items" var="item" status="ctr">
<tr>
<td>
<s:textfield name="item[%{#ctr.index}].id" />
</td>
<td>
<s:textfield name="item[%{#ctr.index}].product.price" />
</td>
</tr>
</s:iterator>
</tbody>
</table>
<s:submit value="Edit"/>
</form>
I would suggest you make an AJAX call using jquery to update the new one. And then in the success handler you can append the new line to the existing table. Before doing that you need to give your table proper ids so that its easier to use JQUERY.
var newLine = document.createElement("tr");
var cellName = document.createElement("td");
$(cellName).text("itemId");
$(newLine).append(cellName);
// similarly create other td's
$("#modelTable").append(newLine);// replace modelTable by the id of your table

Spring MVC - Submit an Object from JSP

I have a JSP that presents a list of customers (ArrayList searchResults). I want to be able to pick one of those, and submit it to a Spring MVC controller. However, it appears that I cannot pass the selected object, only a property of it, such as customerId. I really need to pass the entire object.
Is there a standard way to do this in Spring 3.x?
<c:forEach items="${searchResults}" var="searchResult">
<tr>
<td><c:out value="${searchResult.customerId}" /></td>
<td><c:out value="${searchResult.firstName}" /></td>
<td><c:out value="${searchResult.lastName}" /></td>
<td>
<form method="POST" ACTION="./customercare">
<input type="SUBMIT" value="Select This Customer"/>
<input type="hidden" name ="searchResult" value="${searchResult}"/>
</form>
</td>
</tr>
</c:forEach>
You can use Spring's form taglib instead of plain <form> to post back to a Spring MVC Controller and then it will Bind the values back to the model you specify.
<form:form method="post" action="addContact.html">
<table>
<tr>
<td><form:label path="firstname">First Name</form:label></td>
<td><form:input path="firstname" /></td>
</tr>
...
#RequestMapping(value = "/addContact", method = RequestMethod.POST)
public String addContact(#ModelAttribute("contact")
Contact contact, BindingResult result) {
See this Post: http://viralpatel.net/blogs/spring-3-mvc-handling-forms/
You might want to consider giving id to each and nested tags to differentiate between row that you want to POST
<c:forEach items="${searchResults}" var="searchResult">
<tr>
....
<form:form id="${searchResults.key}-form" method="POST" ACTION="./customercare">
<form:input id="${searchResults.key}-btn" type="SUBMIT" value="Select This Customer"/>
<form:input id="${searchResults.key}-hidden" type="hidden" name ="${searchResults.key}" value="searchResult['${searchResults.key}']"/>
</form:form>
</tr>
On the backend side you will have to write the controller as suggested by #PatBurke
You could have 1 form per customer with a lot of hidden inputs in. When that customer is selected you can POST that form. Spring can then bind all the hidden inputs to your customer object.
(Generally, I would just send the id only and load the customer info, as an entity, from a Database. However, I assume you must have a good reason for not wanting to do this)

Sending form parameters from JSP to Struts action class

I am implementing a search functionality in a website I am building, which involves searching by the md5 hash of the name of the file submitted and searching by the notes associated with each submitted file. So, I should detect as to which button is pressed "Search by MD5" or "Search by Notes". This is the code I have:
JSP code for the form:
<form id="search" name="search" action = "search.do"
method="POST" enctype="multipart/form-data">
<table align = "center">
<tr>
<th colspan="4" bgcolor="#004276"><font color="white">
Search for Sample
</th>
</tr>
<tr>
<td><input name="md5" type="text" value="${form.md5}"/></td>
<td><input name="md5search" type="submit" value="Search by MD5"/>
</tr>
<tr>
<td><input name="notes" type="text" value="${form.notes}"/></td>
<td><input name="notessearch" type="submit" value="Search by Notes"/>
</tr>
</table>
</form>
search.do is mapped to SearchResultsAction.java. Code in Java action class (SearchResultsAction) which handles the request is:
if(request.getParameter("md5search").toString().equals("Search by MD5")){
searchSubmissionsList = submissionsDAO.searchSubmissionsByMD5(form.getMD5());
}
if(request.getParameter("notessearch").toString().equals("Search by Notes")){
searchSubmissionsList = submissionsDAO.searchSubmissionByNotes(form.getNotes());
}
But the problem I am facing here is that, request.getParameter("md5search") and request.getParameter("notessearch") return null for some reason. I have been working on this for a while and have not been able to figure it out. The weird thing is that it once worked for me sometime back when I was working on another project. Am I missing something here?
It's null because you used multipart/form-data form encoding instead of (default) application/x-www-form-urlencoded. Basically, you have to (let Struts) extract the text fields from the multipart form data body the same way as you (or Struts) extracted the uploaded file. Or, as there is actually no <input type="file"> field in your form at all, just remove the enctype attribute altogether.
See also
Does form with enctype="multipart/form-data" cause problems accessing a hidden field

Categories