简体   繁体   English

如何从 Blazor @code 块中的单选/复选框表单提交中获取数据?

[英]How do I get data from a radio/checkbox form submission in the Blazor @code block?

I am making a quiz/exam page that uses a Question component.我正在制作一个使用问题组件的测验/考试页面。 The questions contain answers with either a checkbox or radio selection and a submit button.问题包含带有复选框或单选选项和提交按钮的答案。 I need to be able to compare the selected answer(s) to the correct answer when a user clicks submit (or some other button type), but I am not sure how to get the value of the input inside of my @code block for processing.当用户单击提交(或其他按钮类型)时,我需要能够将所选答案与正确答案进行比较,但我不确定如何获取我的 @code 块内的输入值加工。

I've messed around with @bind-value but it doesn't seem to relate to the button click at all and I only want the value from one answer, the selected one.我已经搞砸了@bind-value,但它似乎根本与按钮单击无关,我只想要一个答案的值,即选定的答案。

So far using a "submit" button doesn't seem to be the right route because it does a POST request, which is not the behavior I'm looking for.到目前为止,使用“提交”按钮似乎不是正确的路线,因为它执行 POST 请求,这不是我正在寻找的行为。 I just want the button to trigger processing in the component.我只希望按钮触发组件中的处理。

Here is my component这是我的组件

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

and my @code block和我的@code 块

@code {
    public string answer;

    public void OnSubmit()
    {
        System.Console.WriteLine(answer);
    }
}

I want the value from the selection to end up in the variable answer when I click Submit.当我单击提交时,我希望选择的值最终出现在变量answer中。 I realize if there are multiple answers (checkbox) I'll need to change this variable, but I'll get to that later.我意识到如果有多个答案(复选框),我需要更改这个变量,但我稍后会谈到。

@Collin Brittain, understand that no post back should happen in Blazor. @Collin Brittain,了解 Blazor 中不应发生回发。 The behavior you're looking for is available.您正在寻找的行为是可用的。 When you click a button, no post back occurs...Blazor is an SPA app where communication with the outside world is possible only through Http calls or via SignalR.单击按钮时,不会发生回发... Blazor 是一个 SPA 应用程序,只能通过 Http 调用或通过 SignalR 与外界通信。 However, I'd suggest you to use the the Forms Components provided by Blazor.但是,我建议您使用 Blazor 提供的 Forms 组件。 Those components provide a great deal of functionality, including validation.这些组件提供了大量的功能,包括验证。

The following working sample may help you to resolve your issue:以下工作示例可以帮助您解决问题:

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

    }
}

Response to a comment:回复评论:

This quote is from the Blazor team:此报价来自 Blazor 团队:

Currently we don't call preventDefault by default on DOM events in most cases.目前,在大多数情况下,我们默认不会在 DOM 事件上调用 preventDefault。 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.一个例外是表单提交事件:在这种情况下,如果您有一个 C# onsubmit 处理程序,您几乎肯定不想执行服务器端发布,特别是考虑到它会发生在异步事件处理程序之前。

 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.在事件处理程序运行之前。

In the following code snippet the form has onsubmit handler, the result of which is that navigation to the about page is prevented, you are on the page where the form resides, and the HandleClick event handler for the button is executed:在以下代码片段中,表单具有 onsubmit 处理程序,其结果是阻止导航到 about 页面,您位于表单所在的页面上,并且执行按钮的 HandleClick 事件处理程序:

<form action="about:blank" @onsubmit=@(() => { })>
    <button id="form-1-button" @onclick=HandleClick>Click me</button>
</form>

This code snippet, however, causes the app to navigate to the about page.但是,此代码段会导致应用导航到 about 页面。 In other words, the form is submitted.换句话说,表单已提交。 This behavior means that using the button element without assigning the type property is equivalent to using button with type="submit"这种行为意味着在不分配 type 属性的情况下使用按钮元素等同于使用带有 type="submit" 的按钮

<form action="about:blank">
    <button id="form-2-button" @onclick="HandleClick">Click me</button>
</form>

In order to prevent navigation to the about page, and execute the HandleClick event handler add the type attribute with the value "button" as done below:为了防止导航到 about 页面,并执行 HandleClick 事件处理程序,添加值为“button”的 type 属性,如下所示:

<form action="about:blank">
    <button type="button" @onclick="HandleClick" id="form-2-button">Click me</button>
</form>

This code snippet from your question您问题中的此代码段

<button type="submit"@onsubmit="@OnSubmit">Submit</button>

does the following: submit the form instead of calling the OnSubmit event handler of the button element.执行以下操作:提交表单而不是调用按钮元素的 OnSubmit 事件处理程序。

Hope this helps...希望这可以帮助...

Here is the code I came up with to implement a radio button group.这是我想出的实现单选按钮组的代码。

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

It works like a radio button group should and the class is updated as the user click on a button.它的工作原理类似于单选按钮组,并且 class 会在用户单击按钮时更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM