Pass loop variable from Freemarker template to Spring controller - spring-mvc

I am listing objects in a table in my view. I want to be able to edit an object using a button in the table.
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
<form name="product" method="post" action="/product/edit">
<input type="submit" name="submit" value="Edit this product"/>
</form>
</td>
</tr>
</#list>
The object then should be passed to a controller method:
#RequestMapping(value="/edit", method = RequestMethod.POST)
public ModelAndView edit(#ModelAttribute("product") Product product){
ModelAndView mav = new ModelAndView("product/edit");
mav.addObject("product", product);
return mav;
}
However, the product obtained by the edit method is null. How do I fix this? I tried to bind the product inside form using the code below, but that did not work either.
<form name="product" method="post" action="/product/edit">
<#spring.bind "product" />
<input type="hidden" name="${spring.status.expression}" value="${spring.status.value}"/>
<input type="submit" name="submit" value="Edit this product"/>
</form>
I want to use the POST method.

I would like to suggest a different approach. If I'm not mistaken you just want to pick an object for later editing - you don't really edit it in that very view.
If so, all you have to do is to pass an identifier of your object to your controller, but not the selected object itself.
If not, you should give us the hole story and provide the rest of the view as well.
Assuming I'm right the next question is why you need to use a form submission at all. Passing an id is best done by links - either as parameter or, if you follow REST-style, as part of the URI itself:
<!-- Link parameter -->
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
Edit ${product.productName}
</td>
</tr>
</#list>
<!-- REST-style -->
...
Edit ${product.productName}
...
productName isn't a good id of course. If products is a list (meaning, java.util.List) the index of the list is handy. Even in a HashMap or Set I'd create a unique id instead of using the product name.
Now that you can identify your object, select it in the backing code for later editing, but not in the view.
You'll find loads of examples of how to get link parameters in a controller. So, no need to go into detail here.
If however you insist on using a form and a POST-method then do it like this:
<form method="post" action="/product/edit">
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
<button value="${product.productName}" name="product" type="submit">Edit ${product.productName}</button>
</td>
</tr>
</#list>
</form>
Note that this won't work for older IE browsers (below Ver. 10), because they don't return the value, but everything that is inside the button tag.
Hidden inputs and a single submit button won't help at all, because all inputs are submitted and using different forms is not the way either.

Related

Access value outside form using thymeleaf

I need to obtain vaulue of an input using thymeleaf and spring but haven't been able to do so. Since I need that value in a lot of the methods in the controller I can't put that input inside of one of the forms.
I tried to use javascript to pass on the value to a hidden input in the forms, however since I'm using th:each I'm only getting the value of the first input.
I also tried adding a string to the model and then trying to access that string with #ModelAttribute, but it didn't workout either.
This is the html:
<tr th:each="pro:${productos}">
<td th:text="${pro.id}">id</td>
<!-- More code here omitted for brevity-->
<td>
<div>
<form th:action="#{|/actualizarMas/${pro.id}|}" method="post">
<button type="submit" id="mas">+</button>
</form>
<form th:action="#{|/actualizarMenos/${pro.id}|}" method="post">
<button type="submit" id="menos">-</button>
</form>
<input name="masomenos"/>
<form th:action="#{|/${pro.id}|}" method="post">
<button type="submit">Borrar</button>
</form>
</div>
</td>
</tr>
This is the controller:
#RequestMapping(value = "/actualizarMenos/{productosId}", method = RequestMethod.POST)
public String eliminarUno(#PathVariable int productosId, RedirectAttributes redirectAttributes, #RequestParam("masomenos") String masomenos) {
//Code here using that string omitted for brevity
return "redirect:/";
}
I need to access the input with the name "masomenos", if that is posible, how could I do it?, if not, what options do I have? besides creating inputs inside all the forms.
Thank you very much.

MVC - Receive Form with Viewbag Variable from database and passing to the view

i have a html form into my database.
In this form i have a value which contains a Viewbag,
for example value="#Viewbag.MyVariable"
In my view when i try to receive my form all works fine,
but my problem is that the Viewbag value are not converting
to the value which comes from my controller.
any ideia how to resolve this ?
my code:
View:
#Html.Raw(p.Form)
My form in my database looks like:
<form action="/MyController/MyAction" method="post">
<input type="hidden" name="num" value="#ViewBag.num" />
....
....
....
</form>
What i have try to do was with:
Stringbuilder a=new Stringbuilder;
#Html.Raw(a.To.String())
Your code should technically work, if you are using MVC you could try
#MvcHtmlString.Create(p.Form);
I found a solution and now i solved it.
what i have done:
in my form the only part which are different from the others
forms are the dropdownlists.
i only put the part from <select> to </select> in my
database. (only the dynamically part of my form)
in my view i have write my form and only insert the variable
which comes from my controller to insert the data from my
database on the right part in my form.
here is the code:
<form action="/MyController/MyAction" method="post">
<input type="hidden" name="num" value="#ViewBag.num" />
#MvcHtmlString.Create(p.Form);
<button type="submit" name="submit" id="submit">OK</button>
</form>
So i have never more the problem with the variables to be
converted, because the variables are still the same

asp.net razor Model Binding Dynamic List in Form submission

I am trying to create an order form for input.
I need the user to be able to add multiple line items then update. I was trying to
use the shopping cart class (where user creates a cart item and adds a
list item, multiple lines can be added to the list item).
I didn't get through with that. I am using asp.net razor am using
webmatrix to build site. Webmatrix is saying that it doesnt recognise Cart().
#{
if (Session["cart"] == null)
{
Session["cart"] = new Cart();
}
Cart cart = (Cart)Session["cart"];
}
<table id="cartTable">
<tr>
<th class="product">Product</th>
<th class="size">Size</th>
<th class="price">Price</th>
</tr>
#foreach (var item in cart.Items)
{
<tr>
<td class="product">#item.ProductID</td>
<td class="size">#item.Size</td>
<td class="price">£#item.Price</td>
</tr>
}
</table>
Is there a better way to do this? All help is greatly appreciated
There IS a way to bind dynamic list elements
#foreach (i=0; i< cart.Items.count; i++)
{
<tr>
<td class="product"> <input type="hidden" name="cart.item[#i].ProductID"> </td>
<td class="size"> <input type="text" name="cart.item[#i].Size"> </td>
<td class="price">£ <input type="text" name="cart.item[#i].Price"> </td>
</tr>
}
Webmatrix is saying that it doesnt recognise Cart()
I strongly recommend you place your Models in the Models folder and make them part of the Models namespace. Then they should be available automatically. Otherwise, you may have to reference cart by it's complete reference path (if it is not in your Models folder). example
Datalayer.Entities.Cart cart = (Datalayer.Entities.Cart)Session["cart"];
Final Note:
You are not passing your Cart as a Model to your View
example
#model {Project}.Entities.Cart
This is a better practice using the MVC 3 framework. You would have discovered whatever reference problem earlier and would have the option to use tightly bound Helpers
I recommend using the Visual Studio 2012 Express over WebMatrix for MVC development. Furthermore, I would also suggest using jQuery (javascript) if you wish to let users add line items on the fly via the same page. I can share an example with you if you like.
One more note: You tagged this with both MVC and WebForms, which are two very different platforms.
Edit:
I think Dave A's solution may be better, but to do this with jQuery:
1 Put your add button and hidden div in a form
<form action="/MyController/MyAction" method="post" id="addListItemForm">
<button id="addListItemButton">Add List Item</button>
<div style="hidden">
<input type="text" name="product" id="product" />
<button id="addButton">Add</button>
</div>
<input type="submit" text="Submit" />
</form>
2 Show the form fields on button click
$('#addListItemButton').click(function(){
$('#addListItemForm div').show();
});
3 Add hidden field on add button click
$('#addButton').click(function(){
var product = $('#addListItemForm #product').val();
$("input").attr({
name : "productListItems[]",
type : "hidden",
value : product
}).after('#addListItemForm');
});
4 When the form submits, you will have various product names in the productListItems array passed via POST method.
Note: You'll have to play with this a little bit, but it would be a good learning exercise... I am not exactly sure what you are trying to do, but this is my best guess.

More than one form in one view. Spring web flow + displaytag + checkbox

I have a table, using display tag, in my application, that is using spring web flow. I would like to have a check box in each row, a button that allows me to select/uselect all and a button to execute a function. After clicking the button, the action will perform some database actions and the page should be render, so we can see these changes.
I don´t know which could be the best option, submitting the whole table
<form method="POST" (more params)>
<display:table id="row">
....
</display:table>
</form>
Or only the checkbox column. I this case I wouldn´t know how to implement it.
I have tryed two different approaches:
1. Using a simple input text, checkbox type. This is not possible, because when I submit the form, I need to set a path to another page.jsp (I am working with flows). Besides, I wouldn´t know how to send these values to java backend.
Using spring tags.
In this case, the problem comes whith the class conversationAction
I found some examples, but allways using MVC and controller cases.
How could I implement this issue??
EDIT
I have found a kind of solution, but I faced a new problem...
flow.xml
var name="model1" class="com.project.Model1"/>
var name="model2" class="com.project.Model2"/>
view-state id="overview" model="formAggregation">
...
</view-state>
page.jsp
form:form modelAttribute="formAggregation.model1" id="overviewForm">
...
/form:form>
...
form:form method="POST" modelAttribute="formAggregation.model2">
display:table id="row" name="displayTagValueList" requestURI="overview?_eventId=tableAction">
display:column title="">
form:checkbox path="conversationIds" value="${row.threadId}"/>
/display:column>
/display:table>
input type="submit" name="_eventId_oneFunction" value="Send>>"/>
/form:form>
FormAggregation.java
#Component("formAggregation")
public class FormAggregation {
private Model1 model1;
private Model2 model2;
//Getters and setters
I need this aggregator, because I need both models. I have tested it one by one and it is working as wished. Any idea about that??
Thanks!!
I couldn´t find a solution to add two model in a view-state. So I made a workaround, adding the fields I needed to the model I was using, com.project.Model1. So the result is:
page.jsp
<form:form method="POST" id="tableForm" modelAttribute="model1">
<display:table id="row">
<display:column title="">
<form:checkbox path="chosenIds" value="${row.id}"/>
</display:column>
<display:footer>
<div class="tableFooter" >
<input type="submit" name="_eventId_workIds" value="Send"/>
</div>
</display:footer>
</display:table>
</form:form>
flow.xml
<var name="model1" class="com.project.Model1"/>
...
<transition on="workIds" to="overview" validate="false">
<evaluate expression="actionBean.workIds(model1.chosenIds)" />
</transition>
java class
public void workIds(List<Long> ids) {
Hope it helps

asp.net mvc 3, dynamic array

I am a beginner in ASP.Net MVC 3
I will make a dynamic array initially must show me the first ten elements, and when I click view more displays all array elements
here's what I did:
<table>
#foreach (var tweet in Model)
{
<tr>
<td>
<img alt="" src="#tweet.ProfileImageUrl" />
<br />
<input id="rowIDs" type="checkbox" />
</td>
<td>
<strong>#tweet.Name</strong>
<br />
Friends: <strong>#tweet.FriendsCount</strong>
</td>
</tr>
}
</table>
thank you in advance
You have to put 10 items in the controller,
return View(array.Take(10).Skip(page));
Do not use the button anymore. Use the pager.
You need to peredovat variable Pag.
The easiest way(on my opinion) is to create a anchor to the page, itself, with a query string.
Your View must have an anchor like this:
All Comments
And relative controller(HttpGet, not HttpPost(if it has any)) must be something like this:
public ViewResult List(bool fullComment=false)
{
if (fullComment)
return View(dbContext.EntityList.ToList());
else
return View(dbContext.EntityList.Take(5).ToList());
}
Note: if the page has querystring already, in creating anchor link, in view, you must pay attention to this.

Resources