Created Shared Dropdown Component

I want to create a shared component for list of country that I can use in different places. I have done it like this, I just want to check, If the approach I'm doing is good or not, if not then how can I do this.

MultiSelectCountryDropDownDataGrid.razor

<RadzenDropDownDataGrid Name="CountriesDropDown" Style="width: 100%;" @ref="dropDownGrid" AllowSelectAll="false" IsLoading="IsLoading" Density="LocalAppSate.Density" PageSize="GetRequestInput.MaxResultCount" Multiple=true AllowClear="true" @bind-Value=@ValueEnumerable Change="@((arg) => OnValueChanged(arg))"
                        LoadData=@LoadProcesses AllowFiltering="true"
                        Data=@Data Count="@(GetCount())"  TextProperty="Name" ValueProperty="Id" Placeholder="Select Countries" Chips=true>

    <Columns>

        <RadzenDropDownDataGridColumn Width="60px" Sortable="false">
            <HeaderTemplate>
                <RadzenCheckBox  Disabled="@(!dropDownGrid.AllowSelectAll)" TriState="false" TValue="bool" Value="@(Data != null && Data.Any(c => ValueEnumerable != null && ValueEnumerable.Contains(c.Id)))"
                                Change="@(args => ValueEnumerable = args ? dropDownGrid.View.Cast<CountryDto>().Select(c => c.Id) : ValueEnumerable = Enumerable.Empty<string>())"/>
            </HeaderTemplate>
            <Template Context="data">
                <RadzenCheckBox  TriState="false" Value="@(ValueEnumerable != null && ValueEnumerable.Contains(((CountryDto)data).Id))"
                                TValue="bool" Change=@(_ => dropDownGrid.SelectItem(data)) @onclick:stopPropagation/>
            </Template>
        </RadzenDropDownDataGridColumn>
        <RadzenDropDownDataGridColumn Property="AlphaTwoLaterCode" Title="Two Later Code" Width="80px"/>
        <RadzenDropDownDataGridColumn Property="Name" Title="Name" Width="200px"/>
        <RadzenDropDownDataGridColumn MinWidth="100px" Property="RFC" Title="RFC" Sortable="false" Filterable="false" TextAlign="TextAlign.Center">
            <Template Context="data">
                <RequestForChangesStatus SubHeading="@(nameof(EntityKind.Country) + ": " + data.Name)" RequestForChangeInfos="data.RequestForChange"></RequestForChangesStatus>
            </Template>
        </RadzenDropDownDataGridColumn>
    </Columns>
</RadzenDropDownDataGrid>

MultiSelectCountryDropDownDataGrid.razor


public partial class MultiSelectCountryDropDownDataGrid : ComponentBase
{
    
    RadzenDropDownDataGrid<IEnumerable<string>> dropDownGrid;
    [Inject] ICountryService CountryService { get; set; }
    Response<PaginationResponse<CountryDto>> response;
    bool IsLoading = false;
    private IEnumerable<CountryDto>? Data;
    [Parameter]
    public GetRequestInput GetRequestInput { get; set; } = new ();
    
    private IEnumerable<string>? ValueEnumerable { get; set; }

    private List<string> _value;

    [Parameter]
    public List<string> Value
    {
        get => _value;
        set
        {
            if (_value != value)
            {
                _value = value;
                ValueEnumerable = value;
            }
        }
    }
 
    [Parameter]
    public EventCallback<List<string>> ValueChanged { get; set; }

    [Parameter] public List<string> IdsToDisable { get; set; } = new();
 
    async Task LoadProcesses(LoadDataArgs args)
    {
        IsLoading = true;
        await Task.Yield();
        GetRequestInput.SkipCount = args.Skip ?? 0;
        GetRequestInput.MaxResultCount = args.Top ?? 10;
        GetRequestInput.Filter = args.Filter;
        GetRequestInput.OrderBy = args.OrderBy;
        IsLoading = true;
        response = await CountryService.Get(GetRequestInput, CancellationToken.None);
        if (response is { Data.Items: not null })
        {
            Data = response.Data.Items.Where(c => !IdsToDisable.Contains(c.Id)).ToList();
        }
        IsLoading = false;
        await InvokeAsync(StateHasChanged);
    }

    int GetCount()
    {
        if (response is { Data: not null })
        {
            return response.Data.TotalCount;
        }
        return 0;
    }
    
    private async Task OnValueChanged(object newValue)
    {
        if (newValue is IEnumerable<string> newValueEnumerable)
        {
            ValueEnumerable = newValueEnumerable;
            await ValueChanged.InvokeAsync(newValueEnumerable.ToList());
        }
        else
        {
            Console.WriteLine("Invalid value type");
        }
    }
}

in used in different component

<MultiSelectCountryDropDownDataGrid @bind-Value="@createOrUpdateRequest.StandardCountries">

looking someone to verify the way, I'm doing is good and it is the approach to do it.

It looks like a valid approach - composition of a new component.

1 Like

Thank you for looking into it.
I was not so sure about bind-Value use on Shared component created using RadzenDropDownDataGrid. where RadzenDropDownDataGrid bind-Value needs to bind with parent component of shared component created using RadzenDropDownDataGrid