2014-01-28 3 views
0

В моем проекте у меня есть одно представление, которое динамически заполняется, создавая одну или несколько форм на одном экране/странице. Мне удалось динамически предоставить каждой форме уникальный идентификатор, однако при наличии нескольких форм на одной странице массив всех форм возвращается, когда отправляется только один, и я не знаю, как идентифицировать фактический экземпляр, который отправляется с массив.Несколько динамических форм в одном представлении MVC

вот мой взгляд;

@using Microsoft.AspNet.Identity 
@model IEnumerable<Template.Models.GetQuestionViewModel> 
@{ 
    ViewBag.Title = "View question"; 
    ViewBag.Page = Model.First().PageNumber; 
} 
@Html.AntiForgeryToken(); 
@foreach (var q in Model.OrderBy(o => o.QuestionRanking)) 
{ 
Html.BeginForm("ViewQuestion", "Question", FormMethod.Post, new { @class = "form-horizontal", id = @q.formNumber, role = "form" }); 
var qtype = q.QuestionTypeId; 
<div> 
    <h1>@q.QuestionRanking. @q.Question1</h1> 
</div><div class="form-group"> 
    @switch (qtype) 
    { 
     case 1: 
      // Textbox 
      @Html.TextArea("Answer", q.Answer, new { @class = "form-control", rows="4", cols="10" }) 
      break; 

     case 2: 
      // Dropdown 
      <select class="form-control" id="Answer" name="Answer"> 
       @foreach (var item in q.QuestionOptions.OrderBy(o => o.QuestionOptionRanking)) 
       { 
        if (q.Answer == item.QuestionOption1) 
        { 
         <option value="@item.QuestionOption1" selected>@item.QuestionOption1</option> 
        } 
        else 
        { 
         <option value="@item.QuestionOption1">@item.QuestionOption1</option> 
        } 
       } 
      </select> 
       break; 
... 
    } 
    </div> 
    <input type="hidden" name="QuestionId" value="@q.Id"/
    <div class="form-group"> 
    <div class="col-md-offset-2 col-md-10"> 
     <input type="submit" name="@q.formNumber" class="btn btn-primary" value="Save answer" /> 
    </div> 
</div> 
<br /> 
<hr /> 
**Html.EndForm();** 
} 

И вот мой контроллер;

using System.Web.Mvc; 
using Template.Models; 
using Microsoft.AspNet.Identity; 
using System.Linq; 
using System.Collections.Generic; 
using System; 

namespace Template.Controllers 
{ 
public class QuestionController : Controller 
{ 
    private WebTemplateEntities db = new WebTemplateEntities(); 

    // GET: /Questions/ViewQuestion/5 
    [HttpGet] 
    public ActionResult ViewQuestion(int page = 1) 
    { 
     // If user is not logged in, push them back to Login 
     var userId = User.Identity.GetUserId(); 
     if (userId == null) 
     { 
      return RedirectToAction("Login", "Account"); 
     } 
     // Get the list of Questions and Response options from the database 
     List<GetQuestionViewModel> quest = new List<GetQuestionViewModel>(); 

     var i = 1; // for form array 

     foreach (var item in db.Questions.Where(q => q.PageNumber == page)) 
     { 
      //Check if user has submitted a response 
      var reply = db.Responses.Where(r => r.QuestionId == item.Id && r.UserId == userId).Select(r => r.Answer).ToList(); 
      //If no input, do not look for answers 
      if (reply.Count == 0) 
      { 
       quest.Add(new GetQuestionViewModel() 
       { 
        Id = item.Id, 
        QuestionOptions = db.QuestionOptions 
        .Where(k => k.QuestionId == item.Id) 
        .ToList(), 
        PageNumber = item.PageNumber, 
        Question1 = item.Question1, 
        QuestionRanking = item.QuestionRanking, 
        QuestionTypeId = item.QuestionTypeId, 
        formNumber = "form" + i // for form array 
       }); 
      } 
      else //If user has input answers find them 
      { 
       quest.Add(new GetQuestionViewModel() 
       { 
        Id = item.Id, 
        QuestionOptions = db.QuestionOptions 
        .Where(k => k.QuestionId == item.Id) 
        .ToList(), 
        PageNumber = item.PageNumber, 
        Question1 = item.Question1, 
        QuestionRanking = item.QuestionRanking, 
        QuestionTypeId = item.QuestionTypeId, 
        formNumber = "form" + i, // for form array 
        Answer = reply.First() 
       }); 
      }   
      i++; // for form array 
     } 
     return View(quest); 
    } 

    // POST: /Questions/ViewQuestion/5 
    [HttpPost] 
    public ActionResult ViewQuestion([Bind(Include = "QuestionId, Answer, UserId")] ResponseViewModel responseViewModel) 
    { 
     // Get page and question id 
     var page = System.Web.HttpContext.Current.Request["page"]; //NOTE: Problem with binding on multi form pages 
     var qId = System.Web.HttpContext.Current.Request["QuestionId"]; //NOTE: Problem with binding on multi form pages 
     var newAnswer = System.Web.HttpContext.Current.Request["Answer"]; 
     int a = Convert.ToInt32(qId); //NOTE: Problem with binding on multi form pages 

     //Check if user has previously answerer 
     List<Response> reply = new List<Response>(); 
     reply = (from r in db.Responses 
        where r.QuestionId == a && r.UserId == responseViewModel.UserId 
        select r).ToList(); 

     // If this is the first time the user has answered, add the response 
     if (reply.Count() == 0) 
     { 
      Response re = new Models.Response(); 
      re.Answer = responseViewModel.Answer; 
      re.UserId = responseViewModel.UserId; 
      re.QuestionId = responseViewModel.QuestionId; 
      re.Source = "Web"; 
      re.Status = "New"; 
      re.DateStamp = System.DateTime.Now; 
      db.Responses.Add(re); 
      db.SaveChanges(); 
     } 
     else // If the user has already answered move the original responses to AuditTrail 
     { 
      var ans = reply.Select(r => r.Id).First(); 
      var dos = reply.Select(r => r.Answer).First(); 
      AuditTrail au = new Models.AuditTrail(); 
      au.ResponseId = ans; 
      au.OriginalData = dos; 
      au.DateChanged = System.DateTime.Now; 
      db.AuditTrails.Add(au); 
      db.SaveChanges(); 

      // Update user's response 
      var stat = "Update, 1"; // NOTE: Work in progress; create array of updates to track number of updates 
      var updateAnswer = db.Responses.Single(q => q.Id == ans); 
      updateAnswer.Answer = newAnswer; 
      updateAnswer.Status = stat; 
      db.SaveChanges(); 
     } 
      return RedirectToAction("ViewQuestion/" + page); 
    } 
    } 
} 

Есть еще вопросы типа типа, но я оставил их для ясности.

При наличии более одного вопроса и ответа на экран действие post возвращает массив всех форм на странице. Из моих первоначальных исследований я не вижу, как определить, какая конкретная форма подана, поэтому я не знаю, как вывести правильный ответ.

Есть ли способ?

ответ

0

Существует концепция под названием PartialView в MVC. Вы можете использовать это, чтобы отображать несколько форм на одной странице.

+0

Итак, я бы поместил форму в частичный вид и дал каждому частичному виду форму уникального имени? Я не уверен, что получаю, как это сделать. Можете ли вы указать мне пример, пожалуйста? – Alex

0

Как абсолютно глупо я себя чувствую !! Я не закрыл форму!

Для тех из вас, кто борется с той же проблемой, просто закройте Html.EndForm();

Я поместил его сразу после последней строки на мой взгляд и теперь возвращает только значения из представленной формы.

И мой босс заметил это ..... Не хороший день!

Смежные вопросы