'Blazor: Drag & Drop list elements
I would like to know how to bind Drag & Drop events to rearrange items in a list.
This is the code I have:
<PageTitle>Drag & Drop</PageTitle>
<ul style="border:1px solid black">
@foreach (var item in Items)
{
<li draggable="true" @* draggable *@
@[email protected]
id="@item.Id"
@* how to bind drag events? *@
>@item.Label</li>
}
</ul>
@code {
public class Item
{
public int Id {get; set;}
public string Label {get; set; } = default!;
}
public List<Item> Items = new() {
new Item(){Id= 1, Label = "hi 1"},
new Item(){Id= 2, Label = "hi 2"},
new Item(){Id= 3, Label = "hi 3"},
new Item(){Id= 4, Label = "Move me!"},
};
}
Solution 1:[1]
Here I illustrate some basic Drag & Drop html5 event handling operations just with Blazor:
Here is the code, self explanatory.
@page "/"
<PageTitle>Drag & Drop Sample</PageTitle>
<ul style="border:1px solid black">
@foreach (var item in Items)
{
<li draggable="true"
class="@(DragEnter==item?"inserting":"")"
@[email protected]
id="@item.Id"
ondragover="event.preventDefault();"
@ondragstart="@( (e) => hondragstart(e, item))"
@ondrop="@( () => hondropOverAFriend(item))"
@ondragenter="@( ()=> hondragenter(item) )"
@ondragend="@( ()=> hondragend() )"
>@item.Label</li>
}
<div style="height: 1.5em;"
ondragover="event.preventDefault();"
@ondrop="hondropBotton"
@ondragenter="hondragenterBotton"
/>
</ul>
<style>
.inserting
{
border-top: 1px solid black;
margin-top: 5px;
}
</style>
@code {
public class Item
{
public int Id {get; set;}
public string Label {get; set; } = default!;
}
public List<Item> Items = new() {
new Item(){Id= 1, Label = "hi 1"},
new Item(){Id= 2, Label = "hi 2"},
new Item(){Id= 3, Label = "hi 3"},
new Item(){Id= 4, Label = "Move me!"},
};
public void hondropOverAFriend(Item friend)
{
DragEnter=null;
if (DraggedItem == null) return;
if (DraggedItem == friend) return;
var friendposition = Items.IndexOf(friend);
Items.Insert(friendposition, DraggedItem!);
DraggedItem=null;
}
public void hondropBotton()
{
DragEnter=null;
if (DraggedItem == null) return;
Items.Add(DraggedItem!);
DraggedItem=null;
}
public void hondragstart(DragEventArgs e, Item item)
{
e.DataTransfer.EffectAllowed = "move"; //does't run
DraggedItem = item;
DraggedItemPosition = Items.IndexOf(item);
Items.Remove(DraggedItem!);
}
public void hondragenter(Item item)
=>
DragEnter = item;
public void hondragenterBotton()
=>
DragEnter = null;
public void hondragend()
{
// never fired IDK why
if (DraggedItem == null) return;
DragEnter = null;
Items.Insert(DraggedItemPosition, DraggedItem!);
}
private Item? DraggedItem;
private int DraggedItemPosition;
private Item? DragEnter;
}
Disclaimer
They are some things that I don't know how to do without JSInterop, for example, I was unable to change EffectAllowed
or to set data on DataTransfer
. People, be free to improve code!
Solution 2:[2]
If you change @ondragend="@(()=> hondragend())" to @ondragend="hondragend" It will fire the event on your code
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | user3275015 |