How to: Struts 2 validating dynamic forms array - java

I read through this
Struts2 Validation for an array
and it makes sense, but wished person (Quaternion) would explain how to
"rewrite the above to specifically name fields (with indexes) in which case you can use , and you'll use the addFieldError method. For details on these tags see http://struts.apache.org/2.3.1.2/docs/tag-reference.html"
This is what I have:
<s:form action="saveOrUpdateAction" method="get">
<s:token/>
<table>
<tr>
<td> Fund </td>
<td> Award Code </td>
</tr>
<s:iterator value="gfeListWithEmptyCode">
<tr>
<td> <s:property value="sfafund "/> </td>
<td> <s:property value="awardcode"/>
<input type="text" name="codeArray">
</td>
</tr>
</s:iterator>
<s:token />
<s:submit key="Submit2"/>
</table>
</s:form>
Part of my Action:
public void validate()
{
if (fund == null || fund.trim().length() != 5 )
{
System.out.println("testing+++++++++++++++++++1");
addFieldError("fund","Fund requires 5 characters.");
}
if (code == null || code.trim().length() != 3 )
{
System.out.println("testing+++++++++++++++++++2");
addFieldError("code","Fund requires 3 characters.");
}
if (gfeListWithEmptyCode !=null)
{
int index = 0;
for (GiftFundEntity giftFundEntity : gfeListWithEmptyCode)
{
if ( codeArray[index]!=null && codeArray[index].length() < 3 )
{
System.out.println("testing+++++++++++++++++++3");
// technically, this is not possible to do because it requires codeArray[index] and not a string.
addFieldError("codeArray","Code requires 3 characters.");
index++;
}
}
}
try
{
this.execute();
} catch (Exception e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
During validation, the red error message does not show up on the jsp page for obvious reasons because codeArray isn't listed by the indexes. How do I get this to work? * Please note* the array is dynamic.
I looked through the struts documentation and searched through stackoverflow, but I don't see how it can be done.
Thanks for your time.

The answer is Struts 2 treats the codeArray variable inside the Action class as an Array: String [] codeArray; This is not documented.

Related

How to use Java get function on Thymeleaf HTML?

Follow up on this question
Function to determine winner
How do I use the java function stated on the linked question in thymeleaf HTML form?
Here is the code I have so far, but the function call doesn't work:
<tr th:each="score : ${score}">
<td th:text="${score.player1name}"></td>
<td th:text="${score.player2name}"></td>
<td>
<ul th:each="round : ${score.roundScores}">
<li th:text="${round}"/>
</ul>
</td>
<td th:text="${score.finalscore}"></td>
<td th:text="score.winner : ${score.getWinningScore()}">
<td th:text="${score.sportstype}"></td>
<td><a class="btn btn-danger" onclick="return confirm('Are you sure you want to delete this score?')" th:href="#{/delete/{id}(id=${score.gameid})}">Delete</a></td>
<td><a class="btn btn-primary" th:href="#{/edit/{id}(id=${score.gameid})}">Edit</a></td>
</tr>
</table>
New Game
Here is the funtion I'm trying to call:
public String getWinningScore() {
//Lambda Expressions to convert String array to Int array and calculate sums
int sumOfscore1 = Arrays.stream(player1score).mapToInt(Integer::parseInt).sum();
int sumOfscore2 = Arrays.stream(player2score).mapToInt(Integer::parseInt).sum();
if (sumOfscore1 > sumOfscore2) {
winner = player1name;
} else if (sumOfscore2 > sumOfscore1) {
winner = player2name;
}
return winner;
}
Here is the error I'm getting:
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "score.getWinningScore()" (template: "scorelist" - line 31, col 8)
You don't need get, just try using ${score.winningScore}
Apparently I had empty fields on my html front, and when less than max amount of rounds where played it filled the rest with blank string.
Blank string cannot be inputted to a string list.

Unable to catching multiple table rows with JSTL forEach in Spring MVC

The goal: adding multiple table rows dynamically based on user inputs and catch the data through controller.
What I have so far(all simplified):
POJO:
public class Item(){
String price;
String weight;
getters and setters...
}
public class ItemForm(){
List<Item> items;
getter and setter...
}
JSP:
<form:form action="/create" method="POST" modelAttribute="itemForm">
<table>
<tr>
<td><input type='text' name='price'/></td>
<td><input type='text' name='weight'/></td>
</tr>
</table>
<c:forEach items="${itemForm.items}" var="item" varStatus="status">
<tr>
<td align="center">${status.count}</td>
<td><input name="items[${status.index}].price" value="${item.price}" /></td>
<td><input name="items[${status.index}].weight" value="${item.weight}" /></td>
</tr>
</c:forEach>
</form:form>
Controller:
private List<Item> items = new ArrayList<>();
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String saveMultipleRows(#ModelAttribute("itemForm") ItemForm itemForm) {
items = itemForm.getItems();
if(items != null && items.size() > 0){
System.out.println("The list is not null!");
}
System.out.println("didn't get into the if statement");
return null;
}
I skipped the Javascript on adding table rows, if you think that have anything to do with this question, I will update my post and put the Javascript code.
The idea is to create a ItemForm class that contains a list of Item object, and in the JSP using JSTL c:foreach to save all the data from users to the list. And in my controller, if the list is not empty, I simply want to print out a message so that I know the list is not empty. But now if I run the program, it prints out "didn't get into the if statement".
So the problem I am currently having is the list is empty, that means I am not able to save the user input data to the list. Can anyone help me and let me know where I did wrong?
Below is the corrected code
since you have item in scope you can directly access the props of Item,You dont need to explicitly declare the index
<input name="${item.price}" value="${item.price}" />
<input name ="${item.weight}" value="${item.weight}" />

Getting checkboxes check state

I am trying to get the check boxes' check state with the code below but ended up with the following error if the any of the checkboxes are not checked. My goal is to update the database table with the checkbox state. if checked then 1 else 0.
Error:
Severe: java.lang.NullPointerException
at doPost(Controller.java:125)
java:
String[] chkDisperse = request.getParameterValues("chkDisperse");
int status;
for (int i = 0; i < attId.length; i++) {
if (chkDisperse[i] == null) {
//(line 25 here)
status = 0;
}
else
{
status = 1;
}
html:
<c:forEach var="AttList" items="${att}" varStatus="iter">
<tr id="test">
<td style="text-align: center;"><input name="attId" type="hidden" value="${AttList.attId}" /></td>
<td style="text-align: center;"><input type="checkbox" name="chkDisperse" value="${AttList.isPresentDisperse}" ${AttList.isPresentDisperse == 1 ? 'checked' : ''}></td>
</tr>
</c:forEach>
It seems that selected checkbox values are not being passed to the servlet. Hence you get array as null here,
String[] chkDisperse = request.getParameterValues("chkDisperse");.
And you end up with NPE at this line:
if (chkDisperse[i] == null)
Make sure that the checkbox are properly enclosed within the form tag. In case it is an ajax call do check the parameters being sent from the web browser console.
Edited
I want to set the the status to 0 if not checked
In jsp or js file imported in jsp, try this jQuery solution:
$(function() { //dom ready
$('input[name=chkDisperse]').on('change', function() {//change event handler
this.value = this.checked ? '1' : '0';
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="checkbox" name="chkDisperse" value="0" />
<input type="checkbox" name="chkDisperse" value="1" />
This is plain js solution:
var putState = function(input) {
input.value = input.checked ? '1' : '0';
};
<input type="checkbox" name="chkDisperse" value="0" onchange='putState(this);' />
<input type="checkbox" name="chkDisperse" value="1" onchange='putState(this);' />

Working with <div> tag in JSP for making the contents hidden or visible

I have written a javascript function.
function wellChecked(state) {
if (state)
{
wellDropDown.style.visibility = 'visible';
}
else
{
wellDropDown.style.visibility = 'hidden';
}
}
I have a checkbox after the Well Modification <td> as given below,
<tr>
<td>On Call</td>
<td><html:checkbox property="onCall"/></td>
<td>Well Modification</td>
<td><input type="checkbox" onclick="wellChecked(this.checked)" /></td>
</tr>
When that checkbox is clicked I want the drop down list given under the div id=wellDropDown to be displayed. Defaultly, if the check box is not clicked, the drop down should not be displayed.
<tr>
<td>Active</td>
<td><html:checkbox property="active"/></td>
<div id="wellDropDown" style="visibility:hidden;">
<td>
<html:select property="wellFormatId">
<html:option value="">(Select)</html:option>
<bean:define id="wellFormatColl" name="wellFormats" scope="request"/>
<logic:iterate id="wellFormats" name="wellFormatColl" indexId="index" type="com.astrazeneca.compis.data.WellFormatVO">
<% Long wellId = wellFormats.getWellFormatId();%>
<% String wellIdNo = wellId.toString(); %>
<html:option value="<%=wellIdNo%>">
<bean:write name="wellFormats" property="wellFormatName"/>
</html:option>
</logic:iterate>
</html:select>
</td>
</div>
</tr>
When I tried executing this code, I could see the drop down list getting displayed irrespective of the checkbox checked or not.
Where I have went wrong in this scenario? Please give ur suggestions or ways to implement my requirement.
Your HTML is invalid. You may not have a div enclose a td like this. Either make the td itself visible or invisible, or put the div inside the td, instead of putting it around the td.
Also, unless wellDropDown is a global JS variable, the code should be
document.getElementById("wellDropDown").style.visibility = 'visible';
with jquery you could do this :
<tr>
<td>On Call</td>
<td><html:checkbox property="onCall"/></td>
<td>Well Modification</td>
<td><input type="checkbox" id="myCheckBox" /></td>
</tr>
...
<script>
$('#myDropDown').click(
function () {
$("#wellDropDown").toggle();
});
);
</script>

Nullpointer exception in doPost

I have de following Form:
<form action="/AppStore/publish" method="post" accept-charset="ISO-8859-1">
<fieldset>
<legend>Do you have an Account already?</legend>
<input type="radio" name="registred" value="yes"> Yes
<input type="radio" name="registred" value="no"> No
</fieldset>
<fieldset>
<legend>About your App</legend>
<table>
<tr>
<td><label for="AppDesc">Describe it:</label></td>
<td><input type="text" name="AppDesc" /></td>
</tr>
<tr>
<td><label for="AppName">Name:</label></td>
<td><input type="text" name="AppName" /></td>
</tr>
</table>
</fieldset>
<input type="submit" value="Submit" />
</form>
I pass this data to a Java Servlet, but every time I get a Nullpointer Exception at getParameter("AppDesc"), instead getParameter("AppName") works fine, what do I wrong?
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
RequestDispatcher dispetcher = context.getRequestDispatcher("/publishForm.jsp");
List<String> errorMessages = new ArrayList<String>();
//Validating form input...
if(request.getParameter("AppName").toString().isEmpty())
{
errorMessages.add("Please type a valid Name for your App.");
}
if(request.getParameter("AppDesc").toString().isEmpty())
{
errorMessages.add("The Description of your App should contain at least 160 Characters.");
}
You're calling request.getParameter("...").toString().
request.getParameter() already returns a string reference, so you don't actually need to call toString() to get the value as a string, but it will return a null reference if the parameter is missing - in which case calling toString() will throw an exception. You need to check whether the value is null or empty. For example:
String description = request.getParameter("AppDesc");
if (description == null || description.isEmpty())
...
Of course, there are libraries around to check for "null or empty" - for example, in Guava you could use:
if (Strings.isNullOrEmpty(description))
If request.getParameter("AppDesc") is null, then
request.getParameter("AppDesc").toString().isEmpty() will throw a NullPointerException.
Why not change the condition to:
if(request.getParameter("AppDesc") == null ||
request.getParameter("AppDesc").toString().isEmpty()))
{
<td><input type="text" name="AppDescr" /></td>
You've named the actual field AppDescr (notice the trailing "r"), but you're calling getParameter for AppDesc (sans "r").
EDIT: Or not... you edited your post and fixed it. Was this not the problem?
It must be the case that request.getParameter("AppDesc") returns a null value, causing the chained toString() to generate a NullPointerException.
This parameter was never set; the name specified in the html was "AppDesr" (note the trailing 'r').
Your question title says doGet, your code says doPost. The difference between those two might explain your problem. :-)

Categories

Resources