削除確認ダイアローグ
削除欄にある x をクリックすると、
削除確認ダイアローグ
を出すようにしています。
練習プログラムでは、
<td class="pseude_link" hx-delete="/del_institution/26/5" hx-target="closest tr" hx-swap="delete swap:1s" hx-confirm="データを削除します。削除したデータを戻すことはできません。">x</td>
としています。
class="pseude_link"は、アスタリスクに下線を付け、マウスを持って行くとカーソルを変えるようにするクラスの指定で、プログラム的な意味はありません。
今回は htmx にある、1行削除のデモを参考にしました。
動作は
- x (<td>\タグ)をクリックすると、
- hx-confirm属性により、確認ダイアローグが開き、
- ダイアローグの「OK」を選択すると、AJAXが発火し、
- hx-delete属性により、HTTPのDELETEメソッドで、サーバーの/del_institution/26/5にアクセスし、
- hx-target属性により、サーバーからの応答で、idに"inst_26"を持つタグの中身を、
- hx-swap属性に示された方法(delete:タグのすべてを消す)で、書き換えようとしますが、
- idに"inst_26"を持つタグには、hx-on属性が付けてあり、内容が書き換えられる前に(before-swap)、サーバーの応答をchange_institution()関数で評価し、
- サーバーの処理が成功していたら処理を継続、失敗していたら書き換えを中断します。
というものです。
サーバーの対応
サーバーでは、@router.delete('/del_institution/{ID}/{version}')で修飾してある関数で、編集するデータを整形して出力しています。
@router.delete('/del_institution/{ID}/{version}')
def del_institution(ID:int , version:int):
'''指定されたデータを削除する
- ID : データの番号
- version : 更新回数
- return : 処理結果
'''
conn = mydb.connect(**config.database)
cur = conn.cursor(dictionary=True)
sql = ("DELETE FROM `sightseeing` WHERE (ID = %s ) AND (`更新回数` = %s) ")
cur.execute(sql , (ID , version))
if cur.rowcount != 1:
ret = "データを削除しませんでした。別のPCで変更されている可能性があります。"
else:
ret = "データを削除しました"
cur.close()
conn.close()
return PlainTextResponse(ret)
排他制御に「更新回数」を使っています。
戻り値は、プレーンテキストで返しています。
サーバーからの応答の評価
hx-target="closest tr"で、「x」のある<td>タグの親の<tr>の内容を、hx-swap="delete swap:1s"として、削除しますが、親要素の<tr>には、
hx-on::before-swap="change_institution(event)"の属性を付けて、書き換える前に返事の内容を評価しています。
change_institution(event)は、
/**
* Ajaxの戻り値を判断して1行を書き換える
*/
function change_institution(event) {
close_dialog();
if (event.detail.xhr.status == 200) {
// (通信)成功時の処理
responseText = event.detail.xhr.responseText;
if (responseText == 'データを削除しました') {
return;
}
if (!responseText.includes('<tr')) {
alert(responseText);
console.table(event.detail.xhr);
event.preventDefault();
}
} else {
// 失敗時の処理
alert("サーバーとの通信に失敗しました");
console.table(event.detail.xhr);
event.preventDefault();
}
}
とし、
サーバーからの返事が「データを削除しました」であれば、何もせずに関数から抜け、要素の書き換え(削除)を行います。
もし、返事に<trが含まれていない=行を書き換えない場合=は、event.preventDefault()でJavaScriptの実行を中断しています。
hx-swapの修飾子
ドキュメントには5種類が示されています。
練習プログラムでは、hx-swap="delete swap:1s"として、置換の開始を1秒遅らせています。
併せてCSSで
tr.htmx-swapping {
opacity: 0;
transition: opacity 1s ease-out;
}
と指定して、「ゆっくり消える」ようにしています。
おわり
「htmxを使ってみた」記事は、本編でおわりです。
もっと詳しく知りたい人は、htmxのホームページを見てください。
紹介できなかった(私の理解が及ばなかった)属性や機能がたくさんあります。
htmxを使ってみた感想
htmxはjQueryの代替になりそうです。
AJAXはすてきな機能だと思いますが、ブラウザのレンダリングエンジンを書いている人は大変でしょうね。
関連記事一覧
htmxを使ってみた-(1)htmxの基本-
htmxを使ってみた-(2)準備-
htmxを使ってみた-(3)ルート関数-
htmxを使ってみた-(4)htmxを使う-
htmxを使ってみた-(5)HTMLのdialog-
htmxを使ってみた-(6)データの表示-
htmxを使ってみた-(7)データ追加-
htmxを使ってみた-(8)要素の変更-
htmxを使ってみた-(9)ページの再読み込み-
htmxを使ってみた-(10)データの変更-
htmxを使ってみた-(11)データベースの排他制御-
htmxを使ってみた-(12)確認ダイアローグ-
htmxを使ってみた-(13)データ削除-(最終)