Reputation: 5839
Blazor vRC1
I'm looking for a straightforward technique on how to conditionally render an attribute within an <InputText>
(or any of the input components for that matter). This used to be simple in MVC Razor, where you'd just write the conditional logic within the @(...)
statement. Now, writing @(...)
has different meaning in the Razor syntax.
For example, I'd like to conditionally output the autofocus
HTML attribute for InputText
.
<InputText
@bind-Value="@TextProperty"
@(MyModel.isAutoFocus ? "autofocus" : "") <- This is invalid razor syntax!
/>
Upvotes: 29
Views: 23858
Reputation: 15759
To add or remove HTML attribute via Blazor logic, I suggest you use the "attribute splatting" feature (<input @attributes=... />
) built into Microsoft Blazor.
Why? Its better to modify the attributes dictionary on the element for all attributes assigned to your <input>
and using the event OnInitialized()
, rather than cobbling attributes inside the HTML, as the @attributes
collection could have custom attributes assigned to the component in its tag helper or added elsewhere via the @attributes
value on prerender events that get erased or conflict. This code below makes sure your attributes are added into the pipeline of processes for all attributes assigned to your HTML element that the @attributes
feature manages.
<input @attributes="MyAttributes" />
@code {
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> MyAttributes { get; set; }
protected override void OnInitialized()
{
// CONDITIONALLY ADD/REMOVE AN HTML ATTRIBUTE
// Remove
if (MyAttributes.ContainsKey("style"))
{
if ({Add Your Conditional Logic Here})
{
MyAttributes.Remove("style");
}
}
// Add
if ({Add Your Conditional Logic Here})
{
var MyAttributes = new Dictionary<string, object> {{"data-helloworld", "Hello World!"}};
// This adds your new attribute created above,
// BUT prevents duplicates by honoring the first
// or original attribute, if it exists.
MyAttributes = MyAttributes.Concat(newAttribute)
.GroupBy(i => i.Key)
.ToDictionary(g => g.Key, g => g.First().Value);
}
}
}
}
Btw...I use these techniques to force a single name-value attribute pair into HTML when modifying a Blazor component. It's not pretty, but it's all we are stuck with using their "attribute splatting" model.
This code below becomes <div style="color:blue;">Blue Text</div>
:
<div @attributes="MyCSS">Blue Text</div>
@code {
private Dictionary<string,object> MyCSS{ get; set; } =
new Dictionary<string,object> {{ "style","color:blue;" }};
}
If you just want to update a known attribute value in Blazor, you can also do this:
<div style="@MyCSS">Blue Text</div>
@code {
private string MyCSS= "color:blue;";
}
Upvotes: 1
Reputation: 326
This could potentially be achieved with the @attributes tag. See more here
Basically, you can add an @attributes tag to your InputText. This can bind to a parameter, or to a handy little method.
<InputText @bind-Value="@TextProperty" @attributes="HandyFunction()" />
@code{
Dictionary<string,object> HandyFunction()
{
var dict = new Dictionary<string, object>();
if(MyModel.isAutoFocus) dict.Add("autofocus",true);
return dict;
}
}
Upvotes: 24
Reputation: 5839
As it turns out, Blazor will not render the attribute if the value of the attribute is false
or null
HTML element attributes are conditionally rendered based on the .NET value. If the value is false or null, the attribute isn't rendered. If the value is true, the attribute is rendered minimized.
<InputText @bind-Value="@TextProperty" autofocus="@MyModel.isAutoFocus" />
Upvotes: 40
Reputation: 20106
You could try below code:
<InputText @bind-Value="@TextProperty" autofocus="@(MyModel.isAutoFocus)" />
Refer to https://github.com/aspnet/AspNetCore/issues/10122
Upvotes: 13