Skip to content

Commit

Permalink
Merge pull request #94 from Blazored/updates
Browse files Browse the repository at this point in the history
A few bug fixes
  • Loading branch information
chrissainty authored Dec 6, 2019
2 parents d80279f + 5257d2a commit aee3c94
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 54 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ steps:
- task: DotNetCoreInstaller@0
displayName: 'Installing .NET Core SDK...'
inputs:
version: 3.0.100
version: 3.1.100

- task: NuGetToolInstaller@0
displayName: 'Installing NuGet Tools...'
Expand Down
4 changes: 0 additions & 4 deletions samples/BlazorClientSide/BlazorClientSide.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RestoreAdditionalProjectSources>
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnet.myget.org/F/blazor-dev/api/v3/index.json;
</RestoreAdditionalProjectSources>
<LangVersion>7.3</LangVersion>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>
Expand Down
9 changes: 1 addition & 8 deletions src/Blazored.Typeahead/Blazored.Typeahead.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<RootNamespace>Blazored.Typeahead</RootNamespace>

<PackageId>Blazored.Typeahead</PackageId>
<Version>4.2.0</Version>
<Version>4.2.1</Version>
<Authors>Chris Sainty</Authors>
<Description>A typeahead control for Blazor applications</Description>
<Copyright>Copyright 2019 (c) Chris Sainty. All rights reserved.</Copyright>
Expand All @@ -23,13 +23,6 @@
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.0" />
</ItemGroup>

<ItemGroup>
<!-- .js/.css files will be referenced via <script>/<link> tags; other content files will just be included in the app's 'dist' directory without any tags referencing them -->
<EmbeddedResource Include="wwwroot\**\*.js" LogicalName="blazor:js:%(RecursiveDir)%(Filename)%(Extension)" />
<EmbeddedResource Include="wwwroot\**\*.css" LogicalName="blazor:css:%(RecursiveDir)%(Filename)%(Extension)" />
<EmbeddedResource Include="wwwroot\**" Exclude="**\*.js;**\*.css" LogicalName="blazor:file:%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
<None Include="wwwroot\blazored-typeahead.js" />
</ItemGroup>
Expand Down
9 changes: 4 additions & 5 deletions src/Blazored.Typeahead/BlazoredTypeahead.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

@typeparam TItem
@typeparam TValue
@inherits BlazoredTypeaheadBase<TItem, TValue>

<div class="blazored-typeahead @FieldCssClasses" @ref="typeahead">
<div class="blazored-typeahead @FieldCssClasses">

<div class="blazored-typeahead__controls">

Expand Down Expand Up @@ -70,7 +69,7 @@
}
}

<input @ref="searchInput"
<input @ref="_searchInput"
@bind-value="SearchText"
@bind-value:event="oninput"
@onkeyup="HandleKeyup"
Expand All @@ -87,15 +86,15 @@
if (IsShowingMask)
{
<div class="blazored-typeahead__input-mask-wrapper">
<div class="blazored-typeahead__input-mask" @onclick="HandleClickOnMask" @onkeyup="HandleKeyUpOnMask" tabindex="0" @ref="mask">
<div class="blazored-typeahead__input-mask" @onclick="HandleClickOnMask" @onkeyup="HandleKeyUpOnMask" tabindex="0" @ref="_mask">
@SelectedTemplate(Value)
</div>
<div class="blazored-typeahead__clear" @onclick="HandleClear" tabindex="-1">
&#10005;
</div>
</div>
}
<input @ref="searchInput"
<input @ref="_searchInput"
@bind-value="SearchText"
@bind-value:event="oninput"
@onkeyup="HandleKeyup"
Expand Down
95 changes: 59 additions & 36 deletions src/Blazored.Typeahead/BlazoredTypeahead.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@

namespace Blazored.Typeahead
{
public class BlazoredTypeaheadBase<TItem, TValue> : ComponentBase, IDisposable
public partial class BlazoredTypeahead<TItem, TValue> : ComponentBase, IDisposable
{
private EditContext _editContext;
private FieldIdentifier _fieldIdentifier;
private Timer _debounceTimer;
private string _searchText = string.Empty;
private bool _eventsHookedUp = false;

protected ElementReference searchInput;
protected ElementReference mask;
protected ElementReference typeahead;
private ElementReference _searchInput;
private ElementReference _mask;

[Inject] private IJSRuntime JSRuntime { get; set; }

Expand Down Expand Up @@ -52,12 +50,12 @@ public class BlazoredTypeaheadBase<TItem, TValue> : ComponentBase, IDisposable
[Parameter] public bool EnableDropDown { get; set; } = false;
[Parameter] public bool ShowDropDownOnFocus { get; set; } = false;

protected bool IsSearching { get; private set; } = false;
protected bool IsShowingSuggestions { get; private set; } = false;
protected bool IsShowingMask { get; private set; } = false;
protected List<TItem> Suggestions { get; set; } = new List<TItem>();
protected int SelectedIndex { get; set; }
protected string SearchText
private bool IsSearching { get; set; } = false;
private bool IsShowingSuggestions { get; set; } = false;
private bool IsShowingMask { get; set; } = false;
private List<TItem> Suggestions { get; set; } = new List<TItem>();
private int SelectedIndex { get; set; }
private string SearchText
{
get => _searchText;
set
Expand All @@ -77,8 +75,8 @@ protected string SearchText
}
}

protected string FieldCssClasses => _editContext?.FieldCssClass(_fieldIdentifier) ?? "";
protected bool IsMultiselect => ValuesExpression != null;
private string FieldCssClasses => _editContext?.FieldCssClass(_fieldIdentifier) ?? "";
private bool IsMultiselect => ValuesExpression != null;

protected override void OnInitialized()
{
Expand Down Expand Up @@ -122,7 +120,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
if ((firstRender && !Disabled) || (!_eventsHookedUp && !Disabled))
{
await Interop.AddKeyDownEventListener(JSRuntime, searchInput);
await Interop.AddKeyDownEventListener(JSRuntime, _searchInput);
_eventsHookedUp = true;
}
}
Expand All @@ -139,7 +137,7 @@ private void Initialize()
IsShowingMask = Value != null;
}

protected async Task RemoveValue(TValue item)
private async Task RemoveValue(TValue item)
{
var valueList = Values ?? new List<TValue>();
if (valueList.Contains(item))
Expand All @@ -149,7 +147,7 @@ protected async Task RemoveValue(TValue item)
_editContext?.NotifyFieldChanged(_fieldIdentifier);
}

protected async Task HandleClear()
private async Task HandleClear()
{
SearchText = "";
IsShowingMask = false;
Expand All @@ -162,32 +160,42 @@ protected async Task HandleClear()
_editContext?.NotifyFieldChanged(_fieldIdentifier);

await Task.Delay(250); // Possible race condition here.
await Interop.Focus(JSRuntime, searchInput);
await Interop.Focus(JSRuntime, _searchInput);
}

protected async Task HandleClickOnMask()
private async Task HandleClickOnMask()
{
SearchText = "";
IsShowingMask = false;

await Task.Delay(250); // Possible race condition here.
await Interop.Focus(JSRuntime, searchInput);
await Interop.Focus(JSRuntime, _searchInput);
}

protected async Task HandleKeyUpOnShowDropDown(KeyboardEventArgs args)
private async Task HandleKeyUpOnShowDropDown(KeyboardEventArgs args)
{
if (args.Key == "Enter")
if (args.Key == "ArrowDown")
MoveSelection(1);
else if (args.Key == "ArrowUp")
MoveSelection(-1);
else if (args.Key == "Escape")
Initialize();
else if (args.Key == "Enter" && Suggestions.Count() == 1)
await SelectTheFirstAndOnlySuggestion();
else if (args.Key == "Enter" && SelectedIndex >= 0 && SelectedIndex < Suggestions.Count())
await SelectResult(Suggestions[SelectedIndex]);
else if (args.Key == "Enter")
await ShowMaximumSuggestions();
}

protected async Task HandleKeyUpOnMask(KeyboardEventArgs args)
private async Task HandleKeyUpOnMask(KeyboardEventArgs args)
{
switch (args.Key)
{
case "Enter":
IsShowingMask = false;
await Task.Delay(250); // Possible race condition here.
await Interop.Focus(JSRuntime, searchInput);
await Interop.Focus(JSRuntime, _searchInput);
break;
case "Backspace":
case "Delete":
Expand All @@ -198,7 +206,7 @@ protected async Task HandleKeyUpOnMask(KeyboardEventArgs args)
}
}

protected async Task HandleKeyup(KeyboardEventArgs args)
private async Task HandleKeyup(KeyboardEventArgs args)
{
if ((args.Key == "ArrowDown" || args.Key == "Enter") && EnableDropDown && !IsShowingSuggestions)
{
Expand All @@ -217,7 +225,7 @@ protected async Task HandleKeyup(KeyboardEventArgs args)
await SelectResult(Suggestions[SelectedIndex]);
}

protected async Task HandleInputFocus()
private async Task HandleInputFocus()
{
if (ShowDropDownOnFocus)
{
Expand All @@ -226,7 +234,7 @@ protected async Task HandleInputFocus()
}

private bool _resettingControl = false;
protected async Task ResetControl()
private async Task ResetControl()
{
if (!_resettingControl)
{
Expand All @@ -237,7 +245,7 @@ protected async Task ResetControl()
}
}

protected async Task ShowMaximumSuggestions()
private async Task ShowMaximumSuggestions()
{
if (_resettingControl)
{
Expand All @@ -262,7 +270,7 @@ protected async Task ShowMaximumSuggestions()
}
}

protected string GetSelectedSuggestionClass(TItem item, int index)
private string GetSelectedSuggestionClass(TItem item, int index)
{
const string resultClass = "blazored-typeahead__active-item";
TValue value = ConvertMethod(item);
Expand All @@ -283,7 +291,7 @@ protected string GetSelectedSuggestionClass(TItem item, int index)
return Equals(value, Value) ? resultClass : string.Empty;
}

protected async void Search(Object source, ElapsedEventArgs e)
private async void Search(Object source, ElapsedEventArgs e)
{
IsSearching = true;
await InvokeAsync(StateHasChanged);
Expand All @@ -294,7 +302,7 @@ protected async void Search(Object source, ElapsedEventArgs e)
await InvokeAsync(StateHasChanged);
}

protected async Task SelectResult(TItem item)
private async Task SelectResult(TItem item)
{
var value = ConvertMethod(item);

Expand All @@ -311,18 +319,24 @@ protected async Task SelectResult(TItem item)
}
else
{
Value = value;
await ValueChanged.InvokeAsync(value);
}

_editContext?.NotifyFieldChanged(_fieldIdentifier);

if (IsMultiselect)
{
await Interop.Focus(JSRuntime, searchInput);
await Interop.Focus(JSRuntime, _searchInput);
}
else
{
await Task.Delay(250);
await Interop.Focus(JSRuntime, _mask);
}
}

protected bool ShouldShowSuggestions()
private bool ShouldShowSuggestions()
{
return IsShowingSuggestions &&
Suggestions.Any();
Expand All @@ -348,16 +362,25 @@ private Task SelectTheFirstAndOnlySuggestion()
}

private bool IsSearchingOrDebouncing => IsSearching || _debounceTimer.Enabled;
protected bool ShowNotFound()
private bool ShowNotFound()
{
return IsShowingSuggestions &&
!IsSearchingOrDebouncing &&
!Suggestions.Any();
}

public void Dispose()
{
_debounceTimer.Dispose();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_debounceTimer.Dispose();
}
}
}
}
1 change: 1 addition & 0 deletions src/Blazored.Typeahead/wwwroot/blazored-typeahead.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@

.blazored-typeahead__input-icon:focus {
outline: none;
box-shadow: 0 0 0 0.2rem rgba(38,143,255,.5);
}

.blazored-typeahead__input-icon:hover {
Expand Down

0 comments on commit aee3c94

Please sign in to comment.