Soenneker.Blazor.TomSelect 4.0.4761

Prefix Reserved
dotnet add package Soenneker.Blazor.TomSelect --version 4.0.4761
                    
NuGet\Install-Package Soenneker.Blazor.TomSelect -Version 4.0.4761
                    
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="Soenneker.Blazor.TomSelect" Version="4.0.4761" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Soenneker.Blazor.TomSelect" Version="4.0.4761" />
                    
Directory.Packages.props
<PackageReference Include="Soenneker.Blazor.TomSelect" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Soenneker.Blazor.TomSelect --version 4.0.4761
                    
#r "nuget: Soenneker.Blazor.TomSelect, 4.0.4761"
                    
#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.
#:package Soenneker.Blazor.TomSelect@4.0.4761
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Soenneker.Blazor.TomSelect&version=4.0.4761
                    
Install as a Cake Addin
#tool nuget:?package=Soenneker.Blazor.TomSelect&version=4.0.4761
                    
Install as a Cake Tool

alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

alternate text is missing from this package README image Soenneker.Blazor.TomSelect

A strongly typed Blazor component and JS interop wrapper for searchable single-select, multi-select, user-created, and remotely loaded Tom Select controls.

Live demo

Installation

dotnet add package Soenneker.Blazor.TomSelect

Register the interop service in Program.cs:

using Soenneker.Blazor.TomSelect.Registrars;

builder.Services.AddTomSelectInteropAsScoped();

Add the component namespace to _Imports.razor:

@using Soenneker.Blazor.TomSelect

Basic usage

Data supplies the available options. Items contains the selected TItem objects and is the normal source of truth for selection state:

@using Soenneker.Blazor.TomSelect.Configuration

<TomSelect TItem="Country"
           TType="string"
           Data="_countries"
           TextField="country => country.Name"
           ValueField="country => country.Id.ToString()"
           @bind-Items="_selectedCountries"
           Multiple="true"
           Placeholder="Select countries…"
           Configuration="_configuration" />

@code {
    private IReadOnlyList<Country> _countries =
    [
        new(1, "Canada"),
        new(2, "Mexico"),
        new(3, "United States")
    ];

    private List<Country> _selectedCountries = [];

    private readonly TomSelectConfiguration _configuration = new()
    {
        MaxItems = 3,
        CloseAfterSelect = false
    };

    private sealed record Country(int Id, string Name);
}

TextField is the label shown to the user. ValueField must return a stable, non-empty, unique string for each option. Duplicate or null values cannot be represented reliably and are removed or skipped.

The component's browser value path is string-based, so TType="string" is the appropriate declaration. The bound result is still List<TItem>. With Multiple="false", that list contains zero or one item; use Items.FirstOrDefault() when the rest of your model expects a scalar.

When the parent replaces Data or Items, the component synchronizes its browser options and selection. Replace the list or ensure your item type has meaningful equality/hash behavior when changing mutable data. Use UpdateOption(value, updatedItem) for an explicit in-place option update.

Creating new options

Enable creation and provide exactly one function that converts typed text into a valid TItem:

<TomSelect TItem="Tag"
           TType="string"
           Data="_availableTags"
           TextField="tag => tag.Name"
           ValueField="tag => tag.Id"
           @bind-Items="_selectedTags"
           Create="true"
           CreateFuncSync="CreateTag" />

@code {
    private Tag CreateTag(string text) => new(Guid.NewGuid().ToString("N"), text.Trim());
}

Use CreateFunc for asynchronous creation or CreateFuncSync for synchronous creation, never both. Validate length, format, duplicates, and authorization in that function before persisting user-created values. CreateOnBlur and CreateFilter provide additional Tom Select behavior but do not replace server-side validation.

Remote loading

Set LoadFunc or LoadFuncSync to query options from .NET. The wrapper enables Tom Select's load callback automatically:

<TomSelect TItem="Customer"
           TType="string"
           Data="[]"
           TextField="customer => customer.DisplayName"
           ValueField="customer => customer.Id"
           @bind-Items="_customers"
           LoadFunc="SearchCustomersAsync"
           Configuration="_remoteConfiguration" />

@code {
    private readonly TomSelectConfiguration _remoteConfiguration = new()
    {
        ShouldLoadMinQueryLength = 2,
        LoadThrottle = 300,
        MaxOptions = 20
    };

    private async ValueTask<IEnumerable<Customer>> SearchCustomersAsync(string query)
    {
        string encoded = Uri.EscapeDataString(query);
        return await Http.GetFromJsonAsync<List<Customer>>($"api/customers/search?q={encoded}") ?? [];
    }
}

The load delegate receives only the query string, not a per-request cancellation token. Apply authorization and result limits on the server, encode the query, handle timeouts/failures, and avoid returning sensitive records merely because their text matches. LoadThrottle reduces request frequency but is not a server-side rate limit.

Rendering and HTML safety

Default labels are HTML-escaped. OptionTemplate and ItemTemplate let Blazor provide trusted template markup; values substituted through {{property.path}} placeholders are also escaped:

<OptionTemplate>
    <div class="customer-option">
        <strong>{{displayName}}</strong>
        <span>{{email}}</span>
    </div>
</OptionTemplate>

Template markup itself is inserted into Tom Select's DOM. Keep it application-owned, and validate values used in URL-bearing attributes such as href or src; HTML escaping alone does not validate URL schemes.

RenderOptionHtml, RenderOptionHtmlAsync, RenderItemHtml, and RenderItemHtmlAsync are raw HTML escape hatches. Their return values are not sanitized. Never concatenate untrusted labels, descriptions, URLs, or remote API fields without context-appropriate encoding and URL validation.

Events and imperative methods

Use @bind-Items for domain state. Event callbacks such as OnInitialize, OnChange, OnItemAdd, OnItemRemove, OnItemCreated, OnFocus, and OnBlur are useful for UI side effects and telemetry that does not contain sensitive option data.

The component reference exposes option/item mutation, focus, dropdown, enable/disable, lock, cache, and refresh methods. Wait for OnInitialize before calling imperative methods. Reinitialize() clears and repopulates options and selections from the current Data and Items; it is not a general configuration hot-reload mechanism.

Assets and cleanup

UseCdn defaults to true and loads pinned Tom Select script/style assets from jsDelivr with integrity validation. Set it to false to use the package's bundled _content assets. UseBootstrap5Styling selects the Bootstrap 5 stylesheet; set it to false for Tom Select's regular stylesheet.

Every component instance owns separate browser callbacks and a removal observer. Normal Blazor disposal explicitly destroys the Tom Select instance; detached targets are also cleaned up when an ancestor is removed. Applications using direct ITomSelectInterop calls should still call Destroy(elementId) when they own the target lifecycle.

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

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Soenneker.Blazor.TomSelect:

Package Downloads
Soenneker.Blazor.SheetMapper

A Blazor component and utility library for mapping uploaded CSV or tabular files to C# objects. Supports header extraction and user-defined property mapping.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.0.4761 148 9/17/2026
4.0.4760 96 9/16/2026
4.0.4759 75 9/16/2026
4.0.4758 81 9/16/2026
4.0.4757 93 9/16/2026
4.0.4756 76 9/16/2026
4.0.4755 81 9/16/2026
4.0.4752 120 9/16/2026
4.0.4749 75 9/15/2026
4.0.4747 75 9/15/2026
4.0.4746 118 9/15/2026
4.0.4744 112 9/14/2026
4.0.4743 144 9/13/2026
4.0.4742 101 9/13/2026
4.0.4740 93 9/13/2026
4.0.4739 111 9/13/2026
4.0.4738 99 9/13/2026
4.0.4737 93 9/13/2026
4.0.4736 103 9/13/2026
4.0.4734 86 9/13/2026
Loading failed

Update dependency Soenneker.Blazor.Utils.InteropEventListener to 4.0.4141 (#6388)