I have a LogModel that has a Children property of type LogModel, so a recursive/nested structure. There is also a Collapsed bool property and a Description string.
I am trying to display this in Blazor server side markup, but cant figure out how to process the recursive piece.
I want it to show the Description, with a +/- button which has @onclick that toggles the Collapse property, which then controls the collapse class in bootstrap, collapsing/hiding all children from display.
Like this example: How to collapse/expand Razor components using Blazor syntax?
My 2nd idea was to do the recursive piece inside Code, which returns a MarkupString. This displayed ok, but then I couldnt work out how to bind the +/- button to an event to toggle the collapsed property, because the @onlick cant be done from inside MarkupString from what I've read.
Thanks in advance, Aaron.
Here's a solution based on the information you've given. It's not pretty: you'll need to sort the Bootstrap CSS out to suite your needs.
using System.Collections.Generic;
namespace StackOverflow.Answers
{
public class LogModel
{
public string Description { get; set; }
public List<LogModel> Children { get; set; } = new List<LogModel>();
}
}
@namespace StackOverflow.Answers
<div class="container m-0 p-1 border border-secondary">
<div class="row">
<div class="col-11">
@this.Model.Description
</div>
@if (this.hasChildren)
{
<div class="col-1">
<button class="btn @this.buttonCss" type="button" @onclick="ToggleShow">
@buttonText
</button>
</div>
}
</div>
@if (this.Show)
{
<div class="row">
<div class="col-12">
@if (this.hasChildren)
{
@foreach (var child in this.Model.Children)
{
<LogDisplayControl Model="child"></LogDisplayControl>
}
}
</div>
</div>
}
</div>
@code {
[Parameter] public LogModel Model { get; set; }
private bool Show;
private void ToggleShow()
=> this.Show = !this.Show;
private bool hasChildren => this.Model?.Children?.Count > 0;
private string buttonText => this.Show ? "Hide" : "Show";
private string buttonCss => this.Show ? "btn-dark" : "btn-primary";
private string HeaderCols => this.hasChildren ? "col-11" : "col-12";
}
@page "/Accordion"
@foreach (var child in Model)
{
<LogDisplayControl Model="child" />
}
@code {
private List<LogModel> Model = new List<LogModel>();
protected override void OnInitialized()
{
var model1_1_1 = new LogModel { Description = "Log Model 1.1.1" };
var model1_1_2 = new LogModel { Description = "Log Model 1.1.2" };
var model1_1 = new LogModel { Description = "Log Model 1.1", Children = new List<LogModel> { model1_1_1, model1_1_2 } };
var model1_2 = new LogModel { Description = "Log Model 1.2" };
var model1 = new LogModel { Description = "Log Model 1", Children = new List<LogModel> { model1_1, model1_2 } };
var model2_1_1 = new LogModel { Description = "Log Model 2.1.1" };
var model2_1 = new LogModel { Description = "Log Model 2.1", Children = new List<LogModel> { model2_1_1 } };
var model2 = new LogModel { Description = "Log Model 2", Children = new List<LogModel> { model2_1 } };
Model.Add(model1);
Model.Add(model2);
}
}