บางครั้งการแสดงผลข้อมูลใน Gridview จะมีความต้องการให้ผู้ใช้งานสามารถกำหนดลำดับข้อมูลได้ ในบทความนี้ผู้เขียนจะยกตัวอย่างการประยุกต์ใช้ jQuery มาเพิ่มความสามารถให้กับ Gridview ให้สามารถขยับแถวที่ต้องการไปอยู่ในตำแหน่งที่ต้องการได้
โดยมีขั้นตอนดังต่อไปนี้
1. เพิ่มโค้ด HTML สำหรับแสดงผลข้อมูล Gridview
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:GridView ID="gvBib" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="BIB_NO" HeaderText="Bib#" />
<asp:BoundField DataField="TITLE" HeaderText="Title" />
<asp:BoundField DataField="AUTHOR" HeaderText="Author" />
<asp:BoundField DataField="CALL_NO" HeaderText="CallNo" />
<asp:BoundField DataField="ISBN" HeaderText="ISBN" />
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<button class="up">UP</button>
<button class="down">DOWN</button>
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
จะสังเกตว่าจะมีฟิลด์ที่เป็น ItemTemplate สำหรับแสดงผลปุ่ม UP และปุ่ม DOWN สำหรับใช้ในการเลื่อน row นั้นๆ ขึ้นหรือลง
และเหตุผลที่จะต้องมี UpdatePanel ครอบปุ่มไว้ เพราะทุกครั้งที่มีการกด จะเกิดการ Postback ทำให้ข้อมูลจะถูก Bind ซ้ำ การเรียงลำดับก็จะกลับคืนไปเหมือนเดิม จึงจำเป็นต้องทำ Partial Load เพื่อป้องกันการ Bind ข้อมูลซ้ำ
2. เพิ่มโค้ดใน event Page_Load ในหน้า code behind เพื่อจำลองข้อมูลที่จะใช้แสดงใน GridView
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[5] { new DataColumn("BIB_NO"),
new DataColumn("TITLE"),
new DataColumn("AUTHOR"),
new DataColumn("CALL_NO"),
new DataColumn("ISBN")});
dt.Rows.Add("001", "1 ทศวรรษ ดัชนีสุขภาพคนไทย", "สำนักงานคณะกรรมการสุขภาพแห่งชาติ (สช.)", "WA13 ห159 2556", "9786160822258");
dt.Rows.Add("002", "ความลับในร่างกายมนุษย์ที่เราไม่เคยรู้", "ฟรานซิส, เกวิน", "QS4 ฟ133a 2560", "9786168022887");
dt.Rows.Add("003", "The best ICU", "ดุสิต สถาวร", "WX218 B561 2560", "9786168122020");
dt.Rows.Add("004", "COVID-19 โรคระบาดแห่งศตวรรษ", "นำชัย ชีววิวรรธน์", "QW168.5.C8 น515c 2563", "9789740217060");
dt.Rows.Add("005", "Good health & smart life ในวัย 40+", "ไวต์, จอห์น", "WT104 ว967g 2560", "9786160827237");
gvBib.DataSource = dt;
gvBib.DataBind();
}
}
เนื่องจากโค้ดตัวอย่างมีการใช้งาน class DataTable และ DataColumn ซึ่งอยู่ใน namespace System.Data เพราะฉะนั้นจะต้อง Import namespace นี้ด้วย
using System.Data;
3. เพิ่มโค้ด jQuery สำหรับควบคุมการทำงานปุ่ม UP/DOWN โดยหลักการทำงานคือ เมื่อคลิกปุ่ม UP หรือ DOWN แถวที่เลือก จะถูกขยับหรือลง 1 เรคคอร์ด
//เมื่อคลิกปุ่ม UP
$(document).on("click", ".up", function () {
//เก็บเร็คคอร์ดที่ถูกคลิกเอาไว้
var curRow = $(this).closest('tr');
//ย้ายเร็คคอร์ดปัจจุบัน ไปอยู่ในตำแหน่งก่อนหน้า เร็คคอร์ดที่อยู่ก่อนหน้า
curRow.insertBefore(curRow.prev());
});
//เมื่อคลิกปุ่ม DOWN
$(document).on("click", ".down", function () {
var curRow = $(this).closest('tr');
curRow.insertAfter(curRow.next());
});
เมื่อทดลองรัน จะปรากฏผลลัพธ์ดังรูปด้านล่าง
//เมื่อคลิกปุ่ม UP
$(document).on("click", ".up", function () {
//เก็บเร็คคอร์ดที่ถูกคลิกเอาไว้
var curRow = $(this).closest("tr");
//เก็บเร็คคอร์ดแรกสุดของตารางเอาไว้ ซึ่งก็คือเรคคอร์ดหัวตาราง
//ที่เราจะไม่อนุญาตให้เอาเรคคอร์ดอื่นมาแทรก
var firstRow = $("[id*=gvBib] tr:first");
//ตรวจสอบว่าเร็คอคอร์ดก่อนหน้าของเร็คคอร์ดที่เรากดปุ่ม คือเร็คคอร็ดที่เป็นหัวตารางหรือไม่
//ถ้าไม่ใช่ก็จะทำการย้ายเร็คคอร์ด
if (curRow.prev().html() != firstRow.html() ) {
//ย้ายเร็คคอร์ดปัจจุบัน ไปอยู่ในตำแหน่งก่อนหน้า เร็คคอร์ดที่อยู่ก่อนหน้า
curRow.insertBefore(curRow.prev());
}
});
เมื่อทดสอบอีกครั้ง ก็จะพบว่า ไม่สามารถกด UP เรคคอร์ดที่อยู่ใต้ Header ได้อีกแล้ว
ก็หวังเป็นอย่างยิ่งว่าบทความนี้จะมีประโยชน์ไม่มากก็น้อยต่อผู้อ่าน ที่สามารถนำไปประยุกต์ใช้กับงานของตัวเองได้ สวัสดีครับ
แหล่งข้อมูลอ้างอิง
- https://stackoverflow.com/questions/16524497/jquery-to-move-row-up-and-down
- https://stackoverflow.com/questions/36243730/jquery-to-compare-rows-in-two-tables