0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Drag&Dropの裏側の処理(備忘録)

Last updated at Posted at 2022-08-15

Drag&Dropって結構Webアプリだと当たり前になってきてるし、フロントサイドだとJqueryUIやReactなどライブラリを使用すればすぐできる世の中だと思います。ただ裏側(サーバサイド)の処理ってどう実装するんだっけと、ふと思い書いてみました。

まず、前提としてフロントだけで完結せず、サーバサイドの実装あるものとしてます。

初期状態(前提条件)

↓↓↓ 順序の情報をもってるテーブル ↓↓↓
image.png
※ここでは上記テーブルをT_○○と命名しておきます
※またorder_noでソートしたものを表示する

Drag&Dropの手順

  1. フロントサイドでDrag&Dropの操作をして、サーバサイドに以下の情報を送る。
    ・動かそうとしているorder_no (from_order_noと呼びます)
    ・動そうとしている先にいるitemのorder_no (to_order_noと呼びます)
  2. from_order_noとto_order_noの間にあるorder_noを増減させる。
  3. 対象itemのorder_noをto_order_noで更新する。

パッと見、文字だけだと分かりづらいので、図で例を示します。


ex.)id=2をid=4, 5の間にDrag&Dropする。
つまり、id=2のorder_noを4で更新したい時
image.png
 ↓

id=2のorder_noを更新する前に、id=3, 4のorder_noを1減らす
image.png

id=2のorder_noを4で更新する
image.png
の手順を実装していきます。
ただ今回は上から下へDrag&Dropをしました(from_order_no < to_order_no)が、下から上へとDrag&Dropした(from_order_no > to_order_no)時も同じようにfrom_order_noとto_order_noの間のorder_noを調整する必要があり、若干今回の例と異なります。
ここは考えてみてください...

実装

実装しちゃいます。
あ、言語はC#です。

/// <summary>
/// Drag&Dropのサーバサイド側の処理
/// </summary>
/// <param name="fromOrderNo">移動前のorder_no</param>
/// <param name="toOrderNo"  >移動先のorder_no</param>
public void DragAndDrop(int fromOrderNo, int toOrderNo)
{
    // SQLへ接続、Transactionの処理は今回省略します....

    var command = new SqlCommand();
    command.Connection = connection; // connectionは上で定義してください
    
    var headOrderNo = fromOrderNo < toOrderNo ? (fromOrderNo + 1) : toOrderNo;
    var tailOrderNo = fromOrderNo < toOrderNo ? toOrderNo : (fromOrderNo - 1);
    var step = fromOrderNo < toOrderNo ? -1 : 1;
    
    // fromOrderNoとtoOrderNoの範囲内のorderNoを調整する
    IncrementTargetRangeOrderNo(command, headOrderNo, tailOrderNo);

    // fromOrderNoとtoOrderNoを入れ替える
    ReplaceOrderNo(command, fromOrderNo, toOrderNo);    

    // SQL接続終了の処理....
}

/// <summary>
/// 指定範囲内のorder_noを増減させる
/// </summary>
/// <param name="cmd">SqlCommand</param>
/// <param name="headOrderNo">orderNoの範囲指定の先頭</param>
/// <param name="tailOrderNo">orderNoの範囲指定の末尾</param>
/// <param name="step">増減数(マイナス値を入れれば減少数)</param>
private void IncrementTargetRangeOrderNo(SqlCommand cmd, int headOrderNo, int tailOrderNo, int step = 1)
{
    cmd.CommandText = @"
UPDATE
  T_◯◯
SET
  order_no = order_no + @step
WHERE
  order_no >= @head_order_no
AND
  order_no <= @tail_order_no
";
    cmd.Parameters.Add(new SqlParameter("@step", step));
    cmd.Parameters.Add(new SqlParameter("@head_order_no", headOrderNo));
    cmd.Parameters.Add(new SqlParameter("@tail_order_no", tailOrderNo));
    cmd.ExecuteNonQuery();
}

/// <summary>
/// 指定したorder_noへ置き換える
/// </summary>
/// <param name="cmd">SqlCommand</param>
/// <param name="headOrderNo">orderNoの範囲指定の先頭</param>
/// <param name="tailOrderNo">orderNoの範囲指定の末尾</param>
private void ReplaceOrderNo(SqlCommand cmd, int fromOrderNo, int toOrderNo)
{
    cmd.CommandText = @"
UPDATE
  T_◯◯
SET
  order_no = @to_order_no
WHERE
  order_no = @from_order_no
";
    cmd.Parameters.Add(new SqlParameter("@from_order_no", fromOrderNo));
    cmd.Parameters.Add(new SqlParameter("@to_order_no", toOrderNo));
    cmd.ExecuteNonQuery();
}

これでいけたかな?

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?