the-urlist / BlazorSortable

A sortable list component for Blazor
MIT License
150 stars 22 forks source link

Sort is corrupted when using a custom component in SortableItemTemplate #6

Open GerardFR opened 7 months ago

GerardFR commented 7 months ago

When using a custom component in SortableItemTemplate, the sorted output can be corrupted. Actually, it seems that sorting is right, but the display of the components doesn't happen in the correct order, and the visual result is wrong. I created a testing repository that illustrates the issue, with a simple component that displays a text, or another one that shows an image. Both have the same issue. See here.

The following code works fine:

<SortableList Class="d-flex flex-wrap gap-2" Id="text1" Items="Texts" OnUpdate="SortList" Context="text">
    <SortableItemTemplate>
        <div class="card" style="width:5rem;height:5rem">
            <div class="card-body">
                @text
            </div>
        </div>
    </SortableItemTemplate>
</SortableList>

But that one has the issue:

<SortableList Class="d-flex flex-wrap gap-2" Id="text1" Items="Texts" OnUpdate="SortList" Context="text">
    <SortableItemTemplate>
        <TextComponent Text="@text" />
    </SortableItemTemplate>
</SortableList>

where TextComponent has the code from the previous section:

<div class="card" style="width:5rem;height:5rem">
    <div class="card-body">
        @Text
    </div>
</div>

@code {
    [Parameter]
    public string? Text { get; set; }
}

Here is a capture showing the issue. The three blocks show the same list and the should always be synchronized, but the last one is wrong. I just moved 6 before 5. The issue only seems to happen if you start by moving an item to the left.

image

My feeling is that there is a synchronization issue, but I can't figure out where it comes from.

TheRookster commented 6 months ago

Hi @GerardFR I faced a similar issue. If you wrap your component in a div, does it work as expected?

<SortableItemTemplate>
  <div>
        <TextComponent Text="@text" />
  </div>
</SortableItemTemplate>
GerardFR commented 6 months ago

Yes that fixes it, thank you! The only drawback I can see is that adding a div breaks the layout of the component. I had to move some css classes from the component to the div, which makes it less encapsulated. But I can live with that...

nabeelfarooqui98 commented 4 months ago

Hi @GerardFR I faced a similar issue. If you wrap your component in a div, does it work as expected?

<SortableItemTemplate>
  <div>
        <TextComponent Text="@text" />
  </div>
</SortableItemTemplate>

I wasted so much time trying to figure this out. For me it would sometimes work and sometimes not. I thought it was an issue related to the UI not updating even though the list was updated in the code.

Adding a div wrapper seems to have fixed it!

GerardFR commented 4 months ago

Hi @nabeelfarooqui98 yes, it seems to fix it, as you can see in my previous answer 😉

joshmackay commented 2 months ago

Hi @GerardFR I faced a similar issue. If you wrap your component in a div, does it work as expected?

<SortableItemTemplate>
  <div>
        <TextComponent Text="@text" />
  </div>
</SortableItemTemplate>

Thanks for this, something so simple that I had not tried yet. Completely eliminated the issue.