Hi there I am using Spring MVC and I am trying to display some data from multiple Lists in a jsp page. I've searched and found some similar topics but I wasn't able to achieve what I am trying to do plus got more confused.
My model class contains something like this:
private String BlaBla1;
private String BlaBla2;
private List<String> Alpha;
private List<String> Beta;
.....
//getters setters
What I want is to display a table in a jsp with the values from these two Lists (Alpha and Beta ..) one value at a column.They both have the same number of values.
For Example
<tr><td>Alpha.value1</td><td>Beta.value1</td></tr>
<tr><td>Alpha.value2</td><td>Beta.value2</td></tr>
......................................
<tr><td>Alpha.valueN</td><td>Beta.valueN</td></tr>
As I've seen here rendering data in jsp using spring controllers and different classes
and some other examples, they create something like that: List<MyObjects> objects but MyObjects model always has private String ... and NOT any List<String>..
I tried to construct something like that
Map<String,List<String>> test = new HashMap<String,List<String>>();
then
test.put("alfa", Alpha);
test.put("beta", Beta);
but all I got was just display them in 2 rows and a single column using
<c:forEach var="testValue" items="${test}">
<tr><td>${testValue.value}</td></tr>
</c:forEach>
Please don't aske me to change my Model class, it is 'impossible'.
I've seen somewhere saying to use Collection but I'm not sure how to do that.
Any suggestion would be useful,
happy coding!
model.addObject("alphaList", alpha);
model.addObject("betaList", beta);
In the jsp :
<c:forEach var="listItem" items="${alphaList}" varStatus="theCount" >
<tr><td>${listItem}</td><td>${betaList[theCount.index]}</td></tr>
</c:forEach>
Note : ${theCount.index} starts with 0
${theCount.count} starts with 1.
So basically you can use the count to iterate over the second list.
You just have to iterate the Alpha list normally ... but with use of the varStatus attribute of <c:foreach > tag. This varStatus has (among others) an attribute index which is the index of the iteration and all what you need to display corresponding element from Beta list. Code example :
<c:forEach var="alphaVal" items="${Alpha}" varStatus="status">
<tr><td>${alphaVal}</td><td>${Beta[status.index]}</td></tr>
</c:forEach>
Related
On my website I have a few checkboxes each of them contains id in value attribute. After submitting form I'd like to have a list containing ids of checked checkboxes to be passed to the controller. That's how I want to make new page comparing n products.
Controller can accept List<Long> or long[]. That's what I have for now:
HTML:
<form th:action="#{/comparison}" th:object="${productsComparison}" target="_blank" method="post">
<table>
<tr data-th-each="item, iter : ${items.item}">
<td>
<input type="checkbox" th:name="|productsComparison.ids[${iter.index}]|" th:value="${item.id}"/>
</td>
</tr>
</table>
I've added to my controller List<Long> wrapped in ProductComparison with appropriate getters and setters. After submitting form list is always null.
Controller:
#RequestMapping("/productsPage")
public String showProducts(Model model) {
ProductsComparison productsComparison = new ProductsComparison();
model.addAttribute("productsComparison", productsComparison);
}
#RequestMapping("/comparison")
public String compareProducts(#ModelAttribute ProductsComparison productsComparison) {
System.out.println("List: " + productComparison.getIds());
// Always shows null
return "comparison";
}
public class ProductsComparison {
private List<Long> ids;
// Getters & setters
}
The underscores __ are ThymeLeaf's syntax for a preprocessing expression. Or in layman's terms, the stuff inside of the underscores are processed before the rest of the expression.
This is important because your expression is using an array, and the ${iter.index} portion of it gives the array index.
If you are curious or if anyone else stumbles upon this. th:name is no different than the html attribute name. The ThymeLeaf engine will just shove a name attribute into the html entity or overwrite the old one. ThymeLeaf has a ton of properties like this. th:field is a totally different beast though. It is what tells ThymeLeaf to bind the input of your form to the back forming bean or your model attribute, th:object="${productsComparison}". So with the expression th:field="*{ids[__${iter.index}__]}", Thymeleaf is going to call productsComparison.getIds[0] and the corresponding setter.
Note about th:name if you are submitting with Javascript of any kind, you probably want to use this. Most likely you are serializing your form, and the JSON created by this method call will use the name property.
If you want to know more about ThymeLeaf preprocessing expressions, there is a bit in the documentation about it.
I've finally found solution. Instead of th:name I had to use th:field.
th:field="*{ids[__${iter.index}__]}"
Because it's field I didn't have to specify object productsComparison before ids. ids field is List<String>.
To be honest I have no idea what underscores do, I will be glad if someone could explain.
I'm new to the front end side of Java EE and HTML5. I have read that you could use the data attribute to read through the DOM. How would you properly use this to get a session attribute already set by java. Compared to the other methods such as using a hidden input.
<input id="sid" type="hidden" name="series" value="${sessionScope.series} />
var sid = document.getElementById("sid"), series;
Use something like this:
<div id="div1" data-special-value="${sessionScope.series}"></div>
And get the attribute value like:
document.getElementById("div1").getAttribute("data-special-value")
Or even ( http://caniuse.com/dataset ):
document.getElementById("div1").dataset("special-value")
Or with jQuery:
$("#div1").attr("data-special-value")
// or
$("#div1").data("special-value")
Although I'm not sure storing a session value on an element is right. It's definitely not wrong, I'm just wondering what you'd need/use it for with sessions. Sessions appear once.
The data-* attributes are more useful with storing related data to something. For example, if you loop through a bunch of database records and print their columns, but want to also store the row's database id once, you'd use:
<c:forEach items="${rows}" var="row">
<tr data-row-id="${row.id}">
<td>${row.name}</td>
<td>${row.description}</td>
</tr>
</c:forEach>
Then if you want to get the original row.id value, it's stored in one place an encompasses everything it pertains to (the columns). This is usually how/where I use data-* attributes. Of course, there are many ideas/uses for this.
I am trying to read data from a table and display it to the user .
Can anybody tell how to do it using struts 1.3 ?
Write an class extending Struts' Action class. This class pulls the data from Database as a List. Pass this data as request attribute, request.setAttribute("myList", list). Return "success".
In your struts-config.xml, map this Action class to a JSP on "success". The request will be forwarded to the JSP.
In the JSP, get the list from request by request.getAttribute("myList"). Iterate through the list and print the List.
You need to study this: http://struts.apache.org/1.x/userGuide/index.html
(Edit: Just noticed this is a 2 year old question)
Don't use the struts tags unless you NEED to. This can be accomplished with jstl/el.
So on your Action class you would have something like this:
List<Map<?, ?>> listOfHashMaps = new ArrayList<Map<?, ?>>();
request.setAttribute("listOfHashMaps", listOfHashMaps);
In your jsp:
<c:forEach var="hashMap" items="listOfHashMaps">
${hashMap[someInteger]} <%-- To get the value associated with 'key' --%>
</c:forEach>
You can also access the keys/values with:
${hashMap.key}
${hashMap.value}
Respectively.
I have a servlet ( that I cannot change ) to gather information to be displayed in on a web page. I use a bean in a JSP page to loop through the information.
I tried to simplify, but my information is stored tables basically like this
alt text http://img36.imageshack.us/img36/4295/schemase.jpg
So for example, the bean stores information in nested arrays like this:
---2009
------TOYOTA
---------BLUE 10
---------RED 20
------CHEVY
---------BLUE 30
---------RED 10
---2010
------TOYOTA
---------BLUE 30
---------RED 12
------CHEVY
---------BLUE 12
---------RED 20
This is great for when I display the report per year, per category, per color. I can easily loop through the years, loop through the categories, then loop through the colors. This is the report I have ( simplified )
alt text http://img841.imageshack.us/img841/3666/reportihave.jpg
Now I need to turn that information sideways. I need to create a report to display the count per color, per year. This is the report I need:
alt text http://img33.imageshack.us/img33/461/reportineed.jpg
How can I rearrange the information within the JSP? Should I use arrays to gather the info, or is there an equivalent to a hash that I can use?
Thanks
I don't think you should be doing such things in a JSP. Have a servlet handle the request, put the data in the correct form, and have the JSP simply display it. Sounds to me like you're asking the JSP to do something it shouldn't.
If those are objects, you should be able to iterate over a different key (color in this case) and redisplay without too much trouble. Have the servlet send down a second map in the right form.
Are you using JSTL? If you're not, you should be.
To be consistant with your original approach, you could rearrange the nested arrays to look like the following:
---BLUE
------2009
---------TOYOTA 10
---------CHEVY 30
------2010
---------TOYOTA 30
---------CHEVY 12
etc
Your JSP code must look very bad having to iterate through all the arrays. My suggestion would be the following: Create a JavaBean class which represents a row in the table and pass a List of instances of this JavaBean class to the JSP for display:
JavaBean
public class ColorRow{
private String color;
private int year;
//...
//getters and setters
}
Servlet/Controller
List<ColorRow> colorTable = new ArrayList<ColorRow>();
//populate the list
request.setAttribute("colorTable", colorTable);
JSP
<c:forEach items="${colorTable}" var="row">
<tr><td>${row.color}</td><td>${row.year}</td><!-- ... --></tr>
</c:forEach>
I solved the problem by looping though the lists in the bean until I got to the color list, then started looping through again and again until I found all the records for each color.
<c:forEach var="year1" items="${Info.list}" varStatus="yearCounter1" >
<c:if test="${yearCounter1.count == 1}">
<c:forEach var="clist1" items="${year1.list}" varStatus="catCounter1">
<c:if test="${catCounter1.count == 1}">
<c:forEach var="colorlist1" items="${colorlist1.list}" varStatus="colorCounter1">
<!-- this gets me to all possible colors -->
<c:forEach var="year2" items="${Info.list}" varStatus="yearCounter2" >
<c:forEach var="clist2" items="${tlist2.list}" varStatus="catCounter2">
....
<c:if test="${colorCounter1.description==colorCounter3.description&& year2.description==year3.description && clist2.description==clist3.description}" >
Is it efficient? No.
Is it a good use of JSTL? No.
But I am stuck. I cannot change anything in the bean, I had to use JSP to do the work.
I'm building a spring mvc application.
Now the problem I have is the following.
I have a controller which adds a DayInfo[][] to my ModelMap.
(DayInfo has an id, a title (String) and Text(also String).
Now the problem I have is that I have no problem displaying this DayInfo[][] with <foreach> tags in my jsp.
However I'm outputting the Title property as an input box(type text), and I'd like to be able to update this value (and thus saving it to be a database but that shouldn't be a problem). However I'm having trouble with binding this value to the input box so that it is actually returned to the controller.
If anyone has some advice it would be welcome.
I have never done this with multidimensional arrays but it should be something like this (though I haven't tried it, it's just to give you an idea). In the JSP you should set the name of the input with each index, something like this:
<c:forEach var="row" items="${days}" varStatus="statusRow">
<c:forEach var="day" items="${row}" varStatus="statusCol">
<input type="text" name="days[${statusRow.index}][${statusCol.index}].title" value="${day.title}"/>
</c:forEach>
</c:forEach>
and in the controller you have to prepare days variable so the size of the array is the same as the one you get from the JSP. So you can use #ModelAttribute method to prepare the array (this method will be executed before the #RequestMapping method).
#ModelAttribute("days")
public getDays(){
DayInfo[][] days;
//Here you have to instantiate the days to prepare it so it can be filled
//You can load for example the data from the database
return days;
}
#RequestMapping("/yourURL")
public String getFormData(#ModelAttribute("days")DayInfo[][] days){
//Here in days you should have the data from the form overriding
// the one from the database
}
Hope this helps and sorry if there is any error, though I'm writing withoug trying it.