Blazor Closes the div tag on a conditionally div wrapper

Viewed 710

Im trying to wrap one of my components on some specific tag based on some conditions.

To make it simple lets say that i have a

<div class="inner-class">
    this must be in inner-class div and wrapped in some-class div
</div>

And if 'condition' == true then it should wrap it in another div the result should be like this

<div class="wrapper-class">
    <div class="inner-class">
        this must be in inner-class div and wrapped in some-class div
    </div>
</div>

And before you say, use if-else method. i must say no. because the tag and the class in it is dynamic so i cant write it like that.

What i tried to do is

@if (condition)
{
    @:<div class="wrapper-class">
}
    <div class="inner-class">
        this must be in inner-class div and wrapped in some-class div
    </div>
}
@if (condition)
{
    @:</div>
}

I Thought it should do the job. But the problem is the browser closes the outer div before putting the inner div in it.

enter image description here

3 Answers

I ended up writing a wrapper component similar to this to solve this problem pretty elegantly:

@if (Wrap)
{
    <div id="@Id" class="@Class">
        @ChildContent
    </div>
}
else
{
    @ChildContent
}
@code
{
    [Parameter] public string? Id { get; set; }
    [Parameter] public string? Class { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    [Parameter] public bool Wrap { get; set; }
}

It doesn't support dynamic tag types, but that would be pretty easy to create using a component implementing BuildRenderTree as mRizvandi suggested.

If it's a simple layout like you've described than you can make use of the MarkupString. The trick is understanding that MarkupString will automatically close any tags that are left open. Therefore you just need to build the entire string properly before trying to render it as a MarkupString.

@{ bool condition = true; }
@{ string conditionalMarkup = string.Empty; }
@if (condition)
{
    conditionalMarkup = "<div class=\"wrapper-class\">";
}

@{ conditionalMarkup += "<div class=\"inner-class\"> this must be in inner-class div and wrapped in some-class div </div>"; }

@if (condition)
{
    conditionalMarkup += "</div>";
    @((MarkupString)conditionalMarkup)
}
else
{
     @((MarkupString)conditionalMarkup)
}

I do this for building simple conditional markup. Usually inside of an object iteration making use of String.Format to fill in property values.

Related