Attempting to create drag/drop dual list component

Hi.  

I have need in my app for a means to select items from available lists in more than one place, which I would like to do with two listboxes which you can drag/drop items between.

I can do this following the example here: https://blazor.syncfusion.com/demos/listbox/drag-and-drop?theme=fluent

however, since I want to do this in a few places, with lists of different types of objects, I want to encapsulate this in a re-usable component.

I have managed to basically achieve this with this component:

---------------------------------------

@typeparam TItem
@using Syncfusion.Blazor.DropDowns;
@using Syncfusion.Blazor.Lists


  <div id="drag-drop-wrapper">
    <div class="listbox-control left-box">
        <h5>Available</h5>
        <SfListBox
            DataSource="@ItemList"
            Scope="@Scope"
            TItem="TItem"
            AllowDragAndDrop="true"
            Height="330px"
            TValue="TItem"
            NoRecordsTemplate="NoRecs()"
        >
            <ItemTemplate>
                @GetItemTemplate(context)
            </ItemTemplate>
        </SfListBox>
    </div>
    <span class="e-swap-icon"></span>
    <div class="listbox-control right-box">
        <h5>Selected</h5>
        <SfListBox
            DataSource="@SelectedList"
            Scope="@Scope"
            TItem="TItem"
            AllowDragAndDrop="true"
            Height="330px"
            TValue="TItem"
            NoRecordsTemplate="NoRecs()"
            @onchange="ChangeSelected"
        >
        <ItemTemplate>
            @GetItemTemplate(context)
        </ItemTemplate>
        </SfListBox>
    </div>
</div>
@code {
    [Parameter]
    public string? Scope{ get; set; }


    [Parameter]
    public IEnumerable<TItem>? ItemList{ get; set; }


    [Parameter]
    public List<TItem>? SelectedList { get; set; }


    [Parameter]
    public RenderFragment<TItem>? ItemTemplate { get; set; }


    [Parameter]
    public Func<TItem, string> GetDisplayItem { get; set; }


    [Parameter]
    public EventCallback<List<TItem>> SelectedListChanged{ get; set; }


    [Parameter]
    public string? NoItemsText { get; set; }


    async Task ChangeSelected()
    {
        await SelectedListChanged.InvokeAsync(SelectedList);
    }


    RenderFragment NoRecs() => builder =>
       {
           builder.AddContent(1, NoItemsText ?? "No Items Selected");
       };


    RenderFragment GetItemTemplate(TItem context) => builder =>
    {
        builder.AddContent(1, GetDisplayItem(context));
    };
}
-----------------------

And it is used like this in a page:

--------------------------------------

<DragDropListSelector
    @bind-SelectedList="@Selected"
    ItemList="@Available"
    NoItemsText="nothing here"
    Scope="group-fields-scope"
    TItem="CountryCode"
    GetDisplayItem="x=>x.Name">
</DragDropListSelector>
-------------------------

And it almost works - it shows the lists OK, and you can pick up to drag items...  but you can't drop the items (it just gets ignored)

I'm not sure what I've done wrong here - is it due to my use of ItemTemplate rather than ListBoxFieldSettings?

I have attached a minimal example solution which implements a "working" example as per the demo and under that a non-working equivalent using my component version.

Can anyone let me know where I've gone wrong here?


Attachment: DragDropListbox_dc13bcf.zip

1 Reply

YA YuvanShankar Arunagiri Syncfusion Team November 16, 2022 09:57 AM UTC

We have validated the attached sample and found an issue in your code.

TItem and TValue would miss-match in Index and DragDropListSelector file. And we need to set the field setting for the list box. Refer to the below code snippet.

<SfListBox                                               

            DataSource="@ItemList"

            Scope="@Scope"

            TItem="CountryCode"

            AllowDragAndDrop="true"

            Height="330px"

            TValue="string[]"

            NoRecordsTemplate="NoRecs()"

        >    

        <ListBoxFieldSettings

                    Text="Name"

                    Value="Code">

                </ListBoxFieldSettings>

                <ListBoxTemplates TItem="CountryCode">

            <ItemTemplate>               

                @GetItemTemplate(context)

            </ItemTemplate>

            </ListBoxTemplates>

        </SfListBox>


Attachment: BlazorApp1net6_1c4554e.zip

Loader.
Up arrow icon