31

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!
/>
1

5 Answers 5

42

As it turns out, Blazor will not render the attribute if the value of the attribute is false or null

https://learn.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.0#conditional-html-element-attributes

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" />
Sign up to request clarification or add additional context in comments.

5 Comments

Of interesting note - this also works for the disabled or selected tags which normally don't equal anything. E.g. <select @bind="selectValue" disabled="isDisabled">
@AlbatrossCafe it doesn't work on disabled
It doesn't work on the form attribute on buttons either.
Works for the readonly attribute of the built-in InputText component.
Worth noting that attributes without values can't be disabled by simply adding "false". You must declare "@false".
24

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

2 Comments

Thanks, although nowhere near as straightforward as it should be like in earlier editions of Razor.
This also works if you need to conditionally set a parameter on a blazor component like if you need to pass a render fragment through.
13

You could try below code:

<InputText  @bind-Value="@TextProperty"  autofocus="@(MyModel.isAutoFocus)"  />

Refer to https://github.com/aspnet/AspNetCore/issues/10122

5 Comments

The presence of the autofocus attribute enables the feature. I need to conditionally write out the attribute, not the value.
@Aaron Hudon I have tried and find that If set autofocus= true,it will show as autofocus in the input on page, if autofocus= false, it will not show as attribute for the input.Maybe you could open browser F12 to check the result?
Thanks - I might just have to fall back to this, but the original question still stands, how to conditionally output an attribute.
@Aaron Hudon I understand now but I think blazor does not support that yet.Good luck...
@jottin answer below is the correct one stackoverflow.com/a/79412059/235648
1

Add or Remove Attributes in HTML Using Blazor

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

Simple Ways to Add An Attribute in Blazor

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

Comments

1

I had the opposite problem that was not easy to solve at first. In order to remove an attribute that has no value such as "readonly", "disabled", or "inert", setting it to "true" or "false" will actually activate it. Instead, specifying "@true" or "@false" such as "readonly=@true", "disabled=@false", or "inert=@false" will prevent the attribute from being generated.

https://blazor-university.com/components/code-generated-html-attributes/#special-cases

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.