Blazor.FamilyTreeJS 3.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Blazor.FamilyTreeJS --version 3.0.0                
NuGet\Install-Package Blazor.FamilyTreeJS -Version 3.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blazor.FamilyTreeJS" Version="3.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Blazor.FamilyTreeJS --version 3.0.0                
#r "nuget: Blazor.FamilyTreeJS, 3.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Blazor.FamilyTreeJS as a Cake Addin
#addin nuget:?package=Blazor.FamilyTreeJS&version=3.0.0

// Install Blazor.FamilyTreeJS as a Cake Tool
#tool nuget:?package=Blazor.FamilyTreeJS&version=3.0.0                

Blazor.FamilyTreeJS

This is a wrapper library for FamilyTreeJS and it is only compatible for Blazor WASM.

Current FamilyTreeJS version packaged in this library: 1.9.44.

Here is the release note list of FamilyTreeJS.

Installation

Install from Nuget.

dotnet add package Blazor.FamilyTreeJS --version <latest-version>

Depenencies

Register Blazor.FamilyTreeJS dependencies.

builder.Services.AddBlazorFamilyJS();

IJSRuntime configuration

Configure IJSRuntime's JsonSerializerOptions. This allows System.Text.Json to ignore null when serializing to JSON and send that JSON to Javascript. Note this affects globally.

var app = builder
  .Build()
  .ConfigureIJSRuntimeJsonOptions();

Enable C# callback interop with Javascript

This library depends on the library Blazor.Core in which provides the feature to help serialize/deserialize C# callback to Javascript. To ensure Blazor.FamilyTreeJS work correctly, you must call RegisterCallbackReviverAsync() from the Blazor.Core library.

var webHost = builder
  .Build()
  .ConfigureIJSRuntimeJsonOptions();

await webHost.RegisterCallbackReviverAsync();
await webHost.RunAsync();

Serialize/deserialize derived types

If you have classes/records that inhereit from classes/records in this library, then you may need to use the following extension method, UseDerivedTypes<BaseType>([derive types]). This allows serializing your derived classes/records with all of their properties.

var app = builder
  .Build()
  .ConfigureIJSRuntimeJsonOptions();
  .UseDerivedTypes<NodeMenu>(typeof(CollapseNodeMenu), typeof(DrawLineNodeMenu));

public record CollapseNodeMenu : NodeMenu
{
  public Menu? Collapse { get; init; } = null;
}

public record DrawLineNodeMenu : NodeMenu
{
  public Menu? Draw { get; init; } = null;
}

Usage

Simplest usage is to use the DefaultFamilyTree component and provide a tree id. This component uses the provided Node record as the type for the nodes stored in the family tree.

<DefaultFamilyTree TreeId="my-tree" />

This library is heavily driven by the FamilyTreeOptions class so almost every control and UI are specified via this class. This C# class mirrors this Typescript options interface.

<DefaultFamilyTree TreeId="my-tree"
                   Options=@new() { FamilyTreeOptions: new(Mode = "dark") } />

If you want to provide your own node with custom properties then you must have your custom node type inherits BaseNode, and use the FamilyTree<TNode> component instead.

public record NodeWithProfession : BaseNode
{
  public string? Job { get; init; }
}

<FamilyTree TNode="NodeWithProfession"
            TreeId="my-tree"
            Options=@new() { FamilyTreeOptions: new(Mode = "dark") } />

Define custom input element

An input element is a HTML element of a node that the user can view and/or edit. For example, the Node record has the property Name. The equivalent input element of this property is <input type="text" <other_attributes />. This property can be viewed when the node is clicked and can be edited when the user navigates to the "Edit details" of the node.

To provide your own custom HTML for an input element, you can reference to one of the provided custom input element in this library, such as ReadOnlyTextbox.

After you define your custom input element, you have to "register" it with a unique type string. This type must be unique across all family tree instances. If the same type is defined more than once, an exception will be thrown.

public record NodeWithProfession : BaseNode
{
  public string? Job { get; init; }
}

<FamilyTree TNode="NodeWithProfession"
            TreeId="my-tree"
            Options=@new(
              // Skip other properties for brevity
              FamilyTreeOptions: new(
                EditForm: new(
                  Elements: new List<EditFormElement>()
                  {
                    // Here you reference your custom input
                    new(Type: "customInput", Label: "Job", Binding: "job"),
                  }
                )
              ),
              NonFamilyTreeOptions: new(
                CustomInputElements: new Dictionary<string, InputElementCallback<CustomNode>>
                {
                  // Register your custom input here
                  // "customInput" is the type - this must be unique across all family tree instances
                  { "customInput", CustomInput.Callback<NodeWithProfession> }
                }
              )
            ) />

Please refer to the sample project for more examples.

Using FamilyTreeStaticModule

To use the static methods defined in FamilyTreeJS, you would have to call them via this class FamilyTreeStaticModule. This class is simply a wrapper class for the static methods defined in FamilyTreeJS.

To use it, you would have to manually register it in your DI container. Then you would have request an instance of it and call .ImportAsync() to import the JavaScript module. Due to this class having an asynchronous initilization, it is recommended to regsiter it as a singleton so that you don't have to deal with when to call ImportAsync() when requesting it.

builder.Services
  .AddBlazorFamilyJS()
  // Register it as a singleton
  .AddSingleton<FamilyTreeStaticModule>()
  .AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

var webHost = builder.Build();

// Get the module object and import the JS module
var familyTreeStaticModule = webHost.Services.GetRequiredService<FamilyTreeStaticModule>();
await familyTreeStaticModule.ImportAsync();

await webHost.RunAsync();
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.1 112 10/20/2024
3.0.0 90 10/12/2024
2.0.7 109 9/7/2024
2.0.6 125 9/3/2024
2.0.5 94 8/6/2024
2.0.4 125 6/30/2024
2.0.3 107 6/23/2024
2.0.2 106 6/23/2024
2.0.1 102 6/12/2024
2.0.0 100 6/11/2024
1.0.1 150 4/19/2024
1.0.0 139 4/13/2024