diff --git a/Demos/Blazorise.Demo/Pages/Tests/DropdownListPage.razor b/Demos/Blazorise.Demo/Pages/Tests/DropdownListPage.razor index e152a36185..9d833c7aa0 100644 --- a/Demos/Blazorise.Demo/Pages/Tests/DropdownListPage.razor +++ b/Demos/Blazorise.Demo/Pages/Tests/DropdownListPage.razor @@ -19,7 +19,8 @@ @bind-SelectedValue="@selectedDropValue" Color="Color.Primary" MaxMenuHeight="200px" - DropdownToggleSize="Size.Large"> + DropdownToggleSize="Size.Large" + Filterable> Select item diff --git a/Source/Extensions/Blazorise.Components/DropdownList.razor b/Source/Extensions/Blazorise.Components/DropdownList.razor index 87a85762a3..57b946d746 100644 --- a/Source/Extensions/Blazorise.Components/DropdownList.razor +++ b/Source/Extensions/Blazorise.Components/DropdownList.razor @@ -3,28 +3,31 @@ @typeparam TValue @ChildContent - - @if ( Data != null ) + + @if ( Filterable ) { - @if ( Virtualize && Data is ICollection collectionableData ) - { - - @itemFragment( item ) - - } - else + + + + } + @if ( Virtualize && FilteredData is ICollection collectionableData ) + { + + @itemFragment( item ) + + } + else + { + @foreach ( var item in FilteredData ?? Enumerable.Empty() ) { - @foreach ( var item in Data ?? Enumerable.Empty() ) - { - @itemFragment( item ) - } + @itemFragment( item ) } } + @code { - protected RenderFragment itemFragment => item => __builder => - { + protected RenderFragment itemFragment => item => __builder => { var text = GetItemText( item ); var value = GetItemValue( item ); var disabled = GetItemDisabled( item ); @@ -32,6 +35,6 @@ @text + CheckedChanged="@((isChecked) => HandleDropdownItemChecked( isChecked, value ))">@text }; } \ No newline at end of file diff --git a/Source/Extensions/Blazorise.Components/DropdownList.razor.cs b/Source/Extensions/Blazorise.Components/DropdownList.razor.cs index 26ee1a66b9..0489ff7638 100644 --- a/Source/Extensions/Blazorise.Components/DropdownList.razor.cs +++ b/Source/Extensions/Blazorise.Components/DropdownList.razor.cs @@ -31,6 +31,8 @@ public partial class DropdownList : ComponentBase private List selectedValues; + private IEnumerable filteredData; + #endregion #region Methods @@ -103,6 +105,34 @@ private bool GetItemDisabled( TItem item ) return DisabledItem.Invoke( item ); } + private void FilterData( IQueryable query ) + { + dirtyFilter = false; + if ( !Filterable || string.IsNullOrEmpty( FilterText ) ) + { + filteredData = Data; + return; + } + + if ( query == null ) + { + filteredData = Enumerable.Empty(); + return; + } + + if ( TextField == null ) + return; + + filteredData = Data.Where( x => TextField.Invoke( x ).Contains( FilterText, StringComparison.OrdinalIgnoreCase ) ); + } + + private Task OnFilterTextChangedHandler( string filteredText ) + { + FilterText = filteredText; + dirtyFilter = true; + return Task.CompletedTask; + } + #endregion #region Properties @@ -148,6 +178,20 @@ protected bool IsSelected( TValue value ) /// [Parameter] public IEnumerable Data { get; set; } + private IEnumerable FilteredData + { + get + { + if ( dirtyFilter ) + FilterData( Data?.AsQueryable() ); + return filteredData; + } + } + + private bool dirtyFilter = true; + + private string FilterText { get; set; } + /// /// Method used to get the display field from the supplied data source. /// @@ -168,6 +212,11 @@ protected bool IsSelected( TValue value ) /// [Parameter] public EventCallback SelectedValueChanged { get; set; } + /// + /// Enebles filter text input on the top of the items list. + /// + [Parameter] public bool Filterable { get; set; } + /// /// Custom classname for dropdown element. ///