Giter Club home page Giter Club logo

typeahead's Introduction

Blazored Typeahead

Typeahead control for Blazor applications.

Nuget version Nuget downloads Build & Test Main

Screenshot

Installing

You can install from NuGet using the following command:

Install-Package Blazored.Typeahead

Or via the Visual Studio package manger.

Setup

Blazor Server applications will need to include the following CSS and JS files in their _Host.cshtml .

Blazor Client applications will need to include the following CSS and JS files in their Index.html .

In the head tag add the following CSS.

<link href="_content/Blazored.Typeahead/blazored-typeahead.css" rel="stylesheet" />

Then add the JS script at the bottom of the page using the following script tag.

<script src="_content/Blazored.Typeahead/blazored-typeahead.js"></script>

I would also suggest adding the following using statement to your main _Imports.razor to make referencing the component a bit easier.

@using Blazored.Typeahead

Usage

The component can be used standalone or as part of a form. When used in a form the control fully integrates with Blazors forms and authentication system.

Below is a list of all the options available on the Typeahead.

Templates

  • ResultTemplate (Required) - Allows the user to define a template for a result in the results list
  • SelectedTemplate (Required) - Allows the user to define a template for a selected item
  • HelpTemplate - Allows the user to define a template to show when the MinimumLength to perform a search hasn't been reached
  • NotFoundTemplate - Allows the user to define a template when no items are found
  • FooterTemplate - Allows the user to define a template which is displayed at the end of the results list

Parameters

  • MinimumLength (Optional - Default: 1) - Minimum number of characters before starting a search
  • Debounce (Optional - Default: 300) - Time to wait after last keypress before starting a search
  • MaximumSuggestions (Optional - Default: 10) - Controls the amount of suggestions which are shown
  • Disabled (Optional - Default: false) - Marks the control as disabled and stops any interaction
  • EnableDropDown (Optional - Default: false) - Allows the control to behave as a dropdown
  • DisableClear (Optional - Default : false) - Hides the clear button from the Typeahead. Users can still change the selection by clicking on the current selection and typing however, they can't clear the control entirely.'
  • ShowDropDownOnFocus (Optional - Default: false) - When enabled, will show the suggestions dropdown automatically when the control is in search mode. If the control has a current value then the user would need to press the enter key first to enter search mode.
  • StopPropagation (Optional - Default: false) - Control the StopPropagation behavior of the input of this component. See https://docs.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.1#stop-event-propagation
  • PreventDefault (Optional - Default: false) - Control the PreventDefault behavior of the input of this component. See https://docs.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.1#prevent-default-actions

The control also requires a SearchMethod to be provided with the following signature Task<IEnumerable<TItem>>(string searchText). The control will invoke this method passing the text the user has typed into the control. You can then query your data source and return the result as an IEnumerable for the control to render.

If you wish to bind the result of the selection in the control to a different type than the type used in the search this is also possible. For example, if you passed in a list of Person but when a Person was selected you wanted the control to bind to an int value which might be the Id of the selected Person, you can achieve this by providing a ConvertMethod The convert method will be invoked by the control when a selection is made and will be passed the type selected. The method will need to handle the conversion and return the new type.

If you want to allow adding an item based on the search when no items have been found, you can achieve this by providing the AddItemOnEmptyResultMethod as a parameter. This method will make the NotFoundTemplate selectable the same way a item would normally be, and will be invoked when the user selects the NotFoundTemplate. This method passes the SearchText and expects a new item to be returned.

Local Data Example

<EditForm Model="MyFormModel" OnValidSubmit="HandlValidSubmit">
    <BlazoredTypeahead SearchMethod="SearchFilms"
                            @bind-Value="MyFormModel.SelectedFilm">
        <SelectedTemplate>
            @context.Title
        </SelectedTemplate>
        <ResultTemplate>
            @context.Title (@context.Year)
        </ResultTemplate>
    </BlazoredTypeahead>
    <ValidationMessage For="@(() => MyFormModel.SelectedFilm)" />
</EditForm>

@code {

    [Parameter] protected IEnumerable<Film> Films { get; set; }

    private async Task<IEnumerable<Film>> SearchFilms(string searchText) 
    {
        return await Task.FromResult(Films.Where(x => x.Title.ToLower().Contains(searchText.ToLower())).ToList());
    }

}

In the example above, the component is setup with the minimum requirements. You must provide a method which has the following signature Task<IEnumerable<T> MethodName(string searchText), to the SearchMethod parameter. The control will call this method with the current search text everytime the debounce timer expires (default: 300ms). You must also set a value for the Value parameter. This will be populated with the item selected from the search results. As this version of the control is integrated with Blazors built-in forms and validation, it must be wrapped in a EditForm component.

The component requires two templates to be provided...

  • SelectedTemplate
  • ResultTemplates

The SelectedTemplate is used to display the selected item and the ResultTemplate is used to display each result in the search list.

Remote Data Example

@inject HttpClient httpClient

<BlazoredTypeahead SearchMethod="@SearchFilms"
                   @bind-Value="@SelectedFilm"
                   Debounce="500">
    <SelectedTemplate>
        @context.Title
    </SelectedTemplate>
    <ResultTemplate>
        @context.Title (@context.Year)
    </ResultTemplate>
    <NotFoundTemplate>
        Sorry, there weren't any search results.
    </NotFoundTemplate>
</BlazoredTypeahead>

@code {

    [Parameter] protected IEnumerable<Film> Films { get; set; }

    private async Task<IEnumerable<Film>> SearchFilms(string searchText) 
    {
        var response = await httpClient.GetJsonAsync<IEnumerable<Film>>($"https://allfilms.com/api/films/?title={searchText}");
        return response;
    }

}

Because you provide the search method to the component, making a remote call is really straight-forward. In this example, the Debounce parameter has been upped to 500ms and the NotFoundTemplate has been specified.

Subscribing to changes in selected values

It is common to want to be able to know when a value bound to the Typeahead changes. To do this you can't use the standard @bind-Value or @bind-Values syntax, you must handle the change event manually. To do this you must specify the following parameters:

  • Value
  • ValueChanged
  • ValueExpression
  • TValue & TItem (these are not always necessary)

The code below shows an example of how these parameters should be used.

<BlazoredTypeahead SearchMethod="SearchPeople"
                   TValue="Result"
                   TItem="Result"
                   Value="selectedResult"
                   ValueChanged="SelectedResultChanged" 
                   ValueExpression="@(() => selectedResult)"
                   placeholder="Search by name...">
</BlazoredTypeahead>

@code {
    private MovieCredits movieCredits;
    private Result selectedResult;

    private async Task<IEnumerable<Result>> SearchPeople(string searchText)
    {
        var search = await client.SearchPerson(searchText);
        return search.Results;
    }

    private async Task SelectedResultChanged(Result result)
    {
        selectedResult = result;
        movieCredits = await client.GetPersonMovieCredits(result.Id);
    }
}

Using complex types but only binding to a single property

There are times when you will want to use complex types with the Typeahead but only bind a certain property of that type. For example, you may want to search against a Person but once a person is selected, only bind to it's Id property. In order to do this you will need to implement the following:

<BlazoredTypeahead SearchMethod="GetPeopleLocal"
                   ConvertMethod="ConvertPerson"
                   @bind-Value="SelectedPersonId"
                   placeholder="Search by first name...">
    <SelectedTemplate Context="personId">
        @{
            var selectedPerson = LoadSelectedPerson(personId);

            <text>@selectedPerson?.Firstname @selectedPerson?.Lastname</text>
        }
    </SelectedTemplate>
    <ResultTemplate Context="person">
        @person.Firstname @person.Lastname (Id: @person.Id)
    </ResultTemplate>
</BlazoredTypeahead>

@code {
    private List<Person> People = new List<Person>();

    protected override void OnInitialized()
    {
        People.AddRange(new List<Person>() {
            new Person() { Id = 1, Firstname = "Martelle", Lastname = "Cullon" },
            new Person() { Id = 2, Firstname = "Zelda", Lastname = "Abrahamsson" },
            new Person() { Id = 3, Firstname = "Benedetta", Lastname = "Posse" }
        });
    }

    private async Task<IEnumerable<Person>> GetPeopleLocal(string searchText)
    {
        return await Task.FromResult(People.Where(x => x.Firstname.ToLower().Contains(searchText.ToLower())).ToList());
    }

    private int? ConvertPerson(Person person) => person?.Id;

    private Person LoadSelectedPerson(int? id) => People.FirstOrDefault(p => p.Id == id);
}

typeahead's People

Contributors

alancs avatar benshemmeld avatar chris5287 avatar chrissainty avatar fclinton avatar hal-nine-thousand avatar jerriep avatar joe-larue avatar juliengrd avatar kiasyn avatar markstega avatar matijs-toonen avatar natsuo avatar rkone avatar vertonghenb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typeahead's Issues

Wrong Return type

private async Task<List> SearchFilms(string searchText) gives an error on SearchMethod of the wrong return type.

private async Task<IEnumerable> SearchFilms(string searchText) allows it to work. The docs show list

Preview 9

Free text entry - Add item to the list.

Investigate the ability to add the text entered as a search, as a new value. I'm not sure that makes sense to anyone else, but I know what I mean! 😆

The example would be if the typeahead was used for selecting a city. If the city exists a user can select it as normal, if it doesn't it can be added.

TypeInference.CreateBlazoredTypeahead

I am using asp.net core 3.0 preview-5 and I get this error when I try to use BlazoredTypeAhead on a serverside Blazor. Am I missing something or doesn't it work with preview 5?

Error CS0411 Active The type arguments for method 'TypeInference.CreateBlazoredTypeahead_0(RenderTreeBuilder, int, int, Func<string, Task<List>>, int, object, int, RenderFragment, int, RenderFragment)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

@page "/Booking"
@using Blazored.Typeahead
@using Trebor.BeteckningSystem.Shared
@inject Trebor.BeteckningSystem.Interfaces.IAreaService areaService

<div>

    <BlazoredTypeahead Data="@SearchAreas" bind="@SearchAreas">
        <SelectedTemplate>
            @context.Name
        </SelectedTemplate>
        <ResultTemplate>
            @context.Name (@context.Descr)
        </ResultTemplate>
    </BlazoredTypeahead>

</div>


@functions {

    [Parameter] protected IEnumerable<Area> Areas { get; set; }

    private IEnumerable<Area> SearchAreas(string searchText)
    {
        return areaService.GetAreas(searchText);
    }
}

Add OnChange event

Add a event to the control which is raised when the value of the typeahead is changed. This is useful when using the control in more complex forms where you need to enable/disable other controls based on changes to selected values.

Single vs multi-mode
Should this work any differently? Probably not.

Cannot programmatically clear search text

I am currently running using Typeahead 3.1.8

After certain actions, I am attempting to clear the Typeahead search bar so that the user can perform a new search. I do this by setting the bound value to string.Empty

It appears that the value has been cleared in the UI, however, as soon as I focus on the text box the previously cleared value re-appears.

typeaheadExample

Add handler for OnKeyUp( enter ) on form/page

Hi Chris,

Thanks for the control - it's great! :)

I have an input where I'm tying in an event to the Enter key, so that somebody can type in a string, and when they hit enter it'll trigger an action to update the underlying object. So I have:

<input @bind-value="NewTag" @bind-value:event="oninput" @onkeyup="ProcessEnterKey" >

@code:

private void ProcessEnterKey( KeyboardEventArgs eventArgs)
    {
        if (eventArgs.Key == "Enter" )        // fire on enter 
            SaveTheData();
    }

Unfortunately, if I try and use this with the BlazoredTypeAhead like this:

<BlazoredTypeahead SearchMethod="SearchTags" @bind-Value="NewTag" @onkeyup="ProcessEnteEnterr">

it breaks the Typeahead control - I think because it replaces your control's internal onkeyup Handler. I'm relatively new to Blazor - is there a way to have both handlers in place, or is there a trivial way to extend the Typeahead keyup handler? I was going to derive a custom class using the BlazoredTypeAhead as the base, and then override the OnKeyUp method to extend it, but to do this, your KeyUp handler would need to be virtual. Is there a better, or more idiomatic way to do this in Blazor?

Focus After SelectItem is pretty annoying

After we select an item we focus the textfield again, which is pretty annoying when using this component in bigger forms. After the select, it should not focus the searchfield again so we can tab to the next input element.

Could not load type 'Microsoft.AspNetCore.Components.ElementRef' from assembly 'Microsoft.AspNetCore.Components

I recently upgraded from ASP.NET Core 3.0 Preview 7 to Preview 8 and noticing below error:

Could not load type 'Microsoft.AspNetCore.Components.ElementRef' from assembly 'Microsoft.AspNetCore.Components

I am suspecting it is due to a breaking change as mentioned in this link: https://devblogs.microsoft.com/aspnet/asp-net-core-and-blazor-updates-in-net-core-3-0-preview-8/

"Rename ElementRef to ElementReference."

Any pointers?

Add support for Enter, Tab keys to finish selection

Once you've narrowed down the list to only one option, user should be able to hit Enter or Tab to select that option and move on to next control in the form. They should not have to use the mouse to finish the selection, or use the down-arrow to move down to the one and only selection.

To repro, run the example code app, first example (I'm using Server-side Blazor):

  1. Type 'tracy' in search box
  2. Notice only one selection is remaining, Tracy Gwinnell
  3. Hit Enter key. Nothing happens (expected behavior: Tracy Gwinnell is selected)
  4. Hit Tab key. Search box is cleared, nothing is selected. (Expected behavior: (Tracy Gwinnell is selected, focus moves to Submit button)

If, when the user hits Enter/Tab, there are still multiple items in the list, perhaps it should just pick the first one?

No inputs were found in config file

After upgrading to asp.net core Preview-8 and TypeAHead 3.13 I get the following error (same with 3.12).
Build:No inputs were found in config file C:/Users/username/.nuget/packages/blazored.typeahead/3.1.3/contentFiles/any/netstandard2.0/tsconfig.json'.
Specified 'include' paths were '["**/*"]' and 'exclude' paths were '["wwwroot"].

Support for attribute splatting

Currently, if I set id, disabled, class, etc. it results in a Object reference not set to an instance of an object error at runtime.

<BlazoredTypeahead id="test" SearchMethod="Search" @bind-Value="@ReferenceProperty.Value" >

Improve the docs

The new version has a lot of new features and the docs need to be made better so people can discover and understand them better. Also a demo would be a good idea!

Server-side sample doesn't work on IIS Express

I was playing with the sample and noticed the server side blazor sample stops working after the first search when using IIS Express.
I then found out websockets doesn't work on IISExpress 8 on windows 7. only on 8 or 2012+

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.2

Fortunately using Kestrel works fine.

Just in case anyone else was coming across the same issue.

Maybe a note in readme if using windows 7 use Kestrel?

Event onchange on result template

Since i am a newbee to blazor there might be an easy solution for my question.

Server Side Blazor

I have a main page with a child component that has a typeahead component, three levels, main -> component -> typeahead. How do I bubble up the event from typeahead to the main page?
I've managed to get it to the degree that the event bubbles up to the main page, but then the typeahead component disappears. So I'm probably doing something wrong. Can you put an event callback on the template for the result on change? Or is it a completely wrong implementation?

Naming of static assets

https://github.com/Blazored/Typeahead/blob/master/src/Blazored.Typeahead/content/blazored.Typeahead.ts

I am not sure it is a good idea to use dot (period) or mixed case in static asset names.

May be better to use

blazored-typeahead.css
blazored-typeahead.ts

Technically URLs are case sensitive and dots are allowed but rarely used due to problems with users using regex for redirection in their reverse proxy servers.

If you look at other js libraries this seems to be the convention.

Fill like a DropDownList

Is there a way to use this like a DropDownList?
Example when I click on it all list items are shown and then I can filter them.

no drop down event error

If not drop down/typing event i have error then submit the editContext.
example

    <p>
        <label>ИТСО</label>
        <BlazoredTypeaheadInput SearchMethod="@(async (s)=>await SearchITSO(s))"
                                @bind-Value="@specificationDP.ITSO">
            <SelectedTemplate Context="itso">
                @itso.Name
            </SelectedTemplate>
            <ResultTemplate Context="itso">
                Наименование: @itso.Name<br>
                Код оборудования: @itso.DeviceCode<br>
            </ResultTemplate>
        </BlazoredTypeaheadInput>
    </p>

Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: Cannot read property 'addEventListener' of null
TypeError: Cannot read property 'addEventListener' of null
at Object.addFocusoutEventListener (http://localhost:55460/_content/Blazored.Typeahead/blazored-typeahead.js:7:17)
at http://localhost:55460/_framework/blazor.server.js:8:28738
at new Promise ()
at e.beginInvokeJSFromDotNet (http://localhost:55460/_framework/blazor.server.js:8:28707)
at http://localhost:55460/_framework/blazor.server.js:1:19148
at Array.forEach ()
at e.invokeClientMethod (http://localhost:55460/_framework/blazor.server.js:1:19119)
at e.processIncomingData (http://localhost:55460/_framework/blazor.server.js:1:17165)
at e.connection.onreceive (http://localhost:55460/_framework/blazor.server.js:1:10276)
at WebSocket.i.onmessage (http://localhost:55460/_framework/blazor.server.js:1:38027)

Add ability to set focus to the input box

A use case for this is as follows - when showing a modal with a typeahead component, it would be nice to set the focus to the input box so the user can just start typing. The same could apply when navigating to a page with a typeahead component.

Open / search without input, on get focus

Allow to search and show suggestions when getting focus, or when user click on the input. Setting the length to 0 seems not to be enough. Or maybe I missed something?

Tab key clears typed text, loses any highlighted selection

After typing text into the input field, hitting Tab key clears all the chars you just entered, and moves focus to the next control in the form. Moving focus is expected, but clearing the text you've just typed seems odd to me, and will be confusing for users. Some users may expect Tab to complete the selection (as it does in, for example, Visual Studio/Code intellisense), but they would not expect it to undo the work they just did.

Also, if you enter partial text, then arrow-down to high-light an item in the list, then hit Tab, your selection is not chosen (highlighted item is lost), and your text is cleared. All your work is undone.

I suggest the control be changed to preserve the text already entered at minimum, and ideally provide a hook for the caller of the control to be able to take their own custom action upon Tab keypress (to select the first item, for example).

Double click required when editing selected item

When an item is selected and you want to change it. Clicking on the input puts the control back into search mode but the focus is not on the input. A further click is required to set focus on the control.

Add a disabled parameter

For use in a business application having a disabled option is a must (or we could create a look-alike control to show instead but ick!) Please add disabled support!

If Disabled is true:

  • Disable input element
  • HandleClear and ShowMaximumSuggestions should not be wired or should return before doing any work
  • Hover effects over blazored-typeahead__input__icon should be disabled
  • placeholder text should not be shown

Multiple

How can i do a multiple select values?

merge my fork in

Its been suggested that I merge my fork back into this project. However the code has drifted a lot. Do we still want me to merge my source in?

Issues/Differences

  1. I made large changes to the html and css structure. We'd need to pick the best UI.
  2. I removed the need for the separator form input control.
  3. Added multi-select support
  4. Added keyboard selection support
  5. Added support for binding to a diff value then what the search result is

thoughts?

Demo: LoreSoft Blazor Controls
Repo: LoreSoft.Blazor.Controls

thanks,
~ Paul

Close dropdown on click

I think it would be great to have the dropdown menu closed when you click anywhere on the screen outside of it. If you do not have the dropdown button enabled and end up not wanting to select an item or not finding an item, there is no easy way to close it.

Endless onfocus loop

There is an endless loop occuring in the component.
To reproduce:

  1. Set a breakpoint in the setter of the _searchText
  2. Optionally set the default Debounce value to 5000000 (so we know it's not coming from here.
    => endless onfocus loop

To fix this issue:

  • change onfocus to onclick in the input of the control.

TwoWay Binding of Value

I want to set the currently selected Value from the outside. Looks like we need to add some kind of UI state refresh if Value changes.

I might make up a PR for this.

NotFoundResult should show when the showsuggestions is clicked and has no results.

Currently when the user clicks the dropdownarrow and wants to see the results, the NotFound is not showing if there are no results (meaning: the searchfunction returned no items).

Basically it's because of the IsValidSearch in the ShowNotFound method.

Currently:

        protected bool ShowNotFound()
        {
            return IsShowingSuggestions &&
                   HasValidSearch &&
                   !IsSearchingOrDebouncing &&
                   !Suggestions.Any();
        }

FIX:

        protected bool ShowNotFound()
        {
            return IsShowingSuggestions &&
                   !IsSearchingOrDebouncing &&
                   !Suggestions.Any();
        }

BlazoredTypeaheadInputBase<> could not be found

I just upgraded to version 3.0.1 and now I get this error.
I am using the standalone version. Did I miss something after the upgrade?

The type or namespace name 'BlazoredTypeaheadInputBase<>' could not be found (are you missing a using directive or an assembly reference?) D:\dev\test\obj\Debug\netcoreapp3.0\RazorDeclaration\Forms\BlazoredTypeaheadInput.razor.g.cs 56

Header templates

Nyaamaste.

It would be great if the library could support a header template as well as a footer template. The header could be used to add a "Add product" or similar button or a checkbox to toggle a filter. The footer could be used for paging and showing the number of returned rows.

Thank you !

Downloaded Blazored.Typeahead 4.1 & received the following error on compile

I used the example found here: https://chrissainty.com/getting-started-with-blazored-typeahead/

@page "/typeahead"

<h3>Typeahead</h3>

<BlazoredTypeahead SearchMethod="SearchFilms"
				   @bind-Value="SelectedFilm">
	<SelectedTemplate>
		@context.Title
	</SelectedTemplate>
	<ResultTemplate>
		@context.Title (@context.Year)
	</ResultTemplate>
</BlazoredTypeahead>

@if (SelectedFilm != null)
{
	<p>Selected Film is: @SelectedFilm.Title</p>
}

@code {

	private List<Film> Films;
	private Film SelectedFilm;

	protected override void OnInitialized()
	{
		Films = new List<Film> {
			new Film("The Matrix", 1999),
			new Film("Hackers", 1995),
			new Film("War Games", 1983) };
	}

	private async Task<List<Film>> SearchFilms(string searchText)
	{
		return await Task.FromResult(Films.Where(x => x.Title.ToLower().Contains(searchText.ToLower())).ToList());
	}

	class Film
	{
		public string Title { get; set; }
		public int Year { get; set; }

		public Film(string title, int year)
		{
			Title = title;
			Year = year;
		}
	}

}

During compile, I received the following errors:

typeahead_errors

The razor component doesn't show any errors until compile time.

Support Arrow Keys to navigate the Suggestions

#31 Made it possible to use Escape, Tab, Delete, Backspace, OnFocusOut etc.

This issue is to make it possible to use the arrow keys of the keyboard in the suggestion-result to navigate up/down.

Possible solution:

  • Not sure yet, still have to investigate.

Clicking on footer template closes suggestion list

Clicking on the footer template, or any of the elements inside the footer template causes the component to close the suggestion list.

The footer template can be used in a variety of ways, including:

  • Showing suggestion/item count.
  • Showing a label with a description or help.
  • Showing a link/logo to the service providing the suggestions (like weather service provider).

Clicking outside the list entirely should obviously close the suggestions list.

GIF in the readme

It could be easier for people to see what the component does if we added a GIF to the readme. I personally like repo's like that since then I don't have to check out the demo, but get a brief idea of what the component is all about.

Using ScreenToGif this can be done quite easily

onfocusout should hide the suggestions

Currently the suggestions are not hidden when the input loses focus. This won't be an easy fix if you only use C# though. Since the onfocusout event isn't fully supported in Blazor yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.