如何在 Blazor 中启用/禁用输入

75

我正在尝试根据一个 checkbox启用/禁用 一组Blazor中的时间输入; 对于类型为buttoninputs,下面的解决方案可以工作,但对于类型为timeinputs却不能:

适用于按钮输入的解决方案:

<button type="button" class="@this.SetButton"></button>

[Parameter] public bool state { get; set; }

public string SetButton() {
    string result = state ? "" : "disabled";
    return result;
}

无法正常工作的时间输入尝试:

<input bind="@IsDisabled" type="checkbox" />                      
<input class="@this.GetGroupState()" type="time" />

protected bool IsDisabled { get; set; }

public string GetGroupState() {
    return this.IsDisabled ? "disabled" : "";
}

P.S.:在第一种情况下,bool作为参数来自另一个component,因此我不进行绑定。然而,在第二种情况下,它与checkbox绑定。

11个回答

151

要禁用元素,应使用disabled属性

我稍微修改了您的代码,这将实现您想要的功能。Blazor会根据IsDisabled值自动添加或删除disabled属性。

您还应在按钮上使用禁用属性。这是更好的做法。

<button type="button" disabled="@IsDisabled"></button>
<input @bind="IsDisabled" type="checkbox" />

<input disabled="@IsDisabled" type="time" />

@code{
    protected bool IsDisabled { get; set; }
}

你仍然可以将其与应用 CSS 类来为禁用的元素进行样式设置相结合。这取决于你。


38
是的,Blazor 会使 disabled="false" 消失。需要一点时间来适应。 - H H
6
这个答案肯定是正确的——我只想指出使用“disabled”属性并不是一个安全的方法来防止表单数据被编辑或保存,因为用户可以轻松地在客户端修改HTML以删除“disabled”属性,然后修改字段。 - GregH
3
@GregH是正确的,如果控件被禁用,你应该将其呈现为一个不可编辑的元素,例如标签,这样可以防止客户端篡改。 - Mister Magoo
3
已经修复。为了便于以后的读者理解,实际上在属性中使用变量时是否使用引号并不重要。你正在编写 Razor 而不是 HTML。所以 disabled="@IsDisabled"disabled=@IsDisabled 都是完全有效的。 - Chris Sainty
2
@Uxonith 只有当元素具有可禁用的功能(例如点击)时,Disabled 才有效。li 元素没有动作函数,它们只是一种显示内容的方式。我建议在你的 li 中放置一个按钮并删除 OnClick。为了提高可访问性等方面的考虑,最好不要改变 HTML 语义。 - Chris Sainty
显示剩余6条评论

15

有一种替代方法可以实现这一点。

<fieldset disabled=@ShouldBeDisabled>
  Your input controls in here will be disabled/enabled by the browser
</fieldset>

13

你也可以将禁用按钮的值直接作为表达式获取

<input disabled="@(MyCondition ? true : false)" type="checkbox" />     

5
真:假的目的是什么?这不就是MyCondition一开始的值吗? - jonas
3
没错,我不认为三元运算符有什么意义。只需要使用 @MyCondition 就可以了。 - Bennyboy1973

10

引号可以起到至关重要的作用,至少在服务器预渲染期间是这样:

a)没有引号 - 当disable参数被评估为false时,它将被删除。这将按预期工作:

<input disabled=@(IsDisabled) ...
b) 使用引号 - 它会向参数添加“True”或“False”的值,例如disabled="True"disabled="False"。在浏览器寻找参数而不是值时,它将保持禁用状态。
<input disabled="@(IsDisabled)" ... 

4

根据上面的答案参考,a) 不使用引号

<input disabled=@(IsDisabled) ...

如果您将IsDisabled设置为true,上述行不会禁用输入。
通过添加!IsDisabled来解决。
Blazor Input Control

<InputText @bind-Value="UserModel.UserName" id="userName" class="form-control" disabled=@(!IsDisabled) />

这段代码是一个HTML输入框,它的id为"userName",class为"form-control",并且根据变量IsDisabled的值来判断是否可用。当可用时,输入框将可编辑,并且绑定到名为UserModel的模型中的属性UserName。
HTML Input Control

<input disabled=@(!IsDisabled) ...


3

添加disabled并不是一个好的解决方案,因为客户端可以检查页面并删除该属性。我认为最好的解决方案是使用value而不是@bind来添加disabled并移除双向绑定。

@if (IsDisabled)
{
    <input type="checkbox" value="@Value" disabled />
}
else
{
    <input type="checkbox" @bind="Value" />
}

现在,即使用户删除了disabled属性,该值也可以更改,但不会更新。

我更喜欢将所有输入组件放入它们自己的组件中,该组件继承InputBase以进行双向绑定,同时处理如上所述的IsDisabled


1

Blazor不会让disabled="false"消失。这个说法是不正确的!唯一的方法是使用像这样的if语句。

@if (IsDisabled)
{
    <input type="checkbox" @bind="Value" disabled />
}
else
{
    <input type="checkbox" @bind="Value" />
}

应该是 @bind = "IsDisabled" - Sith2021
@Sith2021,你完全没有跟上这整个讨论。他们正在讨论将“disabled”属性添加到HTML元素中。 - JohnB

1
我已经简化了完整的代码 - 工作正常!
Test Cases:
By default checkbox is unchecked, and submit button is disabled.
When checkbox checked, submit button enabled
When checkbox un-checked, submit button disabled 

<div class="card">
    <div class="card-header">Final Submission</div>
    <div class="card-body">

        <div class="form-check">
            <input id="xbrlfinal" class="form-check-input" type="checkbox" bind="@IsAcknowledged" 
            @onchange="@((args) => IsAcknowledged = (bool)args.Value)">
            <label class="form-check-label" for="flexCheckDefault">
                I hereby declare that I have checked and verified.
            </label>
        </div>

    </div> <!-- Main Card body ends -->
    <div class="card-footer text-muted">
        <div class="d-grid gap-2 d-md-flex justify-content-md-end">
            <button type="submit" class="btn btn-primary me-md-3" @onclick="OnSubmissionProcess" disabled="@(IsAcknowledged?false:true)">Process</button>

        </div>
    </div>
</div> <!-- Main Card ends --> 

 protected bool IsAcknowledged { get; set; }

0

<input @attributes="@isDisabled"

禁用输入

Dictionary<string, object> isDisabled {get;set;} = new Dictionary<string,object>{{"disabled","disabled"}};

启用输入

IsDisabled = new Dictionary<string, object>();

这对于单个属性来说有点过度了。 - Bennyboy1973
这可能有点夸张,但这是Blazor定义属性的方式。 - Leandro
你不需要使用属性展开来处理 disabled,因为 Blazor 已经内置了对它的支持。请参考 @Chris Sainty 的回答。友情建议:如果你不同意 @Chris Sainty 的观点,那么你已经错了。你应该花些时间去弄清楚为什么。 :D - Bennyboy1973
好的,这个想法是提供解决方案,我认为提供这个方案是不错的,虽然还有其他方法。有多种途径可以实现,假设对某事有疑问的人并不掌握所问之物,因此我认为了解其他解决方法是很好的,而这个方法在Blazor的定义中,你们可以采纳或放弃,这取决于每个人的决定。我告诉你,了解问题的多种替代方案总是有益的。 - Leandro

0

2
这个答案非常误导,因为在处理HTML属性时,Blazor的工作方式有些不同。建议查看此答案:https://dev59.com/JVQI5IYBdhLWcg3w7QHJ#69016913 - Xander Selorm
这并不是误导,它只是错误的。 - Bennyboy1973

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接