I have this table and shows values from the server.
How I can with jquery add a new row in this table if I want to send values from the table to the Server
<table id="Products" class="Products">
<tr>
<th>ProductId</th>
<th>Productname</th>
<th>Quantity</th>
<th>UnitPrice</th>
</tr>
@for (int i = 0; i < Model.NorthOrderDetails.Count; i++)
{
<tr>
@Html.HiddenFor(m => m.NorthOrderDetails[i].ProductID)
@Html.HiddenFor(m => m.NorthOrderDetails[i].ProductName)
<td>@Html.DisplayFor(m => m.NorthOrderDetails[i].ProductID)</td>
<td>@Html.DisplayFor(m => m.NorthOrderDetails[i].ProductName)</td>
<td><input type="hidden" name="NorthOrderDetails.Index" value="@i" /> </td>
<td> @Html.TextBoxFor(m => m.NorthOrderDetails[i].Quantity) </td>
<td> @Html.TextBoxFor(m => m.NorthOrderDetails[i].UnitPrice, String.Format("{0}", Model.NorthOrderDetails[i].UnitPrice))</td>
<td>
<button type="button" class="delete" data-id="@Model.NorthOrderDetails[i].ProductID">Delete</button></td>
</tr>
}
</table>
You can use the BeginCollectionItem html helper a partial view for your model to generate collection items with unique indexers and allow binding to the collection on post back. Note you have not indicate the type of property NorthOrderDetails
, but form your previous questions, I assume its NorthOrderDetails.cs
Create a partial for NorthOrderDetails.cs
Views/YourController/_NorthOrderDetails.cshtml
@model NorthOrderDetailscs
@using(Html.BeginCollectionItem())
{
<tr>
@Html.HiddenFor(m => m.ProductName)
<td>@Html.DisplayFor(m => m.ProductID)</td>
<td>@Html.DisplayFor(m => m.ProductName)</td>
<td>@Html.TextBoxFor(m => m.Quantity)</td>
<td>@Html.TextBoxFor(m => m.UnitPrice)</td>
<td>
<button type="button" class="delete" data-id="@Model.ProductID">Delete</button>
@Html.HiddenFor(m => m.ProductID)
@Html.HiddenFor(m => m.ProductName)
</td>
</tr>
}
Side notes:
- Do not include the hidden input for the
Index
- An
<input>
is not a valid child of a <tr>
element (place the hidden inputs inside a <td>
element
String.Format("{0}", Model.NorthOrderDetails[i].UnitPrice
does
absolutely nothing (If you wanted to to format it as (say) currency, then
it would be @Html.TextBoxFor(m => m.UnitPrice. "{0:C}")
)
You can now remove the for
loop in the main view and replace with
<table id="Products" class="Products">
<thead>
<tr>
<th>ProductId</th>
<th>Productname</th>
<th>Quantity</th>
<th>UnitPrice</th>
</tr>
</thead>
<tbody>
@foreach(var item in Model.NorthOrderDetails)
{
@Html.Partial("_NorthOrderDetails", item)
}
</tbody>
</table>
This will generate a bit of extra html (the indexers for the existing items are a Guid
rather than an int
) but it means you only have one place to maintain your code.
Then in the main view, add the following script for your 'Add' button
<button type="button" id="add">Add</button>
<script>
var tableBody = $('#Products tbody');
var url = '@Url.Action("Add", "YourControllerName")'; // adjust to suit
$('#add').click(function() {
$.get('url, function(response) {
tableBody.append(response);
});
});
</script>
And the controller method
public PartialViewResult Add()
{
var model = new NorthOrderDetailscs();
return PartialView("_NorthOrderDetails");
}
Finally, if you are using client side validation (jquery-validate-unobtrusive.js), and @Html.ValidationMessageFor()
with your properties, then you need re-parse the validator each time you add new elements to the DOM as explained in this answer.