Enrico
Enrico

Reputation: 6202

Show/hide a div based on the model in Blazor WebAssembly

I'm creating my first production project with Blazor WebAssembly. I'm struggle to find a way to change the view alias DOM. Basically, I have a Razor component with a form. The user can add multiple time some information.

enter image description here

In the image "Add Publication Output" is

_model.PublicationOutputs = new List<Domain.PublicationOutput>();

and when the user clicks the button I add a new item in the list

<button class="btn btn-outline-primary" type="button" 
@onclick="@(() => _model.PublicationOutputs.Add(new Domain.PublicationOutput()))">
Add Publication Output
</button>

then there is a foreach to display the new forms.

@foreach (var item in _model.PublicationOutputs)
{
    i++;

    <div class="row">
        <div class="col-2">
            <div class="form-group">
                <label class="font-weight-bold text-secondary">Stage</label>
                <p>@i</p>
            </div>
        </div>

        <div class="col">
            <div class="form-group">
                <label for="outputTypeSelect" 
                class="font-weight-bold text-secondary">
                Output type</label>
                <div class="select">
                    <select @bind="item.OutputTypeId" id="outputTypeSelect">
                        <option value="0">Select an option</option>
                        @if (_listOut != null)
                            foreach (var itm in _listOut)
                            {
                                <option value="@itm.ID">@itm.Name</option>
                            }
                    </select>
                </div>
            </div>
            <div class="form-group">
                <label for="itemShort" class="font-weight-bold text-secondary">
                Short title</label>
                <InputText @bind-Value="item.ShortDescription" 
                           class="form-control" id="itemShortDescription" />
            </div>
        </div>
    </div>
}

I think you got it. The complete result is in the following image

enter image description here

When a user selects from the "Output Type" a specific value, I want to display a div with an InputText, so he can add more details. I tried to do that in 2 ways without achieve the result.

First way was to use style and display to show or hide the div with the InputText but it doesn't work.

<div class="form-group" 
     style="@(item.OutputTypeId == 2 ? "display: ;" : "display: none;")">
    <label for="itemDetails" class="font-weight-bold text-secondary">
    Details</label>
    <InputText @bind-Value="item.Details" class="form-control" id="itemDetails" />
</div>

Then, I tried to use if

@if (item.OutputTypeId == 2) {
    <div class="form-group">
        <label for="itemDetails" class="font-weight-bold text-secondary">
        Details</label>
        <InputText @bind-Value="item.Details" 
                   class="form-control" id="itemDetails" />
    </div>
}

but again, when the select changed, the div is not displaying. If I use the same if in a label, it is working. So, when the user selects a new option from the select, the label changes the text.

<label for="itemTarget" class="font-weight-bold text-secondary" id="labelTarget">
    @(item.OutputTypeId == 3 ? "Target Journal" : "Target Congress")
</label>

How can I show/hide some div or HTML in Blazor based on the model? Plus, how can I do it with multiple instances of the same HTML based on the model?

Upvotes: 0

Views: 7215

Answers (1)

Dominik Oswald
Dominik Oswald

Reputation: 375

For @if (item.OutputTypeId == 2) you have to update the the component view with StateHasChanged or better with:

await InvokeAsync(StateHasChanged);

See documentation.

For div use a show/hide variable:

private bool ShowMyFoo { get; set; } = false;

private void ShowFoo()
{
    ShowMyFoo = !ShowMyFoo;
}   

for <div hidden="@ShowMyFoo">my code</p>

See example fiddle.

Upvotes: 3

Related Questions