如何从 Blazor @code 块中的 radio/checkbox 表单提交中获取数据?
How do I get data from a radio/checkbox form submission in the Blazor @code block?
我正在制作一个使用问题组件的 quiz/exam 页面。这些问题包含带有复选框或单选选项和提交按钮的答案。当用户单击提交(或其他按钮类型)时,我需要能够将 选定的 答案与正确答案 进行比较,但我不确定如何获取我的@code 块内的输入值以进行处理。
我搞砸了 @bind-value 但它似乎与按钮点击根本无关,我只想要一个答案的值,即所选答案。
到目前为止,使用 "submit" 按钮似乎不是正确的路线,因为它执行 POST 请求,这不是我要寻找的行为。我只是想让按钮触发组件中的处理。
这是我的组件
<form>
<div class="q-card">
<h3>@Question.QuestionText</h3>
@foreach (var option in Question.Options)
{
<div>
<input type="@Question.InputType" id="@answer" name="@Question.Id" value="@answer"/>
<label for="@answer">@answer</label>
</div>
}
<div class="q-controls">
<button type="submit"@onsubmit="@OnSubmit">Submit</button>
</div>
</div>
</form>
和我的@code 块
@code {
public string answer;
public void OnSubmit()
{
System.Console.WriteLine(answer);
}
}
当我单击“提交”时,我希望选择的值最终出现在变量 answer
中。我意识到如果有多个答案(复选框),我需要更改此变量,但我稍后再做。
@Collin Brittain,了解在 Blazor 中不应发生 post 返回。您正在寻找的行为是可用的。单击按钮时,不会发生 post 返回...Blazor 是一个 SPA 应用程序,只能通过 Http 调用或 SignalR 与外界通信。但是,我建议您使用 Blazor 提供的表单组件。这些组件提供了大量功能,包括验证。
以下工作示例可以帮助您解决问题:
<form>
<p>@question</p>
@foreach (var item in Enum.GetNames(typeof(Question.Colors)))
{
<div>
<input type="radio" name="question1" id="@item" value="@item" @onchange="SelectionChanged" checked=@(selectedAnswer.Equals(item,StringComparison.OrdinalIgnoreCase)) />
<label for="@item">@item</label>
</div>
}
<div>
<label>Selected answer is @selectedAnswer</label>
</div>
<button type="button" @onclick="@OnSubmit">Submit</button>
</form>
@code {
string selectedAnswer = "";
void SelectionChanged(ChangeEventArgs args)
{
selectedAnswer = args.Value.ToString();
}
Question question = new Question { QuestionText = "What is the color of the sky" };
public void OnSubmit()
{
Console.WriteLine(selectedAnswer);
}
public class Question
{
public string QuestionText { get; set; }
public enum Colors { Red, Green, Blue, Yellow };
}
}
回复评论:
这句话来自 Blazor 团队:
Currently we don't call preventDefault by default on DOM events in
most cases.
The one exception is for form submit events: in that case, if you have a C# onsubmit handler, you almost certainly don't really want to
perform a server-side post, especially given that it would occur
before an async event handler.
Later, it's likely that we'll add a syntax for controlling whether any given event handler triggers a synchronous preventDefault
before the event handler runs.
在以下代码片段中,表单具有 onsubmit 处理程序,其结果是阻止导航到“关于”页面,您位于表单所在的页面上,并且执行按钮的 HandleClick 事件处理程序:
<form action="about:blank" @onsubmit=@(() => { })>
<button id="form-1-button" @onclick=HandleClick>Click me</button>
</form>
但是,此代码段会导致应用导航至“关于”页面。换句话说,表单已提交。此行为意味着在不分配类型 属性 的情况下使用按钮元素等同于使用类型为 "submit"
的按钮
<form action="about:blank">
<button id="form-2-button" @onclick="HandleClick">Click me</button>
</form>
为了防止导航到关于页面,并执行 HandleClick 事件处理程序,添加值为 "button" 的类型属性,如下所示:
<form action="about:blank">
<button type="button" @onclick="HandleClick" id="form-2-button">Click me</button>
</form>
您问题中的这段代码
<button type="submit"@onsubmit="@OnSubmit">Submit</button>
执行以下操作:提交表单而不是调用按钮元素的 OnSubmit 事件处理程序。
希望这对您有所帮助...
这是我想出的实现单选按钮组的代码。
<EditForm Model="cleaningModel" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<div class="form-group">
<p class="csCleanedBox">
Cleaned:
</p>
<p class="csLineCondition">
Line Condition: <br />
<input type="radio" id="0" name="Cleaned" value="0" checked="checked" @onclick="(() => { RadioButtonClicked(0); })">
<label for="0">Not Cleaned</label>
</p>
<input type="radio" id="1" name="Cleaned" value="1" @onclick="(() => { RadioButtonClicked(1); })">
<label for="1">1</label>
<input type="radio" id="2" name="Cleaned" value="2" @onclick="(() => { RadioButtonClicked(2); })">
<label for="2">2</label>
<input type="radio" id="3" name="Cleaned" value="3" @onclick="(() => { RadioButtonClicked(3); })">
<label for="3">3</label>
<input type="radio" id="4" name="Cleaned" value="4" @onclick="(() => { RadioButtonClicked(4); })">
<label for="4">4</label>
<input type="radio" id="5" name="Cleaned" value="5" @onclick="(() => { RadioButtonClicked(5); })">
<label for="5">5</label>
</div>
<button class="btn btn-danger" type="button" @onclick="@BackButton">Cancel</button>
<button class="btn btn-primary" type="submit">Submit</button>
<ValidationSummary />
</EditForm>
@Code
{
public class CleaningDto
{
public int Oid { get; set; }
public int Cleaned { get; set; }
}
private readonly CleaningDto cleaningModel = new CleaningDto();
public void RadioButtonClicked(int value)
{
cleaningModel.Cleaned = value;
}
private void Submit()
{
dm.Save(cleaningModel);
}
}
它的工作方式类似于单选按钮组,当用户单击按钮时 class 会更新。
我正在制作一个使用问题组件的 quiz/exam 页面。这些问题包含带有复选框或单选选项和提交按钮的答案。当用户单击提交(或其他按钮类型)时,我需要能够将 选定的 答案与正确答案 进行比较,但我不确定如何获取我的@code 块内的输入值以进行处理。
我搞砸了 @bind-value 但它似乎与按钮点击根本无关,我只想要一个答案的值,即所选答案。
到目前为止,使用 "submit" 按钮似乎不是正确的路线,因为它执行 POST 请求,这不是我要寻找的行为。我只是想让按钮触发组件中的处理。
这是我的组件
<form>
<div class="q-card">
<h3>@Question.QuestionText</h3>
@foreach (var option in Question.Options)
{
<div>
<input type="@Question.InputType" id="@answer" name="@Question.Id" value="@answer"/>
<label for="@answer">@answer</label>
</div>
}
<div class="q-controls">
<button type="submit"@onsubmit="@OnSubmit">Submit</button>
</div>
</div>
</form>
和我的@code 块
@code {
public string answer;
public void OnSubmit()
{
System.Console.WriteLine(answer);
}
}
当我单击“提交”时,我希望选择的值最终出现在变量 answer
中。我意识到如果有多个答案(复选框),我需要更改此变量,但我稍后再做。
@Collin Brittain,了解在 Blazor 中不应发生 post 返回。您正在寻找的行为是可用的。单击按钮时,不会发生 post 返回...Blazor 是一个 SPA 应用程序,只能通过 Http 调用或 SignalR 与外界通信。但是,我建议您使用 Blazor 提供的表单组件。这些组件提供了大量功能,包括验证。
以下工作示例可以帮助您解决问题:
<form>
<p>@question</p>
@foreach (var item in Enum.GetNames(typeof(Question.Colors)))
{
<div>
<input type="radio" name="question1" id="@item" value="@item" @onchange="SelectionChanged" checked=@(selectedAnswer.Equals(item,StringComparison.OrdinalIgnoreCase)) />
<label for="@item">@item</label>
</div>
}
<div>
<label>Selected answer is @selectedAnswer</label>
</div>
<button type="button" @onclick="@OnSubmit">Submit</button>
</form>
@code {
string selectedAnswer = "";
void SelectionChanged(ChangeEventArgs args)
{
selectedAnswer = args.Value.ToString();
}
Question question = new Question { QuestionText = "What is the color of the sky" };
public void OnSubmit()
{
Console.WriteLine(selectedAnswer);
}
public class Question
{
public string QuestionText { get; set; }
public enum Colors { Red, Green, Blue, Yellow };
}
}
回复评论:
这句话来自 Blazor 团队:
Currently we don't call preventDefault by default on DOM events in most cases. The one exception is for form submit events: in that case, if you have a C# onsubmit handler, you almost certainly don't really want to perform a server-side post, especially given that it would occur before an async event handler.
Later, it's likely that we'll add a syntax for controlling whether any given event handler triggers a synchronous preventDefault
before the event handler runs.
在以下代码片段中,表单具有 onsubmit 处理程序,其结果是阻止导航到“关于”页面,您位于表单所在的页面上,并且执行按钮的 HandleClick 事件处理程序:
<form action="about:blank" @onsubmit=@(() => { })>
<button id="form-1-button" @onclick=HandleClick>Click me</button>
</form>
但是,此代码段会导致应用导航至“关于”页面。换句话说,表单已提交。此行为意味着在不分配类型 属性 的情况下使用按钮元素等同于使用类型为 "submit"
的按钮<form action="about:blank">
<button id="form-2-button" @onclick="HandleClick">Click me</button>
</form>
为了防止导航到关于页面,并执行 HandleClick 事件处理程序,添加值为 "button" 的类型属性,如下所示:
<form action="about:blank">
<button type="button" @onclick="HandleClick" id="form-2-button">Click me</button>
</form>
您问题中的这段代码
<button type="submit"@onsubmit="@OnSubmit">Submit</button>
执行以下操作:提交表单而不是调用按钮元素的 OnSubmit 事件处理程序。
希望这对您有所帮助...
这是我想出的实现单选按钮组的代码。
<EditForm Model="cleaningModel" OnValidSubmit="Submit">
<DataAnnotationsValidator />
<div class="form-group">
<p class="csCleanedBox">
Cleaned:
</p>
<p class="csLineCondition">
Line Condition: <br />
<input type="radio" id="0" name="Cleaned" value="0" checked="checked" @onclick="(() => { RadioButtonClicked(0); })">
<label for="0">Not Cleaned</label>
</p>
<input type="radio" id="1" name="Cleaned" value="1" @onclick="(() => { RadioButtonClicked(1); })">
<label for="1">1</label>
<input type="radio" id="2" name="Cleaned" value="2" @onclick="(() => { RadioButtonClicked(2); })">
<label for="2">2</label>
<input type="radio" id="3" name="Cleaned" value="3" @onclick="(() => { RadioButtonClicked(3); })">
<label for="3">3</label>
<input type="radio" id="4" name="Cleaned" value="4" @onclick="(() => { RadioButtonClicked(4); })">
<label for="4">4</label>
<input type="radio" id="5" name="Cleaned" value="5" @onclick="(() => { RadioButtonClicked(5); })">
<label for="5">5</label>
</div>
<button class="btn btn-danger" type="button" @onclick="@BackButton">Cancel</button>
<button class="btn btn-primary" type="submit">Submit</button>
<ValidationSummary />
</EditForm>
@Code
{
public class CleaningDto
{
public int Oid { get; set; }
public int Cleaned { get; set; }
}
private readonly CleaningDto cleaningModel = new CleaningDto();
public void RadioButtonClicked(int value)
{
cleaningModel.Cleaned = value;
}
private void Submit()
{
dm.Save(cleaningModel);
}
}
它的工作方式类似于单选按钮组,当用户单击按钮时 class 会更新。