マウスによるドラッグ&ドロップで table の行を入れ替える jQuery プラグイン を GridView に適用してみました。
プラグインのダウンロード先とその使い方の詳しい説明は Table Drag and Drop JQuery plugin を見てください。
ブラウザ上で table の行を入れ替えるだけであれば、目的の table 要素を初期化するだけで可能です。例えば、以下のように、table-1 という id を持つ table 要素にプラグインを適用すれば、それだけでマウスよる行の移動が可能になります。
<script type="text/javascript">
$(document).ready(function() {
// Initialise the table
$("#table-1").tableDnD();
});
</script>
しかしながら、これだけではクライアント側で行の入れ替えができるだけで、あまり役には立ちません。普通は入れ替えた結果をサーバー側で取得して、何らかの処置を行う必要があると思います。
入れ替えた結果を取得するために serialise() というメソッドが用意されています。これを以下のように適用すると table-1[]=rowId1&table-1[]=rowId2&table-1[]=rowId3... という並び順の文字列を取得して alert に表示します。この文字列で、table-1 はプラグインを適用する table の id です。rowId1, rowId2, rowId3... は tr 要素の id です。table の id に [] が追加されているのは、php での処置を考えてのことのようです。
$('#table-1').tableDnD({
onDrop: function(table, row) {
alert($.tableDnD.serialize());
}
});
serialise() メソッドで取得した文字列を、行をドロップしたタイミングでサーバーに送信すれば、サーバーでの処置が可能になります。以下に GridView を使ったサンプルコードを書いてみました。jQuery Ajax を利用して文字列を web サービスに送信し、それを編集してクライアントに戻しています。
GridView にプラグインを適用する場合、(1) table の id は ClientID でなければならないこと、(2) tr 要素に id を設定しなければならないことに注意してください。
サンプルコードを実際に動かして試せるよう 実験室 にアップしましたので、興味のある方は試してみてください。
(1) aspx ページ (149-GridViewAndTableDnD2.aspx)
<%@ Page Title="" Language="C#"
MasterPageFile="~/TestMasterPage.master" %>
<%@ Import Namespace="System.Data" %>
<script runat="server">
// データソース用の DataTable を作成
protected DataTable CreateDataTable()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("ID", typeof(Int32)));
dt.Columns.Add(new DataColumn("Name", typeof(string)));
dt.Columns.Add(new DataColumn("Price", typeof(Int32)));
dt.Columns.Add(new DataColumn("Qty", typeof(Int32)));
dt.Columns.Add(new DataColumn("Amount", typeof(Int32)));
dt.Columns.Add(new DataColumn("Note", typeof(string)));
for (int i = 0; i < 10; i++)
{
dr = dt.NewRow();
dr["ID"] = i;
dr["Name"] = "Name_" + i.ToString();
dr["Price"] = 123000 * (i + 1);
dr["Qty"] = (i + 1) * 20;
dr["Amount"] = 123000 * (i + 1) * (i + 1);
dr["Note"] = "Note_" + i.ToString();
dt.Rows.Add(dr);
}
return dt;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = CreateDataTable();
GridView1.DataBind();
}
}
// tr 要素に id を設定。serialise() メソッドは id の
// 値を順に取得して並び順の文字列を生成する。
protected void GridView1_RowDataBound(
object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Attributes["id"] = "row_header";
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView drv = (DataRowView)e.Row.DataItem;
e.Row.Attributes["id"] =
"row_" + ((int)drv["ID"]).ToString();
}
}
</script>
<asp:Content ID="Content1"
ContentPlaceHolderID="head"
Runat="Server">
<script src="../Scripts/jquery-1.4.1.min.js"
type="text/javascript">
</script>
<script src="../Scripts/jquery.tablednd.js"
type="text/javascript">
</script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
$("#<%=GridView1.ClientID%>").tableDnD({
onDrop: function (table, row) {
$.ajax({
type: "POST",
url: "149-GridViewAndTableDnD.asmx/GetResult2",
// serialize() で取得できる並び順の文字列は
// <クライアントID>[]=<tr 要素の id>&... と
// なる。なので、<クライアントID>[] という
// 文字列も一緒にサーバーに送信しておく。
// 2013/1/3 正しい JSON 文字列になるよう修正。
data: '{"clientId":"<%=GridView1.ClientID%>[]",' +
'"data":"' + $.tableDnD.serialize() + '"}',
// JSON の受け渡しには必須
contentType: "application/json; charset=utf-8",
dataFilter: function (data) {
var msg = "";
// ブラウザの native JASON パーサがあれ
// ばそれを使う(セキュリティ対策)。
if (typeof (JSON) !== 'undefined' &&
typeof (JSON.parse) === 'function') {
msg = JSON.parse(data);
} else {
msg = eval('(' + data + ')');
}
// .NET 3.5 で追加された d パラメータの処置
if (msg.hasOwnProperty('d')) {
return msg.d;
} else {
return msg;
}
},
success: function (data) {
$('#AjaxResult').empty();
$('#AjaxResult').append('サーバーの応答<br />');
$.each(data, function (index, data) {
$('#AjaxResult').append(data + '<br />');
});
},
error: function (jqXHR, textStatus, errorThrown) {
$('#AjaxResult').text('Status: ' + textStatus +
', Error: ' + errorThrown);
}
});
}
});
});
//]]>
</script>
</asp:Content>
<asp:Content ID="Content2"
ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
<div id="AjaxResult" style="padding: 4px;
border-color: silver; border-width: 1px;
border-style: solid; float: right">
<h3>Ajax result</h3>
<p>行を入れ替えた結果が表示されます。</p>
</div>
<asp:GridView ID="GridView1" runat="server"
OnRowDataBound="GridView1_RowDataBound">
</asp:GridView>
</asp:Content>
(2) マスターページ (TestMasterPage.master)
<%@ Master Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>WebSurfer's Home - 実験室</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="ContentPlaceHolder1"
runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
(3) Web サービス (149-GridViewAndTableDnD.asmx)
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
using System.Collections.Specialized;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class _149_GridViewAndTableDnD: WebService
{
[WebMethod]
public string[] GetResult2(string clientId, string data)
{
string[] items = data.Split(new char[] { '&' });
NameValueCollection nameValue =
new NameValueCollection();
for (int i = 0; i < items.Length; i++)
{
string[] nv = items[i].Split(new char[] { '=' });
nameValue.Add(nv[0], nv[1]);
}
// キーが clientId の値の配列を返す。
return nameValue.GetValues(clientId);
}
}