user616
user616

Reputation: 855

Razor parent component detect if child component exists

I am using the default Blazor server application for building a login page. I am creating my own UI "framework" of components and i wanted to see if its possible to have the Parent component detect if there is a certain child component. If the child component was provided then change the Parent component html structure.

Login page that consumes the components:

<Card Color="bg-info">
    <CardHeader>Card Header</CardHeader>
    <CardBody>
        <CardTitle>Card title</CardTitle>
        <CardTitle SubTitle>Card Subtitle</CardTitle>
        <CardText>Card text goes here...</CardText>
    </CardBody>
    <CardFooter>
        <Spacer />
        <Button Color="bg-danger">Cancel</Button>
        <Button class="ms-2" Color="bg-primary" @onclick="Test">Ok</Button>
    </CardFooter>
</Card>

Card(parent) component:

<div @attributes="AdditionalAttributes" class="@BaseCss" style="@BaseStyles">
    @ChildContent
</div>

So what i'm looking for is, IF the consumer of the <Card> component has opted to use the <CardHeader> child component inside of <Card> then problematically change the html template of the Card component

Something like this, but im not sure how to implement it:

<div @attributes="AdditionalAttributes" class="@BaseCss" style="@BaseStyles">
    @if (HEADER_COMPONENT_EXISTS) <----- How do i get this?
    {
        @HEADER_COMPONENT_HERE <------ How can i add this RenderFragment
        <div class="card-body">
            @ChildContent
        </div>
    }
    else
    {
        <div class="card-body">
            @ChildContent
        </div>
    }
</div>

Upvotes: 0

Views: 1092

Answers (1)

Astrid E.
Astrid E.

Reputation: 2872

Are the CardHeader, CardBody and CardFooter components used anywhere else? If not, you could simply use these as parameters directly in your Card component as follows:

<div @attributes="AdditionalAttributes" class="@BaseCss" style="@BaseStyles">
    @CardHeader
    <div class="card-body">
        @CardBody
    </div>
    @CardFooter
</div>

@code {
    [Parameter]
    public RenderFragment CardHeader { get; set; }

    [Parameter]
    public RenderFragment CardBody { get; set; }

    [Parameter]
    public RenderFragment CardFooter { get; set; }
}

If no <CardHeader> </CardHeader> has been added inside <Card> </Card>, nothing is rendered for @CardHeader.


You can verify either Parameter existence by checking it against null:

<div @attributes="AdditionalAttributes" class="@BaseCss" style="@BaseStyles">
    @if (CardHeader != null)
    {
        @CardHeader
        <!-- Other header-relevant content -->
    }
    @CardBody
</div>

Note: If you want to keep ChildContent as a parameter for Card as well, that child content needs to be wrapped inside <ChildContent> </ChildContent>:

<Card Color="bg-info">
    <CardHeader><!--Header content--></CardHeader>
    <CardBody><!--Body content--></CardBody>
    <CardFooter><!--Footer content--></CardFooter>
    <ChildContent><!--Other content--></ChildContent>
    <!--Any content that goes here will get an error message-->
</Card>

This is the case for any component if it takes more than one parameter of the RenderFragment type.

Upvotes: 1

Related Questions