简体   繁体   中英

How to pass Model from View to Controller, add items to list, pass back to view

I have a partial view inside a form that append to the form each time a button is clicked. It is a text area with a set of responses. How can I pass my model from the view to the controller, add it to the list model and back to view?

I am passing ReviewFormViewModel I want to pass the ListAdhoc to the partial controller and add items to it then pass it back to the view.

public class ReviewFormViewModel
{
    ...// other fields
    public List<AdhocViewModel> ListAdhoc { get; set; }
}

public class AdhocViewModel
{
    public int? ReviewId { get; set; }
    public String AdhocQuestion { get; set; } //free form
    public int? SelectedAnswer { get; set; } // for binding int? for optional
    public String Comments { get; set; }
    public List<AdhocOptionsVM> ListAdhocOptions { get; set; }
}

public class AdhocOptionsVM
{
    public int AnswerId { get; set; }
    public String RatingName { get; set; }
    public Decimal Rating { get; set; }
    public String ActiveFl { get; set; }

}

controller for partial view

 public PartialViewResult Adhoc()
    {
        //pass model object on button click and add each item to the model everytime
        var AdhocObj = new AdhocViewModel();

        AdhocObj.ListAdhocOptions = new List<AdhocOptionsVM>();
        var query = db.dbQuestionOptions.Where(qo => qo.ActiveFl == "Y").OrderByDescending(qo => qo.Rating).ToList();

        foreach (var item in query)
        {
            var AdhocAnsOptionsVMObj = new AdhocOptionsVM();
            AdhocAnsOptionsVMObj.AnswerId = item.AnswerId;
            AdhocAnsOptionsVMObj.RatingName = item.RatingName;
            AdhocAnsOptionsVMObj.Rating = item.Rating;
            AdhocAnsOptionsVMObj.ActiveFl = item.ActiveFl;

            AdhocObj.ListAdhocOptions.Add(AdhocAnsOptionsVMObj);
        }


        return PartialView("Adhoc", AdhocObj);
}

and partial view that is using the ReviewFormViewModel aswell:

<div class="adhoc">
@using (Html.BeginCollectionItem("adhoc"))
{
    <div class="panel panel-success">
        <div class="panel-heading">
            @Html.HiddenFor(m => m.ReviewId)
            @Html.HiddenFor(m => m.AdhocId)

            @Html.TextAreaFor(m => m.AdhocQuestion, htmlAttributes: new { @style = "width:650px", @placeholder = "Enter Adhoc Question here" })<br />
        </div>
        <div class="panel-body">
            @foreach (var optAnswer in Model.ListAdhocOptions)
            {
                <div class="radio">
                    <responselabel>@Html.RadioButtonFor(m => m.SelectedAnswer, optAnswer.AnswerId, new { id = optAnswer.AnswerId }) @optAnswer.RatingName</responselabel><br />
                </div>
            }
            <div>@Html.ValidationMessageFor(m => m.SelectedAnswer)</div><br />

            @Html.TextAreaFor(m => m.Comments, htmlAttributes: new { @style = "width:650px", @placeholder = "Comments" })<br /><br />
        </div>
        <button type="button" class="delete">Delete</button>
    </div>

}

main view

@model CustomerFeedback.Areas.ProjectManagers.Models.ReviewFormViewModel

@{
    ViewBag.Title = "CreateFormsIndex";
}

<h4 align="center">Project Review Form</h4>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-12">
            <div class="text-center">
                <h4>
                    @Html.DisplayName(Model.ProjectId) @Html.DisplayName(Model.ProjectName)
                </h4>
                <h4>
                    PM: @Html.DisplayName(Model.FullName)
                </h4>
            </div>
        </div>
    </div>
</div>

<div class="container">
    <br />
    <div class="panel-group">
        @using (Html.BeginForm())
        {

            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            @Html.HiddenFor(m => m.ProjectId)
            @Html.HiddenFor(m => m.AccountId)
            @Html.HiddenFor(m => m.ReviewDate)

            <div class="panel panel-default">
                <div class="panel-body">
                    <div class="panel-group">
                        <div class="panel-heading">
                            <h4 class="panel-title">
                                Required Questions
                            </h4>
                        </div>
                        @for (int i = 0; i < Model.ListReqQuestions.Count; i++)
                        {
                            <div class="panel panel-success">
                                <div class="panel-heading">
                                    @Html.HiddenFor(m => m.ListReqQuestions[i].QuestionId)
                                    @Html.DisplayFor(m => m.ListReqQuestions[i].QuestionText)
                                </div>
                                <div class="panel-body">
                                    @foreach (var optAnswer in Model.ListReqQuestions[i].ListQuestionOptions)
                                    {
                                        <div class="radio">
                                            <responselabel>@Html.RadioButtonFor(m => m.ListReqQuestions[i].SelectedAnswer, optAnswer.AnswerId, new { id = optAnswer.AnswerId }) @optAnswer.RatingName</responselabel><br />
                                        </div>
                                    }
                                    <div>@Html.ValidationMessageFor(m => m.ListReqQuestions[i].SelectedAnswer)</div><br />

                                    @Html.TextAreaFor(m => m.ListReqQuestions[i].Comments, htmlAttributes: new { @style = "width:650px", @placeholder = "Comments" })<br /><br />
                                </div>
                            </div>
                        }

                        <div class="panel-heading">
                            <h4 class="panel-title">
                                Optional Questions
                            </h4>
                        </div>
                        @for (int i = 0; i < Model.ListOpQuestions.Count; i++)
                        {
                            <div class="panel panel-success">
                                <div class="panel-heading">
                                    @Html.HiddenFor(m => m.ListOpQuestions[i].QuestionId)
                                    @Html.DisplayFor(m => m.ListOpQuestions[i].QuestionText)
                                </div>
                                <div class="panel-body">
                                    @foreach (var optAnswer in Model.ListOpQuestions[i].ListQuestionOptions)
                                    {
                                        <div class="radio">
                                            <responselabel>@Html.RadioButtonFor(m => m.ListOpQuestions[i].SelectedAnswer, optAnswer.AnswerId, new { id = optAnswer.AnswerId }) @optAnswer.RatingName</responselabel><br />
                                        </div>
                                    }
                                    <div>@Html.ValidationMessageFor(m => m.ListOpQuestions[i].SelectedAnswer)</div><br />

                                    @Html.TextAreaFor(m => m.ListOpQuestions[i].Comments, htmlAttributes: new { @style = "width:650px", @placeholder = "Comments" })<br /><br />
                                </div>
                            </div>
                        }
                        @*on click (new adhoc question) add a new freeform question with list of answers*@
                        <div class="panel panel-success" id="adhoc">
                            @* renders partial adhoc view *@
                        </div>
                        <br />
                        <div class="center">
                            <input type="button" value="New Adhoc Question" class="btnAdhoc btn-success" />
                        </div>
                        <br />
                        <div class="center">
                            <input type="submit" value="Save" name="Command" class="btn btn-success" />
                            <input type="submit" value="Submit" name="Command" class="btn btn-success" />
                            <input type="submit" value="Cancel" name="Command" class="btn btn-success" />
                            <input type="submit" value="Attach" name="Command" class="btn btn-success" />
                        </div>

                    </div>
                </div>
            </div>
        }
    </div>
</div>

<script>

    $(function () {

        $('.btnAdhoc').click(function (event) {
            event.preventDefault();

            $.ajax({
                url: '/ProjectManagers/Forms/Adhoc',
                //data: JSON.stringify(model),
                type: 'get',
                success: function (result) {
                    $('#adhoc').append(result);
                }
            });
        });
    })
</script>

UPDATE: I've added the AdhocViewModel.

Ive added the view model for those properties. I have a form with a set of questions and responses to be answered. Those are from the database. I have a button, on click will generate the partial view and append to the form (can be many). The partial view consists of a text area (for any question entered), set of responses (from database) and a comment box. I am not sure how to handle this on post (submit). My attempt is to pass the model from the view to the partial controller, add items to it and pass it back to the view for processing. I am not have any success on passing model data

UPDATE 2 Updated code with using BeginCollectionItem helper. Added main view

The reason that the collection does not bind is because the parameter in BeginCollectionItem() must match the name of you property. Change it to

@using (Html.BeginCollectionItem("ListAdhoc")) // binds to List<AdhocViewModel> ListAdhoc

In addition you also need a loop in the main view to render existing AdhocViewModel in the collection. Even if none exist initially, it is still required in case you need to return the view because ModelState is invalid. In the main view include

<div class="panel panel-success" id="adhoc">
    @foreach(var item in Model.ListAdhoc)
    {
        @Html.Partial("Adhoc", item)
    }
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM