MudBlazor MudAutocomplete - how to show 'name's in the list, but bind an Id?
Asked Answered
G

2

7

My model looks like this

public partial class EditModel
{
    public int Id { get; set; }
...

    public string Item { get; set; }
}

My SearchItems method header looks like this

protected async Task<IEnumerable<ListItem>> SearchItems(string value)

which returns 'list' of these

public partial class ListItem
{
    public string Id { get; set; }
    public string Name { get; set; }
}

How do I get my MudAutocomplete to show the Name, yet return/bind the Id?

<MudAutocomplete T="ListItem" Label="Select item" @bind-Value="EditModel.Item"
    Clearable="true"
    MinCharacters="4" SearchFunc="@SearchItems"
    ToStringFunc="@(i => i==null ? null : $"{i.Id} [{i.Name}]")"
    SelectValueOnTab="true"/>  

on the @bind-Value, Visual studio shows this error

...cannot convert from 'string' to 'EditModel.Item'

Gynandromorph answered 28/3, 2022 at 22:38 Comment(1)
The problem is that you want to bind a ListItem object to a EditModel.Item object - they are different objects. What you need to do is to remove the ListItem object, you don't need it - just filter over a list of EditModels and then you will be properly binding EditModels to EditModels.Dispart
G
8

This is how I solved it for now...

My SearchItems method now just returns a list of string

protected async Task<IEnumerable<string>> SearchItems(string value)

I've put this attribute in the MudAutocomplete

ToStringFunc="@(i => ItemDisplay(i))" 

This is my ItemDisplay method

private string ItemDisplay(string itemId)
{
    var item = ListItems.FirstOrDefault(i => i.Id == itemId);

    return item == null ? "!Not Found!" : $"{item.Id} [{item.Name}]";
}

I've had to add this to my ComponentBase, to 'cache' all the ListItems for use in ItemDisplay() method:

public List<ListItem> ListItems { get; set; } = new();

In OnInitializedAsync()

ListItems = await MyService.GetItemsAsync();

I've set up my GetItemsAsync() to use IMemoryCache (Microsoft.Extensions.Caching.Memory), but I still don't like this approach. I find it difficult to believe that this component does not support the feature.

Gynandromorph answered 31/3, 2022 at 17:2 Comment(1)
it helped me. thanks for contrubuting mudblazor community.Foppery
P
7

Maybe the component is updated but I was able to achieve this by using the following approach which I think is good.

The model you want to use

record State(Guid Id, string Name);

The binding value

private State value1;

The search function returns IEnumerable<State>

private async Task<IEnumerable<State>> Filter(string value)
{
    // Filtering logic
}

Finally, I am using ToStringFunc to define how values are displayed in the drop-down list

<MudAutocomplete T="State" ToStringFunc="@(state => state.Name)" Label="US States" @bind-Value="value1" SearchFunc="@Filter" Variant="Variant.Outlined"/>
Pavlodar answered 12/9, 2022 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.