2017-02-02 2 views
1

J'ai une vue partielle à l'intérieur d'un formulaire qui s'ajoute au formulaire chaque fois qu'un bouton est cliqué. C'est une zone de texte avec un ensemble de réponses. Comment puis-je passer mon modèle de la vue au contrôleur, l'ajouter au modèle de liste et le retourner à la vue? ReviewFormViewModel Je passe le ListAdhoc au contrôleur partiel et lui ajoute des éléments, puis je le passe à la vue.Comment passer le modèle de la vue au contrôleur, ajouter des éléments à la liste, passer à la vue

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; } 

} 
contrôleur

pour une vue partielle

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); 
} 

vue partielle et qui utilise le 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> 

} 

vue principale

@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> 

MISE À JOUR: J'ai ajouté le AdhocViewModel.

Ive a ajouté le modèle de vue pour ces propriétés. J'ai un formulaire avec un ensemble de questions et de réponses à répondre. Ceux-ci proviennent de la base de données. J'ai un bouton, sur le clic va générer la vue partielle et ajouter au formulaire (peut être beaucoup). La vue partielle est composée d'une zone de texte (pour toute question entrée), d'un ensemble de réponses (de la base de données) et d'une zone de commentaire. Je ne suis pas sûr de savoir comment gérer cela sur le post (soumettre). Ma tentative consiste à passer le modèle de la vue au contrôleur partiel, ajouter des éléments et le renvoyer à la vue pour le traitement. Je n'ai aucun succès sur le passage des données de modèle

MISE À JOUR 2 Code mis à jour avec l'aide BeginCollectionItem helper. La vue principale ajoutée

+0

Difficile de comprendre ce que vous essayez de faire ici. Non où dans votre partiel avez-vous montré quelque chose concernant les propriétés de 'ListAdhoc' –

+0

Mais vous avez affirmé que les utilisations partielles' ReviewFormViewModel' qui clairement ne sont pas basées sur votre code - il doit être '@model AdhocViewModel' –

+0

Et si ce partiel est pour 'AdhocViewModel' cela n'a aucun sens car' ReviewFormViewModel' contient une collection de 'AdhocViewModel' et afin de générer des contrôles pour une collection, ils doivent avoir des indexeurs et votre partial ne le fera pas. –

Répondre

1

La raison pour laquelle la collection ne lie pas est que le paramètre BeginCollectionItem() doit correspondre au nom de votre propriété. Changer à

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

En outre, vous avez également besoin d'une boucle dans la vue principale de rendre existante AdhocViewModel dans la collection. Même si aucune n'existe initialement, elle est toujours requise au cas où vous devriez retourner la vue car ModelState n'est pas valide. Dans la vue principale inclure

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