0

I have a model of type List<ReviewGroupViewModel> where ReviewGroupViewModel is:

public class ReviewGroupViewModel
{
    public string Country { get; set; }
    public List<Review> Reviews { get; set; }
}

In my Index.cshtml view, I iterate through this model using nested for-loops and build a table for each ReviewGroupViewModel, grouped by ReviewGroupViewModel.Country. I ultimately have a row in my table for each Review object. The Commentary field for each row is displayed using a TextAreaFor HTML helper, allowing users to enter text:

Index.cshtml

@using (Html.BeginForm("Save", "Review", FormMethod.Post))
{
    for (var i = 0; i < Model.Count; i++)
    {
        <h6>@Html.DisplayFor(m => m[i].Country)</h6>
        <table class="table table-bordered table-condensed">
            <tr>
                <th style="text-align: center">
                    @Html.DisplayNameFor(m => m[i].Reviews[0].Commentary)
                </th>
                <th style="text-align: center">
                    Actions
                </th>
            </tr>
            @for (var j = 0; j < Model[i].Reviews.Count; j++)
            {
                <tr>
                    <td style="text-align: center">
                        @Html.TextAreaFor(m => m[i].Reviews[j].Commentary)
                    </td>
                    <td style="text-align: center">
                        @Html.ActionLink("Edit", "Edit", new { tempId = Model[i].Reviews[j].TempId }) |
                        @Html.ActionLink("Delete", "Delete", new { tempId = Model[i].Reviews[j].TempId })
                    </td>
                </tr>
            }
        </table>
    }
}

This is bounded by a form that is submitted on-click of a "save" button elsewhere on the page.

Now let's say a user types some text into one (or many) of the textareas in the Index view and then proceeds to click on "Edit" in the "Actions" for a given table row. This text is then lost as I'm simply passing an Id (type: int) to my Edit controller method. The question is, how do I not lose this entered text (for both this Review object and all others in the Index view) when navigating to other views for actions like editing/deleting?

AFAIK, you can't directly pass a complex object from a view to a controller method. You also obviously can't nest HTML forms. Surely this is a common scenario but how do I handle it in code?

illya
  • 377
  • 5
  • 17
  • But this is an edit form (your editing the `Commentary` property) so why are you navigating to a new view to edit it again? –  Oct 03 '15 at 01:25

2 Answers2

0

Your problem is the ActionLink. It generates a simple hyperlink. A hyperlink will send a GET request to the server. And you cannot put complex objects in the body of a GET request.

You need to do this: Form with 2 submit buttons/actions

Community
  • 1
  • 1
makzr
  • 355
  • 2
  • 7
0

The code inside your 'for' loop should be placed into an editor template.

@using (Html.BeginForm("Save", "Review", FormMethod.Post))
{
    for (var i = 0; i < Model.Count; i++)
    {
        @Html.EditorFor(m => Model[i], "MyTemplateName");
    }
}

Create a folder named EditorTemplates inside your View folder and create a View called MyTemplateName. Inside it you have the code for each single item of the iteration by passing a single model to the view.

MyTemplateName.cshtml

@model Review

<h6>@Html.DisplayFor(m => m.Country)</h6>
        <table class="table table-bordered table-condensed">
            <tr>
                <th style="text-align: center">
                    @Html.DisplayNameFor(m => m.Reviews[0].Commentary)
                </th>
                <th style="text-align: center">
                    Actions
                </th>
            </tr>
            @for (var j = 0; j < m.Reviews.Count; j++)
            {
                // Here you should have different editor template... see the pattern :)
                @Html.EditorFor(m => m.Reviews[j], "MySecondTemplate")
            }
        </table>

Hope this information can help you.

George Findulov
  • 769
  • 6
  • 16
  • Thanks George, got thrown off by the `@model Review` in your MyTemplateName.cshtml. I believe that should be `@model ReviewGroupViewModel` in my case? – illya Oct 02 '15 at 18:51
  • In `MySecondTemplate` what would I be passing to the controller? I still won't be able to pass the object right? – illya Oct 02 '15 at 19:11