Below is the sample.
I am trying to show questions on Next/Previous.
Below is the blazor web page.
Which has C# code & HTML.
@page "/Quiz"
<table class="table">
<thead>
<tr>
<th>
<h3>Question : @currentCount.ToString()</h3>
</th>
</tr>
</thead>
<tbody>
@foreach (var question in exam.Questions.Where(x => x.Id == currentCount.ToString()))
{
<tr>
<th>
<h3>@question.Text</h3>
</th>
</tr>
@foreach (var choice in question.Choices)
{
<tr>
<th>
<label>
<input type="radio" name="@question.Id" value="@question.Id" />
@choice.Text
</label>
</th>
</tr>
}
}
</tbody>
</table>
<button class="btn btn-primary" @onclick="NextQuestion">Next</button>
<button class="btn btn-primary" @onclick="PreviousQuestion">Previous</button>
@code {
Model.Exam exam = new Model.Exam();
private int currentCount = 1;
protected override void OnInitialized()
{
exam.Id = "1";
exam.Questions = new List<Model.Question>();
Model.Question question1 = new Model.Question();
question1.Id = "1";
question1.Text = "Which data type is used to create a variable that should store text?";
Model.Choice choice1 = new Model.Choice();
choice1.Id = "1";
choice1.Text = "Txt";
Model.Choice choice2 = new Model.Choice();
choice2.Id = "2";
choice2.Text = "str";
Model.Choice choice3 = new Model.Choice();
choice3.Id = "3";
choice3.Text = "myString";
Model.Choice choice4 = new Model.Choice();
choice4.Id = "4";
choice4.Text = "string";
question1.Choices = new List<Model.Choice>() { choice1, choice2, choice3, choice4 };
exam.Questions.Add(question1);
Model.Question question2 = new Model.Question();
question2.Id = "2";
question2.Text = "Which property can be used to find the length of a string?";
choice1 = new Model.Choice();
choice1.Id = "1";
choice1.Text = "getLength()";
choice2 = new Model.Choice();
choice2.Id = "2";
choice2.Text = "length";
choice3 = new Model.Choice();
choice3.Id = "3";
choice3.Text = "Length";
choice4 = new Model.Choice();
choice4.Id = "4";
choice4.Text = "length()";
question2.Choices = new List<Model.Choice> { choice1, choice2, choice3, choice4 };
exam.Questions.Add(question2);
}
private void NextQuestion()
{
currentCount++;
}
private void PreviousQuestion()
{
currentCount--;
}
}
When I try to show all questions in single page. It's working.
I used different name for radio buttons.
What could be the issue. Did I miss anything?
Is it the correct design what I am doing?
I am using blazor web assembly.
Your solution was pretty much working. Only a few things needed to be changed.
You could change the name of your field currentCount
to something like questionIndex
and starting with zero. In the view, you get a single question then by its index like <h3>@exam.Questions[questionIndex].Text</h3>
.
The radio button then gets kind of tricky.
<input type="radio"
name="@exam.Questions[questionIndex].Id"
value="@choice.Id"
@onchange="SelectionChanged"
checked="@(exam.Questions[questionIndex].SelectedChoiceId == choice.Id)"
@key="@(exam.Questions[questionIndex].Id + choice.Id)" />
To update the model, we introduce a method handler for the change event and update the property SelectedChoiceId
of the Question
.
void SelectionChanged(ChangeEventArgs args)
{
exam.Questions[questionIndex].SelectedChoiceId = (String)args.Value;
}
In case a user navigates back and forth, it would be nice to pre-select the input. So, we set the checked property to true if the option is selected.
The @key
attribute controls when Blazor reuses a component. As long as the value of the @key
doesn't change, Blazor assumes that the element is the same. In this case, the key is changed every time a user navigates, which forces Blazor to rerender the entire radio button. This resets the "checked" state that is saved by some browsers.
Putting everything together results in
@page "/Quiz"
<table class="table">
<thead>
<tr>
<th>
<h3>Question : @((questionIndex+1).ToString())</h3>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<h3>@exam.Questions[questionIndex].Text</h3>
</th>
</tr>
@foreach (var choice in @exam.Questions[questionIndex].Choices)
{
<tr>
<th>
<label>
<input type="radio"
name="@exam.Questions[questionIndex].Id"
value="@choice.Id"
@onchange="SelectionChanged"
checked="@(exam.Questions[questionIndex].SelectedChoiceId == choice.Id)"
@key="@(exam.Questions[questionIndex].Id + choice.Id)"
/>
@choice.Text
</label>
</th>
</tr>
}
</tbody>
</table>
<button class="btn btn-primary" @onclick="NextQuestion">Next</button>
<button class="btn btn-primary" @onclick="PreviousQuestion">Previous</button>
@code {
private Model.Exam exam = new Model.Exam();
private int questionIndex = 0;
private void NextQuestion()
{
//keeo boundaries in mind
questionIndex++;
}
private void PreviousQuestion()
{
//keep boundaries in mind
questionIndex--;
}
void SelectionChanged(ChangeEventArgs args)
{
exam.Questions[questionIndex].SelectedChoiceId = (String)args.Value;
}
protected override void OnInitialized()
{
//not changed
//...
}
}
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.