Should I go with [previous SO answer]
No. That answer was for a different scenario where the question had a form with two submit buttons that wanted to do two different actions (and wasn't even the accepted answer to that question).
Your sample screenshot indicates that some javascript/jquery and ajax would solve the issue cleanly.
As you're new to MVC, try to keep it relatively simple. Break up the page into separate parts:
- the containing page
- the edit form
- the list with remove
the edit/list work independently and should be written in a way that they could be put on any other page - the page is just there to contain them and doesn't do much else (obviously your real page will contain more, but add those parts as separate components as well).
1 Create actions for your list and edit forms that return partialviews - just the parts that are needed for that view (self-contained)
controller:
[HttpGet]
public ActionResult AddCost()
{
var model = new Cost();
return PartialView(model);
}
[HttpPost]
public void AddCost(Cost model)
{
if (ModelState.IsValid) {
db.SaveCost(model);...
}
}
form Views/Home/AddCost.cshtml:
@using (Ajax.BeginForm(...
{
<div class='editor-label'>@Html.LabelFor(model=>model.Description)</div>
...etc...
}
I'll leave you to set the Ajax.BeginForm
properties. But make sure the on-success calls reloadCostList()
(see below)
controller
public ActionResult CostList()
{
var model = db.loadCosts(); ...
return PartialView(model);
}
list, Views/Home/CostList.cshtml
@model IEnumerable<ViewModels.Cost>
<table>
<thead>
<tr>
<th>Cost Description</th>
...
<tbody>
@foreach (var cost in Model.Costs)
{
<tr data-id='@cost.Id'>
<td>@Html.DisplayFor(x=>cost.Description)</td>
...
<td><a href='#' class='remove-button'>Remove</a></td>
}
...
2 Create an action + view for the main page with placeholder for the form and calls the list partial-action, eg:
<div id="body">
<div id="formWrapper">
@Html.Action("AddCost")
</div>
<div id="listWrapper">
@Html.Action("ListView")
</div>
</div>
if you already load the data for the page, you can pass it directly to the partial, but there's no need:
@Html.Partial("ListView", Model.Costs)
this allows you to refresh the list via an ajax call, something like:
function reloadCostList() {
$(".listWrapper").load("Home/CostList");
}
(ideally, $.ajax and add some fancy UI to indicate loading)
3 Add a remove action to your controller
[HttpPost]
public void RemoveCost(int id)
{
}
4 Wire up the Remove link
$(function() {
$(".remove-button").click(function() {
var id = $(this).closest("tr").attr("id");
$.post("/Home/RemoveCost/" + id, null, function() {
$(".listWrapper").load("Home/CostList");
// or reloadCostList(); from above
// or:
//$(".listWrapper tr[id=" + id + "]").hide();
});
});
}
rather than re-load the entire list, you could just remove the row (add some fancy UI like fade-out...)