Úkol Drag and Drop

3. Řešení úkolu

Třída úkol
namespace DragAndDrop3.Models
{
    // Třída úkol, obsahuje pouze název
    public class Ukol
    {
        public string Nazev { get; set; } = "";
    }
}

Třída Úkol definuje jedinou vlastnost - Název. 


Razor komponenta
@page "/"
 
<h3>Seznam úkolů</h3>
 
<div class="container d-flex gap-4">
    <!-- Seznam úkolů k vyřízení, povolené dragover a v momentě upuštění zavolá metodu VlozitDoVyrizeni() -->
    <div class="drop-zone" ondragover="event.preventDefault();" @ondrop="VlozitDoVyrizeni">
 
        <h4>K vyřízení</h4>
 
        <!-- Výpis všech úkolů, které ještě nejsou zpracovány -->
        @foreach (var ukol in ukolyKeZpracovani)
        {
            <!-- Povolení draggable, volání funkce ZahajitPresun() -->
            <div class="draggable-item" draggable="true" @ondragstart="() => ZahajitPresun(ukol)">
                @ukol.Nazev
            </div>
        }
    </div>
 
    <!-- Seznam hotových úkolů, povolené dragover a v momentě upuštění zavolá metodu VlozitDoHotovo() -->
    <div class="drop-zone" ondragover="event.preventDefault();" @ondrop="VlozitDoHotovo">
 
        <h4>Hotovo</h4>
 
        <!-- Výpis všech úkolů, které jsou v seznamu hotovo -->
        @foreach (var ukol in hotoveUkoly)
        {
            <!-- Povolení draggable, volání funkce ZahajitPresun() -->
            <div class="draggable-item" draggable="true" @ondragstart="() => ZahajitPresun(ukol)">
                @ukol.Nazev
            <div>
        }
    </div>
</div>
 
<style>
    /* CSS styl cílové oblasti pro upuštění prvků */
    .drop-zone {
        width: 300px;
        min-height: 400px;
        border: 2px dashed #ccc;
        padding: 20px;
        background-color: #f9f9f9;
    }
    .draggable-item {
        padding: 10px;
        margin-bottom: 10px;
        background-color: #007bff;
        color: white;
        cursor: grab;
        border-radius: 5px;
    }
</style>
 
@code {
    // Kolekce pro oba sloupce (sjednoceno na Models.Ukol)
    List<Models.Ukol> ukolyKeZpracovani = new List<Models.Ukol>
    {
        new Models.Ukol { Nazev = "Napsat mail" },
        new Models.Ukol { Nazev = "Nakoupit" },
        new Models.Ukol { Nazev = "Uklidit" },
        new Models.Ukol { Nazev = "Vyvenčit psa" }
    };
 
    List<Models.Ukol> hotoveUkoly = new List<Models.Ukol>();
 
    // Pomocná proměnná pro právě přenášený objekt (nullable a privátní)
    private Models.Ukol? prenasenyUkol;
 
    // Metoda volaná při začátku tažení (@ondragstart)
    void ZahajitPresun(Models.Ukol ukol)
    {
        prenasenyUkol = ukol;
    }
 
    // Metoda volaná při upuštění do "Hotovo" (@ondrop)
    void VlozitDoHotovo()
    {
        // Ochrana proti null
        if (prenasenyUkol != null && !hotoveUkoly.Contains(prenasenyUkol))
        {
            hotoveUkoly.Add(prenasenyUkol);
            ukolyKeZpracovani.Remove(prenasenyUkol);
            prenasenyUkol = null; // Reset
        }
    }
 
    // Metoda volaná při upuštění zpět do "K vyřízení" (@ondrop)
    void VlozitDoVyrizeni()
    {
        if (prenasenyUkol != null && !ukolyKeZpracovani.Contains(prenasenyUkol))
        {
            ukolyKeZpracovani.Add(prenasenyUkol);
            hotoveUkoly.Remove(prenasenyUkol);
            prenasenyUkol = null; // Reset
        }
    }
}

Atributem draggable="true" určujeme, že prvek HTML lze přesouvat, přičemž událost @ondragstart pomocí lambda výrazu () => ZahajitPresun(ukol) okamžitě ukládá instanci právě taženého úkolu do privátní proměnné prenasenyUkol. U cílových oblastí je pak nezbytné volat ondragover="event.preventDefault();", čímž se potlačí výchozí chování prohlížeče, které by jinak upuštění prvku zablokovalo. Jakmile uživatel prvek pustí, událost @ondrop zavolá příslušnou C# metodu (např. VlozitDoHotovo). V bloku @code tyto metody nejprve bezpečně ověří přítomnost objektu v dočasné proměnné a následně pomocí standardních metod Add a Remove na kolekcích List<Models.Ukol> zajistí přesun dat. Po vyresetování proměnné na null se Blazor automaticky postará o překreslení celého uživatelského rozhraní podle aktuálního stavu obou seznamů.