Skip to content

[dev-v5] FluentAutocomplete debug cases #4716

@MarvinKlein1508

Description

@MarvinKlein1508

I crafted together this debug code which showcases my usage of the FluentAutocomplete component.

It includes 5 examples and a small description of the issue I'm facing.

💻 Repro or Code Sample

@page "/Debug/Test"

<div style="padding: 1rem; overflow-y: auto;">
    <h2>FluentAutoComplete</h2>

    <h3>Example 1</h3>
    <p>In this example I want to bind to <code>int?</code> but the search should work with the class instead. <code>@@bind-SelectedItem</code> can't be used here for some reason</p>
    @* @bind-SelectedItem does not work here *@
    <FluentAutocomplete TValue="int?"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        Multiple="false"
                        Width="100%"
                        Label="Location"
                        @bind-Value="InputAutocomplete.CompanyLocationId" />

    <p>Selected: @(InputAutocomplete.CompanyLocationId?.ToString() ?? "<NULL>")</p>

    <h3>Example 1 pre applied values</h3>

    <FluentAutocomplete TValue="int?"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        Multiple="false"
                        Width="100%"
                        Label="Location"
                        @bind-Value="InputAutocompletePreAppliedValues.CompanyLocationId" />

    <p>Selected: @(InputAutocompletePreAppliedValues.CompanyLocationId?.ToString() ?? "<NULL>")</p>


    <h3>Example 2</h3>
    <p>In this example I bind to <code>CompanyLocation?</code>. This works as expected. However when you click on the component then the first option has a gray background (I think because it is the current highlighted by keyboard)</p>
    <FluentAutocomplete TValue="CompanyLocation"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        OptionText="(o => o.Name)"
                        Multiple="false"
                        Width="100%"
                        Label="Location"
                        @bind-SelectedItem="InputAutocomplete.CompanyLocation" />

    <p>Selected: @(InputAutocomplete.CompanyLocation?.Name ?? "<NULL>")</p>

    <h4>Pre applied values</h4>
    <FluentAutocomplete TValue="CompanyLocation"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        OptionText="(o => o.Name)"
                        Multiple="false"
                        Width="100%"
                        Label="Location"
                        @bind-SelectedItem="InputAutocompletePreAppliedValues.CompanyLocation" />

    <p>Selected: @(InputAutocompletePreAppliedValues.CompanyLocation?.Name ?? "<NULL>")</p>

    <h3>Example 3</h3>
    <p>In this example I bind to <code>DayOfWeek?</code>. For some reason you cannot provide the items with <code>Enum.GetValues</code>. They have to be casted in order for the control to work. The question here is why is this not necessary in example 2?</p>
    <FluentAutocomplete TValue="DayOfWeek?"
                        TOption="DayOfWeek?"
                        Items="Enum.GetValues<DayOfWeek>().Cast<DayOfWeek?>()"
                        Width="100%"
                        Multiple="false"
                        Label="Day"
                        @bind-SelectedItem="InputAutocomplete.DayOfWeek" />

    <p>Selected: @(InputAutocomplete.DayOfWeek?.ToString() ?? "<NULL>")</p>

    <h4>Pre applied values</h4>
    <FluentAutocomplete TValue="DayOfWeek?"
                        TOption="DayOfWeek?"
                        Items="Enum.GetValues<DayOfWeek>().Cast<DayOfWeek?>()"
                        Width="100%"
                        Multiple="false"
                        Label="Day"
                        @bind-SelectedItem="InputAutocompletePreAppliedValues.DayOfWeek" />

    <p>Selected: @(InputAutocompletePreAppliedValues.DayOfWeek?.ToString() ?? "<NULL>")</p>

    <h3>Example 4</h3>
    <p>In this example I bind to <code>IEnumerable&lt;CompanyLocation&gt;?</code>. When I change <code>Locations</code> to a nullable and remove the assignment then the code will compile fine but the app will crash.</p>
    <FluentAutocomplete TValue="CompanyLocation"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        OptionSelectedComparer="CompanyLocationComparer.Instance"
                        OptionText="(o => o.Name)"
                        Width="100%"
                        MaxAutoHeight="unset"
                        Multiple="true"
                        Label="Locations"
                        @bind-SelectedItems="InputAutocomplete.Locations" />

    <p>
        Selected:
        @if (InputAutocomplete.Locations is null)
        {
            <text>&lt;NULL&gt;</text>
        }
        else
        {
            <text>@(String.Join(", ", InputAutocomplete.Locations.Select(x => x.Name)))</text>

        }
    </p>


    <h4>Pre applied values</h4>

    <FluentAutocomplete TValue="CompanyLocation"
                        TOption="CompanyLocation"
                        OnOptionsSearch="OnSearchCompanyLocationsAsync"
                        OptionSelectedComparer="CompanyLocationComparer.Instance"
                        OptionText="(o => o.Name)"
                        Width="100%"
                        MaxAutoHeight="unset"
                        Multiple="true"
                        Label="Locations"
                        @bind-SelectedItems="InputAutocompletePreAppliedValues.Locations" />

    <p>
        Selected:
        @if (InputAutocompletePreAppliedValues.Locations is null)
        {
            <text>&lt;NULL&gt;</text>
        }
        else
        {
            <text>@(String.Join(", ", InputAutocompletePreAppliedValues.Locations.Select(x => x.Name)))</text>
        }
    </p>

    <h3>Example 5</h3>
    <p>In this example I bind to <code>IEnumerable&lt;DayOfWeek&gt;?</code>. When I change <code>Days</code> to a nullable and remove the assignment then the code will compile fine but the app will crash.</p>
    <FluentAutocomplete TValue="DayOfWeek"
                        TOption="DayOfWeek"
                        OnOptionsSearch="OnSearchDaysAsync"
                        Width="100%"
                        MaxAutoHeight="unset"
                        Multiple="true"
                        Label="Days"
                        @bind-SelectedItems="InputAutocomplete.Days" />

    <p>
        Selected:
        @if (InputAutocomplete.Days is null)
        {
            <text>&lt;NULL&gt;</text>
        }
        else
        {
            <text>@(String.Join(", ", InputAutocomplete.Days))</text>
        }
    </p>

    <h4>Pre applied values</h4>
    <FluentAutocomplete TValue="DayOfWeek"
                        TOption="DayOfWeek"
                        OnOptionsSearch="OnSearchDaysAsync"
                        Width="100%"
                        MaxAutoHeight="unset"
                        Multiple="true"
                        Label="Days"
                        @bind-SelectedItems="InputAutocompletePreAppliedValues.Days" />

    <p>
        Selected:
        @if (InputAutocomplete.Days is null)
        {
            <text>&lt;NULL&gt;</text>
        }
        else
        {
            <text>@(String.Join(", ", InputAutocompletePreAppliedValues.Days))</text>
        }
    </p>
</div>



@code {

    Task OnSearchCompanyLocationsAsync(OptionsSearchEventArgs<CompanyLocation> e)
    {
        var locations = new List<CompanyLocation>
        {
            new CompanyLocation { Id = 1, Name = "New York" },
            new CompanyLocation { Id = 2, Name = "London" },
            new CompanyLocation { Id = 3, Name = "Tokyo" },
            new CompanyLocation { Id = 4, Name = "Sydney" }
        };

        e.Items = locations;
        return Task.CompletedTask;
    }

    Task OnSearchDaysAsync(OptionsSearchEventArgs<DayOfWeek> e)
    {
        e.Items = Enum.GetValues<DayOfWeek>();
        return Task.CompletedTask;
    }

    public MyInput InputAutocomplete { get; set; } = new();
    public MyInput InputAutocompletePreAppliedValues { get; set; } = new()
    {
        CompanyLocationId = 1,
        CompanyLocation = new CompanyLocation { Id = 2, Name = "London" },
        DayOfWeek = DayOfWeek.Saturday,
        Locations = [new CompanyLocation { Id = 1, Name = "New York" }, new CompanyLocation { Id = 2, Name = "London" },],
        Days = [DayOfWeek.Monday, DayOfWeek.Friday]
    };
    public MyInput InputSelect { get; set; } = new();

    public class MyInput
    {
        public int? CompanyLocationId { get; set; }

        public CompanyLocation? CompanyLocation { get; set; }

        public DayOfWeek? DayOfWeek { get; set; }

        public IEnumerable<CompanyLocation> Locations { get; set; } = [];

        public IEnumerable<DayOfWeek> Days { get; set; } = [];
    }

    public class CompanyLocation
    {
        public int Id { get; set; }
        public required string Name { get; set; }
    }

    public class CompanyLocationComparer : IEqualityComparer<CompanyLocation>
    {
        public static CompanyLocationComparer Instance { get; } = new CompanyLocationComparer();

        public bool Equals(CompanyLocation? x, CompanyLocation? y)
        {
            if (ReferenceEquals(x, y))
            {
                return true;
            }

            if (x is null || y is null)
            {
                return false;
            }

            return x.Id == y.Id;
        }

        public int GetHashCode(CompanyLocation obj) => HashCode.Combine(obj.Id);
    }
}

Metadata

Metadata

Assignees

Labels

status:needs-investigationNeeds additional investigationv5For the next major version

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions