0

I have taken over support of an MVC application, but unfortunately have pretty much zero experience or knowledge of MVC, so I apologise in advance if this is a stupid question.

We are placing every single result into a listed item in the HTML, then hiding all but one record, so you can filter through the different entries using First/Prev/Next/Last buttons, all via jQuery:

$("a#next").on("click", function () {
  var nextli = $("li.first");
  if ($(nextli).is(":last-child")) {
     return false;
  }
  nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
});
$("a#previous").on("click", function () {
  var nextli = $("li.first");
  if ($(nextli).is(":first-child")) {
     return false;
  }
  nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
});

This is fine, and displays the records without any problem, however when you try to edit any record but the first, you get a "System.ArgumentNullException: Value cannot be null." error.

Here's the code in the controller for the edit function:

[HttpPost]
public ActionResult Edit(RecordsView rv)
{
    if (ModelState.IsValid)
    {
        repository.EditRecord(rv.Records.FirstOrDefault().DogIncident);
    }

    return RedirectToAction("Index");
}

This is defined at the start of the cshtml file:

@using (Html.BeginForm("Edit", "Home", FormMethod.Post,new {@class="record-view"}))

And finally, here is how the HTML is generated on the view:

<li class="first" id="record-1805">
    <form action="/Home/Edit" class="record-view" method="post">
        <ul>
            [form elements]
            <li><input type="submit" style="margin: 18px 0;" value="Save"></li>
        </ul>
    </form>
</li>

<li class="record" id="record-1804">
    <form action="/Home/Edit" class="record-view" method="post">
        <ul>
            [form elements]
            <li><input type="submit" style="margin: 18px 0;" value="Save"></li>
        </ul>
    </form>
</li>

<li class="record" id="record-1803">
    <form action="/Home/Edit" class="record-view" method="post">
        <ul>
            [form elements]
            <li><input type="submit" style="margin: 18px 0;" value="Save"></li>
        </ul>
    </form>
</li>

Does anyone please know why I can only edit the first record that is displayed and not the others? Even if I go through the records using the next/back buttons and back to the first record to submit it, it updates fine, but updating any other record generates an error.

Nick
  • 3,745
  • 20
  • 56
  • 75

1 Answers1

1

Referencing Darin's post: Pass a parameter to a controller using jquery ajax takes you halfway. He's using an input val in jQuery and passing it to the Controller Action.

Typically you'd provide one input link or @Html.ActionLink per record to be clicked for editing and MVC will bind to the controls parameter to your action (ID or what ever you want) just use the same name on the action link as the parameter and it will be mapped during the post.

data: { input: $('#caption').val() },

Change the signature of your controller action , or add another that takes an 'int' as shown below.

[HttpPost]
public ActionResult Edit(int ID = 0)
{
    if (ModelState.IsValid)
    {
        repository.EditRecord(rv.Records.Where(r => r.ID == ID).DogIncident);
    }

    return RedirectToAction("Index");
}

Can you post the complete view so we can complete a solution ? Was expecting the cshtml view. Here's an example:

@model IEnumerable<yourModelName>
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.NID)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CreatedOn)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ExtensionAttribute15)
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.yourElement1)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.yourElement2)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
        </td>
    </tr>
}
    </table>
@section Scripts{
    <script type="text/javascript">
        $("a#next").on("click", function () {
            var nextli = $("li.first");
            if ($(nextli).is(":last-child")) {
                return false;
            }
            nextli.removeClass("first").addClass("record").next().addClass("first").removeClass("record");
        });
        $("a#previous").on("click", function () {
            var nextli = $("li.first");
            if ($(nextli).is(":first-child")) {
                return false;
            }
            nextli.removeClass("first").addClass("record").prev().addClass("first").removeClass("record");
        });
    </script>
}
Community
  • 1
  • 1
StevoKeano
  • 717
  • 6
  • 13
  • Thank you Stevo, I have updated my original post with the full HTML that is being generated – Nick Jan 15 '14 at 09:51
  • 1
    Was hoping for the view.cshtml... I left the control attribute decoration out as I don't fully see where your applying "a#previous" etc. cheers. – StevoKeano Jan 16 '14 at 08:29