MVC update list items
Hi I have a view which displays Invoices
and InvoiceLines
.
@model VectorCheck.ViewModels.InvoiceViewModel
@{
ViewBag.Title = "Invoice Details";
}
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
@Html.ValidationSummary()
<fieldset>
<legend>Invoice</legend>
<table>
<tr>
<th>
Activity ID
</th>
<th>
Invoice Line Amount
</th>
<th>
Payment Type
</th>
<th>
Note
</th>
<th>
</th>
<th>
</th>
<th>
</th>
</tr>
@foreach (var item in Model.InvoiceLines) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
@Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
@Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
<span>Person:</span>
@Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
</td>
<td>
<input type="submit" value="Update" />
</td>
</tr>
}
}
</table>
</fieldset>
}
What I'm wanting is for each InvoiceLine
without going to another screen to be able to change the value in the dropdown list for Person
, click update and get this updated InvoiceLine
in the controller where I can save it.
However when I get to the controller the InvoiceLine
does not contain the values.
Controller method:
[HttpPost]
public ActionResult EditInvoiceLine(InvoiceLine invoiceLine, int id)
{
return View(invoiceLine);
}
Has anyone achieve anything like this on the same page or knows how to do it?
No, I do not want to use jqgrid. I have other functionality which jqgrid isn't suitable for.
InvoiceLine is empty because the controller doesn't know where it's coming from. Also, where is the 'id' coming from? Shouldn't it be 'Personid'? Easiest technique in my opinion would be just to use ajax on the button click and send values using GET through querystrings.
I would use a form per line approach (with or without AJAX). Note this will be easier if you use a non-table-based layout. At a minimum, your submit button will need to share the same table element with the input that you want to post back. Further, you could probably get by with just the line id and the person id, instead of the whole model. Use the line id to fetch the entity from the db, then update the person id and save it. Remove the surrounding form and put a form inside each table element with the dropdown list (moving the submit button as well). Modify the signature of your action to match.
@foreach (var item in Model.InvoiceLines) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Activity.Descriptor)
</td>
<td>
@Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
@Html.DisplayFor(modelItem => item.PaymentType.Name)
</td>
<td>
@using (Html.BeginForm("EditInvoiceLine", new { id => modelItem.InvoiceId } ))
{
<span>Person:</span>
@Html.DropDownListFor(modelItem => item.PersonrId, Model.People as IDictionary<string, IEnumerable<SelectListItem>>, "--- Select ---")
<input type="submit" value="Update" />
}
</td>
</tr>
}
[HttpPost]
public ActionResult EditInvoiceLine( int id, int personId )
{
var line = db.InvoiceLines.SingleOrDefault( id );
line.PersonId = personId;
db.SaveChanges();
return View( line ); // more more likely a model based on the line...
}
精彩评论