Saeed Asgari
Saeed Asgari

Reputation: 427

Blazor Closes the div tag on a conditionally div wrapper

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

Upvotes: 3

Views: 2043

Answers (3)

clamchoda
clamchoda

Reputation: 4941

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.

Upvotes: 0

pwhe23
pwhe23

Reputation: 1334

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.

Upvotes: 2

mRizvandi
mRizvandi

Reputation: 1093

You have to use BuildRenderTree

With BuilderRenderTree you have full control to build component html.

For more information read this good article Building Components Manually via RenderTreeBuilder

Upvotes: 1

Related Questions