ManyToMany Editor

Learn how to create a ManyToMany Editor

Many-to-Many Editor in BlazorForKids

The BkManyToManyEditor component provides a visual and intuitive way to manage many-to-many relationships between two entities — for example, assigning an employee to multiple teams, or linking a product to several categories.

This editor displays two lists side-by-side: one with available items (e.g., all teams in the system), and one with selected items (e.g., the teams already assigned to the employee). Users can move items back and forth between these two lists to update the relationship in real time.

Basic Setup

To use the BkManyToManyEditor, define it in your ComponentsDesigner using the CreateManyToManyEditor method:


            builder.CreateManyToManyEditor<Employee, Team>(a => a.Teams, "AddEmployeeToTeams", options =>
            {
                options.Title("Add Employee To Teams");
                options.CssClass("employee-teams");

                // Optional UI labels
                options.SelectedItemsLabel("Selected Teams");
                options.AvailableItemsLabel("Available Teams");
                options.DestinationEntityLabel("Selected Team");
                options.SourceEntityLabel("Available Team");

                // Optional: Customize how each item is displayed
                options.ItemTemplate<DisplayTemplateForTeamItem>();
            });
    

In this example, we're editing the Teams collection on the Employee entity. The editor will:

  • Load all available teams from the database
  • Load the teams already assigned to the current employee
  • Allow users to add or remove teams with a simple UI
  • Automatically update the database when changes are made

Passing the Parent Entity Key

The editor needs to know which entity you're editing the relationships for. In our case, we need to tell it which Employee we're adding/removing Teams from. This is typically done using a query parameter:


        // Capture the EmployeeId from the query string
        [SupplyParameterFromQuery(Name = "EmployeeId")]
        public string? EmployeeIdParameter { get; set; }

        public EmployeeId EmployeeId => EmployeeId.ParseOrEmpty(EmployeeIdParameter);
    

Then, pass this ID to the component when rendering it in your page content:


            content.DisplayComponent<AddEmployeeToTeams>(component =>
            {
                component.SetParameter(a => a.EmployeeId, EmployeeId);
            });
    

This allows the component to fetch the current employee’s assigned teams, and to know which entity to update when the selection changes.

Customizing the UI

The default item type used in the editor is BkCatalogItem, and the framework knows how to display it using the item’s name. However, you can provide a custom item template to style how items appear — for example, with icons, badges, or descriptions.

Example: DisplayTemplateForTeamItem


            // optional: you can use a custom template to display the item
            @using BlazorForKids.Designer.Web.Internal.Components.ManyToManyEditor
            @using BlazorForKids.Designer.Web.Widgets.Shared
            @using BootstrapIconsForDotNet
            @inherits BkManyToManyItemTemplate

            <div class="team-card">
                <h3>
                    <BkSvg Svg="@Icons.PEOPLE"/>
                    @Item.Text
                </h3>
            </div>
    

This gives you full control over the appearance of each selectable item in the editor.

Summary

  • BkManyToManyEditor is the easiest way to manage many-to-many relationships visually
  • It displays two lists (available and selected), allowing users to move items between them
  • You must pass the ID of the parent entity (e.g., EmployeeId) so the component knows what to edit
  • Optional configuration lets you customize labels, styling, and item display templates

This component is ideal for use cases like assigning users to groups, adding tags to content, managing access roles, and more — wherever two entities can relate to each other in multiple combinations.

An unhandled error has occurred. Reload 🗙