Skip to content

Instantly share code, notes, and snippets.

@dev-cyprium
Created October 27, 2023 23:08
Show Gist options
  • Select an option

  • Save dev-cyprium/f26cc3e81186433272f3f1e4b9c17770 to your computer and use it in GitHub Desktop.

Select an option

Save dev-cyprium/f26cc3e81186433272f3f1e4b9c17770 to your computer and use it in GitHub Desktop.
Combo-box
@using LeagueHandlerCore.DTO.Forms
@inject IJSRuntime JSRuntime
<div @ref="containerRef" data-external-click>
<input type="hidden" name="home-id">
<label for="combobox" class="block text-sm font-medium leading-6 text-gray-900">@Label</label>
<div class="relative mt-2">
<h1>Show Dropdown: @ShowDropdown</h1>
<input @onfocus="OnFocus" @bind:event="oninput" @bind="Search" id="combobox" type="text" class="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" role="combobox" aria-controls="options" aria-expanded="@ShowDropdown">
@if (ShowDropdown)
{
<ul class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" id="options" role="listbox">
@foreach (var item in Filtered)
{
<button class="block w-full h-full text-left" type="button" @onmouseup="() => SetSelected(item)">
<li class="hover:text-white hover:bg-indigo-600 cursor-pointer relative select-none py-2 pl-3 pr-9 text-gray-900" id="option-0" role="option" tabindex="-1">
<span class="block truncate">@item.Name</span>
@if (item.Id == SelectedItem.Id)
{
<span class="absolute inset-y-0 right-0 flex items-center pr-4 text-indigo-600">
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd"/>
</svg>
</span>
}
</li>
</button>
}
</ul>
}
</div>
</div>
@code {
private ElementReference containerRef;
private DotNetObjectReference<ComboBox> objRef;
private Func<Task> outsideClickHandler;
private bool ShowDropdown { get; set; }
private string Search { get; set; } = "";
private List<SelectItem> Filtered
{
get
{
return string.IsNullOrEmpty(Search) ? Items : Items.Where(i => i.Name.Contains(Search)).ToList();
}
}
private SelectItem? SelectedItem { get; set; }
[Parameter]
public string Label { get; set; }
[Parameter]
public List<SelectItem> Items { get; set; }
[Parameter]
public string Active { get; set; }
private void SetSelected(SelectItem item)
{
SelectedItem = item;
Search = item.Name;
ShowDropdown = false;
}
protected override void OnInitialized()
{
SelectedItem = Items.FirstOrDefault(i => i.Id == Active);
Search = SelectedItem?.Name ?? "";
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
objRef = DotNetObjectReference.Create(this);
outsideClickHandler = async () => await JSRuntime.InvokeVoidAsync("addEventListener", "click",
objRef, "HandleOutsideClick", containerRef);
await outsideClickHandler.Invoke();
}
}
private void OnFocus()
{
ShowDropdown = true;
Search = "";
}
[JSInvokable]
public void HandleOutsideClick()
{
ShowDropdown = false;
Search = SelectedItem?.Name ?? "";
StateHasChanged();
}
public async ValueTask DisposeAsync()
{
await JSRuntime.InvokeVoidAsync("removeEventListener", "click", outsideClickHandler);
objRef?.Dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment