เทคนิคการขยับแถวขึ้นลงใน Table ด้วยวิธี Drag & Drop ใน Blazor

สำหรับ blog นี้ของผู้เขียน ถือว่าเป็นซีรี่ส์ที่ต่อเนื่องมาจาก https://sysadmin.psu.ac.th/2021/05/25/ขยับแถว-row-ขึ้น-ลง-ใน-asp-net-gridview-ด้วย-j/ และ https://sysadmin.psu.ac.th/2021/05/27/ขยับแถว-row-ขึ้น-ลง-ใน-asp-net-gridview-ด้วย-c/ ก็คือผู้เขียนจะนำเสนอวิธีการขยับแถวอีกวิธีหนึ่ง ที่น่าจะเฟรนด์ลี่ต่อผู้ใช้มากกว่า นั่นก็การ Drag & Drop ก็คือผู้ใช้งานสามารถเลือกคลิก ลาก และวาง เพื่อจัดลำดับได้ตามความต้องการ ซึ่งเมื่อผู้เขียนมาทำงานบน Blazor พบว่าการ implement เรื่องนี้สามารถทำได้ง่ายมาก โดยไม่ต้องพี่งพา javascript แต่อย่างใด เรามาดูกันเลยครับ

1. เพิ่มโค้ด HTML ในส่วนของการแสดงผลข้อมูลในรูปแบบ Table

@if (provinces != null)
{
    <table class="table table-striped" >
        <thead>
            <tr >
                <th>ลำดับ</th>
                <th>จังหวัด</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var pr in provinces)
            {
                <tr role="button" class="cursor-pointer"  >
                    <td>@pr.ID</td>
                    <td>@pr.Name</td>
                </tr>
            }
        </tbody>
    </table>
}

2. เพิ่มโค้ด C# ในส่วนที่ควบคุมการทำงานและจำลองข้อมูล

private List<Province> provinces = new List<Province>();

protected override void OnInitialized()
{

	provinces.AddRange(new List<Province> {
		new Province(1,"สงขลา"),
		new Province(2,"ปัตตานี"),
		new Province(3,"ยะลา"),
		new Province(4,"นราธิวาส"),
		new Province(5,"สตูล")
	});

}

public class Province
{
	public Int32 ID;
	public string Name;
	public Province(int id, string name)
	{
		ID = id;
		Name = name;
	}
}

ซึ่งจะได้ผลลัพธ์หน้าจอดังรูป และเป้าหมายของเราก็คือสามารถคลิกเลือกจังหวัด จากนั้นลากและวางไปยังตำแหน่งที่ต้องการได้

3. จากนั้นเพิ่มโค้ดส่วนที่ควบคุมการ Drag และ Drop ทั้งใน HTML และ C#

@if (provinces != null)
{
    <table class="table table-striped" ondragover="event.preventDefault();">
        <thead>
            <tr >
                <th>ลำดับ</th>
                <th>จังหวัด</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var pr in provinces)
            {
                <tr role="button" class="cursor-pointer" draggable="true"
            @ondrop="@(()=> Drop(pr))" @ondrag="@(e => StartDrag(pr))" >
                    <td>@pr.ID</td>
                    <td>@pr.Name</td>
                </tr>
            }
        </tbody>
    </table>
}
  • ondragover=”event.preventDefault();” เป็นการขัดขวางการทำงานปกติของการ drag บน object เพื่อให้สามารถ drop ได้
  • @ondrop=”@(()=> Drop(pr))” เรียกฟังก์ชัน Drop พร้อมกับส่ง pr (จังหวัด) เมื่อมีเหตุการณ์ drop เกิดขึ้น
  • @ondrag=”@(e => StartDrag(pr))” เรียกฟังก์ชัน StartDrage พร้อมกับส่ง pr เมื่อมีเหตุการณ์ drag เกิดขึ้น
/// <summary>
/// เก็บตำแหน่งของจังหวัดที่คลิกเลือก เมื่อเริ่ม drag
/// </summary>
/// <param name="province"></param>
private void StartDrag(Province province)
{
	currentIndex = GetIndex(province);
}

/// <summary>
/// หาตำแหน่งของจังหวัดที่อยู่จาก list
/// </summary>
/// <param name="province"></param>
/// <returns></returns>
int GetIndex(Province province)
{
	return provinces.FindIndex(p => p.ID == province.ID);
}

/// <summary>
/// เมื่อ Drop จังหวัดที่ drag มาลงในตำแหน่งที่ต้องการ
/// </summary>
/// <param name="province"></param>
void Drop(Province province)
{
	if (province != null)
	{
		// หาตำแหน่งของจังหวัดที่ถูก drop
		var index = GetIndex(province);

		// หาจังหวัดที่ถูก drag มา จาก index ที่เก็บไว้ตั้งแต่เริ่ม drag
		var current = provinces[currentIndex];

		// ลบจังหวัดที่ถูก drag มา ออกจาก list
		provinces.RemoveAt(currentIndex);

		// แทรกจังหวัดที่ถูก drag มา ลงในตำแหน่งที่ drop
		provinces.Insert(index, current);

		StateHasChanged();
	}
}

4. เมื่อทดสอบการทำงาน รายชื่อจังหวัดในตารางจะสามารถคลิก ลาก และวางไปยังตำแหน่งที่ต้องการได้

5. และเมื่อ drop ลงไปยังตำแหน่งที่ต้องการ จังหวัดที่ลากมาก็จะแทรกเข้าไปยังตำแหน่งที่ drop

ขั้นตอนถัดไป ท่านผู้อ่านก็แค่ทำการบันทึกตำแหน่งใหม่ของจังหวัดลงในฐานข้อมูลหรือทำอย่างอื่นได้ต่อไป ซึ่งวิธีการนี้เราสามารถนำไปประยุกต์ใช้กับคอมโพเน้นอื่นๆ ได้ เช่น li, div หรืออย่างอื่นที่ผู้ใช้ในการนำเสนอข้อมูลในรูปแบบรายการ

ผู้เขียนหวังเป็นอย่างยิ่งว่าบทความนี้น่าจะมีประโยชน์ต่อผู้อ่านไม่มากก็น้อย แล้วเจอกันใหม่โอกาสหน้า สวัสดีครับ


แหล่งข้อมูลอ้างอิง