我有一个应用程序,它是一个多选调查。问题从数据库加载,答案选择也从数据库加载。我想将响应绑定到模型,但我不确定如何实现这一点。这是我的ViewModel和View:
ViewModels:
public class SurveyViewModel : SurveyViewModelBase
{
public IEnumerable<SectionViewModel> Sections { get; set; }
public DemographicQuestionsModel DemographicQuestions { get; set; }
public string Title { get; set; }
}
public class SectionViewModel
{
public string SectionTitle { get; set; }
public IEnumerable<QuestionAnswerViewModel> QAs { get; set; }
}
public class QuestionAnswerViewModel
{
public QuestionViewModel Question { get; set; }
public AnswerViewModel SelectedAnswer { get; set; }
public IEnumerable<QuestionAnswerViewModel> ChildQuestions { get; set; }
}
public class QuestionViewModel
{
public Guid Id { get; set; }
public string Text { get; set; }
public IEnumerable<AnswerViewModel> PossibleAnswers { get; set; }
public int QuestionNumber { get; set; }
}
public class AnswerViewModel
{
public Guid Id { get; set; }
public string AnswerText { get; set; }
}
视图:
@using VSC.ViewModels
@model VSC.ViewModels.SurveyViewModel
@{
SectionViewModel section = Model.Sections.FirstOrDefault();
}
<div class="row">
<div class="sectionTitle">@(section.SectionTitle)</div>
</div>
<form action="/VSC/Survey">
@foreach (var qa in section.QAs)
{
if (qa.Question.QuestionNumber == 0)
{
<div class="row question">
@qa.Question.Text
</div>
}
else
{
if (qa.ChildQuestions != null)
{
<div class="row question child-question @(qa.Question.QuestionNumber==null?"parent-question":"")">
</div>
}
else
{
<div class="row question @(qa.Question.QuestionNumber==null?"parent-question":"")">
@qa.Question.QuestionNumber @qa.Question.Text
</div>
}
<div class="row answers">
@foreach (var answer in qa.Question.PossibleAnswers)
{
<div class="answer">
@{
<div class="answer">
<label>
@answer.AnswerText
@Html.RadioButtonFor(m=>qa.SelectedAnswer, answer.Id)
</label>
</div>
<div class="answer">
<label>
</label>
</div>
}
</div>
}
</div>
}
}
<input type="submit" value"Submit" />
</form>
当然,这会产生具有所有相同名称的单选按钮,所以当我为给定的问题单击一个单选按钮时,前一个问题单选按钮将取消选中,新问题现在是唯一有选择的问题。
感谢您的帮助。
您需要在每个ienumerable的输入字段中指定索引。如果您使用for loop
会更好,但使用当前的代码可以这样做;
请参阅下面的代码,在其中创建索引变量,然后手动创建带有索引的单选按钮。
@foreach (var qa in section.QAs)
{
// create the QA index
int indexQA = 0;
if (qa.Question.QuestionNumber == 0)
{
...
}
else
{
...
<div class="row answers">
@foreach (var answer in qa.Question.PossibleAnswers)
{
// create possible answers index
int indexPA = 0;
<div class="answer">
@{
<div class="answer">
// create label for, with index
<label for="QA[@indexQA]PA[@indexPA]">
@answer.AnswerText
</label>
// create radio button, with index
<input type="radio" id="QA[@indexQA]PA[@indexPA]" name="Sections[0].QAs[@indexQA].Question.SelectedAnswer.Id" data-index="QA[@indexQA]" class="possible-answer" value="@answer.Id">
</div>
<div class="answer">
<label>
</label>
</div>
}
</div>
// increment possible answers index
indexPA++;
}
</div>
}
// increment QA index
indexQA++;
}
由于单选按钮具有不同的name
属性,因此它们不会相互分组,因此我们需要制作一个取消选中其他按钮的脚本。
@section scripts{
<script>
$(document).ready(function(){
$(".possible-answer").change(function(){
var dataValue1 = $(this).data("index");
// loop through all possible answers and check their data-index
$(".possible-answer").each(function(){
var dataValue2 = $(this).data("index");
// if they have the same index, they belong to the same group, uncheck
if(dataValue1 == dataValue2)
{
$(this).prop("checked", false);
}
});
// check the current clicked one
$(this).prop("checked", true);
});
});
</script>
}