How to initialize the id of a button with a value from model - linq

I am retrieving a list of values using List and I am using for loop. The requirement is here I have two buttons, one to submit and the other to delete a record.When I click btnDelete button I want to delete that particular record.
I am having the object Product as
public partial class Product
{
public int Id { get; set; }
public string Model_Name { get; set; }
public Nullable<int> Price { get; set; }
public Nullable<int> Total_Products { get; set; }
}
Now I want the property Id of the Product to come and sit in the button's Id so that I could retrieve the complete record and delete it using Jquery. I have done with jquery here I just want to assign the button's Id with the value from Model.
I am having the following code
#model List<Shop_Online.com.Models.Product>
<script type="text/javascript">
//some script here
</script>
#using (Html.BeginForm())
{
<div style="width: 860px; margin: 0 auto" class="main">
<table border="1" style="font-family: Verdana; font-size: 13px" class="table">
<tr style="background-color: #f2f2f2; height: 30px">
<th colspan="4">ITEM</th>
<th>DELIEVERY DETAILS</th>
<th>QTY</th>
<th>SUB TOTAL</th>
<th>Remove Items</th>
</tr>
<tbody>
#for(int i=0;i<Model.Count;i++)
{
<tr>
#Html.HiddenFor(x=>x[i].Id)
<td colspan="4" > #Html.DisplayFor(x=>x[i].Model_Name)</td>
<td style="width: 39%">Free Delievery Delivered in 2-3 business days.</td>
<td>#Html.TextBoxFor(x=>x[i].Total_Products)</td>
<td>#Html.DisplayFor(x=>x[i].Price)</td>
<td>
//something like this
//btnDelete
<button type="submit" class="btnDelete" value="x[i].Id" id="x[i].Id"
name="Action">Remove</button></td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit" id="btnPost"/>
</div>
}
If I use foreach loop then I have
#foreach(var item in model) then I can use the following within block as
<button type="submit" class="remove" value="#item.Id" id="#item.Id"
name="Action">Remove</button>
Thanks

As #Mark Shechenko already wrote:
<button type="submit" class="btnDelete" value="#Model[i].Id" id="#Model[i].Id" name="Action">Remove</button>
BUT... If the Id is a number, you have to remember that there are rules for ID and NAME attributes in html, see the answer to this question: What are valid values for the id attribute in HTML?

Related

Join two tables in thymeleaf

I have two tables:
userOrganization (userId, OrganizationId)
user (userId, name, age, ...)
The two tables are linked by userId.
I passed to the model via the controller a list of userOrganization.
In Thymeleaf, I can easily loop on the users to display the userId: it works now.
However, I would also like to display the name of the user table.
Do you have any ideas ?
What I have now:
<div>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
</tr>
</div>
and what I have done but which does not display anything:
<div>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
</tr>
</div>
and controller
#GetMapping("/add")
public String pageCreateCompany(final Model model, Principal principal) {
if (!model.containsAttribute("companyForm")) {
CompanyForm companyForm = new CompanyForm();
model.addAttribute("companyForm", companyForm);
final User userConnected = (User) ((Authentication) principal).getPrincipal();
model.addAttribute("users", this.userOrganizationService.getActiveUsersForOrganization(userConnected));
}
return "company/createCompanyPage";
}
thanks in advance :)
It simply worked with :
<div class="createCompany__container-form-input">
<td> Affectation du personnel </td>
<th:block th:each="user : ${users}">
<input type="checkbox" name="userChecked" th:value="${user.id}"/>
<label th:text="${user.id}"></label><label th:text="${user.user.firstName}"></label>
<br>
</th:block>

spring mvc mapping - send value between controllers

I have got webapp in spring 3 mvc. The case is that I have index page with url, when user click on them should be display another page with details of choosed information. Now the details page is shown but without any information (on index page is creating model with correct variable but not in details controller - in debug mode).
index controller method:
#RequestMapping(value="/{site}", method = RequestMethod.GET)
public String showDetails(#RequestParam(value = "site", required = true) String site, Model model){
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
return "details";
}
index html:
<form action="#" th:object="${product}" method="post" th:action="#{/details}">
<table border="0" width="600" th:each="sb, poz : ${product}" >
<tr >
<td rowspan="3" width="20"><span th:text="${poz.count}"></span></td>
<td>
<a th:href="#{/details/(site=${sb.tytul})}" th:value="${site}"><span th:text="${sb.tytul}"></span></a>
</td>
</tr>
<tr >
<td><span th:text="${sb.adres}"></span></td>
</tr>
<tr>
<td>category:<b><span th:text="${sb.category.name}"></span></b></td>
</tr>
</table>
</form>
details controller method:
#RequestMapping(value = "details/{site}", method = RequestMethod.GET)
public String showHomePage(#PathVariable(value = "site") String site, Model model){
model.addAttribute("product");
return "details";
}
details html:
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="${tytul}"></span></td>
<td>
<span th:text="${opis}"></span>
</td>
<td><span th:text="${adres}"></span></td>
</tr>
</table>
</form>
I don't have any ideas how to map the details site (I tried a lot of solution but nothing). Thanks for help.
With thymeleaf, using th:object, you need to reference the fields of that object with *{}
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="*{tytul}"></span></td>
<td>
<span th:text="*{opis}"></span>
</td>
<td><span th:text="*{adres}"></span></td>
</tr>
</table>
</form>
assuming tytul, opis, and adres are fields of product. Unless it's a type, don't forget
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in your details controller method, otherwise you won't have a Catalog model attribute.
inside your details controller where are you setting product object in your model ?
model.addAttribute("product");
is just settingstring object "product", fetch the product object and set it in details controller like you have done in showDetails method
Change
model.addAttribute("product");
To
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in "showPage" method.

Using a partial view to represent a table row

I am trying to use a partial view to represent rows of a table in my project. I currently have
<table>
<thead>
<tr>
<th >
Column 1
</th>
<th >
Column 2
</th>
<th >
Column 3
</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</tbody>
</table>
In my partial view I have this
#using (Ajax.BeginForm("SaveStuff", "Whatever",
new { id = #Model.Id }, new AjaxOptions()
{
HttpMethod = "Post",
OnSuccess = "Success"
}))
{
#Html.HiddenFor(m => m.Id)
<tr>
<td>
#Html.Label("Col1", Model.Col1)
</td>
<td>
#Html.TextBox("Number", Model.Number)
</td>
<td>
<input type="submit" id='submit-#Model.Id'/>
</td>
</tr>
}
How can I make this work?
You can put a form inside a table cell, but you can't have the form inside a tbody element, or spanning multiple columns. So there are three options:
Use a CSS layout instead of a table, or use divs with CSS display set to "table". (for example)
Put the entire form (TextBox and Submit) inside a td
Put another table inside the td element
I'd recommend #1 -- use a CSS layout to construct the table, since it's difficult to style table tags:
Main
<div class="table">
<div class="header-row">
<div class="header-cell">Column 1</th>
<div class="header-cell">Column 2</th>
<div class="header-cell">Column 3</th>
</div>
#foreach(var item in Model.Items)
{
#Html.Action("ItemCalculatedView", new { Id = item.Id})
}
</div>
Partial
#using (Ajax.BeginForm(
actionName: "SaveStuff",
controllerName: "Whatever",
routeValues: new { id = #Model.Id },
ajaxOptions: new AjaxOptions
{
HttpMethod = "Post",
OnSuccess = "Success"
},
htmlAttributes: new { #class = "row" }
))
{
<div class="cell">
#Html.HiddenFor(m => m.Id)
</div>
<div class="cell">
#Html.Label("Col1", Model.Col1)
</div>
<div class="cell">
#Html.TextBox("Number", Model.Number)
</div>
<div class="cell">
<input type="submit" id='submit-#Model.Id'/>
</div>
}
CSS
.table { display: table; }
.header-row, row { display: table-row; }
.header-cell, cell { display: table-cell; }
You have several issues here. First, as dbaseman mentions, you can't place forms within the structure of a table and have it be legal HTML. It may work, or it might not, and even if it does work, you can't guarantee it will continue to work.
I would instead wrap your table in the form, and then on the post figure out which button was pressed based on its value and/or index.
I would strongly advise against using css tables for tabular data. It's just not semantically correct.
Another possible solution is, instead of using the Ajax.BeginForm, instead use jQuery $.ajax and then you can select a row of data in javascript to post to the server.

How to modify a record displaying a form in a view

I am trying to accomplish the following:
I have a list of fruits, that are stored in a table with two columns "id", "name" and "color".
Next to each fruit, I got a "modify" button. What I want to do here is being able to display the fruit in a form and being able to modify the "name" and "color" attributes.
I don't understand why, but when I click the "modify" button, the form is being displayed but the properties of the fruits that I clicked are not.
Here is the code:
Controller:
#RequestMapping(value = "/fruit/modify", method = RequestMethod.POST)
public String modifyFruit( #RequestParam("id") int id, ModelMap model) {
Fruit fruit = fruitManager.getFruitById(id);
model.addAttribute("fruit", fruit);
return "redirect:/modifyfruit";
}
#RequestMapping(value = "/modifyfruit", method = RequestMethod.GET)
public String showAddForm(#ModelAttribute("fruit") Fruit fruit, ModelMap model) {
model.addAttribute("fruit", fruit);
return "/secure/modifyfruit";
}
Here is the modify button that I am displaying next to each fruit in my list:
<td>
<c:url var="modifyUrl" value="/fruit/modify.html"/>
<form id="${fruitForm}" action="${modifyUrl}" method="POST">
<input id="id" name="id" type="hidden" value="${fruit.id}"/>
<input type="submit" value="modify"/>
</form>
</td>
Here is the modifyfruit.jsp that I am using to display the form that I want to populate:
<body>
<form:form method="post" commandName="fruit">
<table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0"
cellpadding="5">
<tr>
<td align="right">Name:</td>
<td><form:input path="title" value="${fruit.name}"/></td>
</tr>
<tr>
<td align="right">Color:</td>
<td><form:input path="color" value="${fruit.color}"/></td>
</tr>
</table>
<br>
<input type="submit" align="center" value="Post Ad">
</form:form>
</body>
Your redirect is simply going to that new URL without any request params being added. Therefore your fruit ID is being discarded, which is why nothing gets displayed.
The redirect seems pointless - why not return the same view name string as the GET version instead?
To redirect with the params, try:
return "redirect:/modifyfruit?id=" + id;
EDIT: just noticed you have added the Fruit to the model - this does not get transferred in a redirect and wouldn't work anyway.

ASP.NET MVC3 Model Binding using IEnumerable (Cannot infer type from)

I have a model class (edited for brevity)
Model Class
public class GridModel
{
public string ItemNumber { get; set; }
public int OnHandQty { get; set; }
}
public class Shipment
{
public string shipTrackingNo {get; set;}
public IEnumerable<GridModel> ItemsShipped { get; set;}
{
cshtml page
#model Namespc.Models.Shipment
<link href="../../Content/CSS/Grid/Grid.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/ECommerce.Grid.js" type="text/javascript"></script>
<div id="_shipmentDetailGrid">
<table class="TableStyle">
<tr class="GridRowStyle">
<td width="130px" ></td>
#foreach (var Item in Model.ItemsShipped)
{
<td width="70px" align="center">
#html.LabelFor(item.OnHandQty) <-- Cannot infer type from usage
</td>
}
</tr>
I want to be able to bind item.OnHandQty that resides in the IEnumerable collection. How can you have a Model class and also an IEnumerable collection of a custom class (or rather you own class)?
Well, what is the type of the items stored in ItemsShipped? You should use the generic version of IEnumerable to indicate what types are stored within it.
If your class was named Item, you would declare it IEnumerable<Item> then, when iterating at run time, ie #foreach (var Item in Model.ItemsShipped), the type of Item will be strongly-typed instead of a plain object.
Instead of this:
#foreach (var Item in Model.ItemsShipped)
{
<td width="70px" align="center">
#html.LabelFor(item.OnHandQty) <-- Cannot infer type from usage
</td>
}
Do this:
#Html.DisplayFor(model => model.ItemsShipped)
Then create a custom display template (placed in Views/Shared/DisplayTemplates/GridModel.cshtml):
#model Namespc.Models.GridModel
<td width="70px" align="center">
#html.LabelFor(model => model.OnHandQty)
</td>
I've got a feeling it's not working because you're not passing an expression to the LabelFor method.
The above is much nicer and robust than an explicit for loop.

Resources