一部の画像や動画でUIが異なりますが、CSS修正の有無によるものでプログラム部分には影響はありません。
前回、収支データを出力することができました。
今回はその収支データの削除を画面からできるように実装していきます。
前回の記事はこちら↓
収支データの削除
収支データを削除ボタンから消すことができるように実装します。
流れとしては以下を想定しました。順番に実装していきます。
①本当に削除するかの確認アラートを出す(JavaScript)
②キャンセルの場合は遷移先を無効にする
③OKの場合は削除プログラムのファイルに遷移し削除実行
削除確認アラートを出す
確認アラートはJavaScriptで実装します。まずは確認アラートを出す関数をfunctions.jsに記述します。
const deleteConfirm = (title) => {
const confirmText = confirm(title + "を本当に削除しますか?");
}
confirm(‘確認内容’)でアラートを出すことができます。
この関数を、削除ボタンを押したときに呼び出すように削除ボタンにonclick属性を追加します。
※データ一覧はPCとスマホで2要素あるので、両方の削除ボタンのonclick属性にイベントを追記してください。
<!--PCで表示する要素-->
<a onclick="deleteConfirm('<?php echo h($title); ?>');"><!--class属性省略-->
<i class="fa-regular fa-trash-can"></i>
</a>
<!--スマホで表示する要素-->
<a onclick="deleteConfirm('<?php echo h($title); ?>');"><!--class属性など省略-->
削 除
</a>
引数はSQL実行で得た$titleを渡すように指定しています。
ここまで実装するとボタンを押した際に、確認アラート画面が画面上部に表示されるようになります。
しっかり引数も渡っていることがわかります。
それではキャンセルが押されたときとOKが押されたときの処理を実装していきます。
キャンセルの場合は遷移先を無効にする
まだ削除ボタンに遷移先を指定していませんが、キャンセルの場合に遷移先を無効にするプログラムを記述します。
const deleteConfirm = (title, target) => { //引数を追加
const confirmText = confirm(title + "を本当に削除しますか?");
//以下を追記
const targetRecord = document.getElementById(target);
if (!confirmText) {
targetRecord.setAttribute('href', '');
}
//追記ここまで
}
まず遷移先を無効にする削除ボタンを使いたいので、引数にtargetを追加します。
そしてhrefを無効化する削除ボタン要素をtargetRecordに格納します。
if文で (!confirmText)=キャンセルが押されたとき と条件を置き、処理を記述します。
今回はhrefを無効にするプログラムなので、先程記述した該当ボタンに .setAttribute(‘href’, ”)でhrefを空文字にする処理をしています。
それではJavaScriptで指定したidのhrefを操作するため、削除ボタン1つ1つに異なるidがつくようにid属性を指定します。
そして同じ値をonclick属性の第2引数として追加します。(スマホ表示の削除ボタンも同様)
<!--パソコン表示用-->
<a href="./delete.php" id="delete<?php echo h($id); ?>" onclick="deleteConfirm('<?php echo h($title); ?>', 'delete<?php echo h($id); ?>');">
<i class="fa-regular fa-trash-can"></i>
</a>
<!--スマホ表示用・idと2つ目の引数の末尾に文字列「sp」を加えています-->
<a href="./delete.php" id="delete<?php echo h($id); ?>sp" onclick="deleteConfirm('<?php echo h($title); ?>', 'delete<?php echo h($id); ?>sp');">
削 除
</a>
id属性と2つ目の引数として ‘delete<?php echo h($id);?>’ (パソコン用)、 ‘delete<?php echo h($id);?>sp’ (スマホ用) を追加しました。
※スマホ表示用には「sp」を末尾に付け加えています。
ついでにhref属性に削除プログラムを記述するファイル名「delete.php」を指定しておきます。(スマホ版も同様)
遷移できたことがわかるようにdelete.phpに以下を記述しておきます。
<?php
echo "削除プログラムのページに遷移しています";
キャンセルしたときは遷移が発生せず、OKを押すとdelete.phpに移動しました。
それでは削除プログラムをdelete.phpに記述していきます。
削除ファイルに遷移し削除実行
現在削除ボタンのhref属性には、./delete.php のみが記述してあります。
削除をする際、どのレコードを削除するかの情報が必要となるため、パラメータをつけてあげます。
<!--PC表示用-->
<a href="./delete.php?id=<?php echo h($id); ?>"> <!--href属性以外は省略しています-->
<i class="fa-regular fa-trash-can"></i>
</a>
<!--スマホ表示用-->
<a href="./delete.php?id=<?php echo h($id); ?>"> <!--href属性以外は省略しています-->
削 除
</a>
パラメータを付けた状態で遷移すると、URLに削除するデータ番号を乗せて遷移することができます。
ここで一度削除ボタンのプログラム部分を載せておきます。
<!--PC用-->
<a class='c-button c-button--bg-red delete' id="delete<?php echo h($id); ?>" href='./delete.php?id=<?php echo h($id);?>' onclick="deleteConfirm('<?php echo h($title); ?>', 'delete<?php echo h($id); ?>');">
<i class="fa-regular fa-trash-can"></i>
</a>
<!--スマホ用-->
<a class="c-button c-button--bg-red delete" id="delete<?php echo h($id); ?>sp" href='./delete.php?id=<?php echo h($id);?>' onclick="deleteConfirm('<?php echo h($title); ?>', 'delete<?php echo h($id); ?>sp');">
削 除
</a>
それでは削除プログラムを記述していきます。
<?php
require_once("./dbconnect.php");
include_once("./functions.php");
if (isset($_GET['id'])) :
//パラメータの値を変数に格納
$id = $_GET['id'];
//SQLの発行
$sql = 'DELETE FROM records WHERE id = ?';
$stmt = $db->prepare($sql);
$stmt->bind_param('i', $id);
sql_check($stmt, $db);
//ホーム画面にパラメータ付きで戻す
header('Location: ./index.php?dataOperation=delete');
exit();
//不正な遷移が行われたときの処理
else :
//ホーム画面にパラメータ付きで戻す
header('Location: ./index.php?dataOperation=error');
exit();
endif;
まずDB接続ファイルとfunctions.phpを読み込んだ後、if文でパラメータがあるかないかを分岐します。
パラメータが存在した場合は、パラメータを変数に格納→SQL(DELETE文)を発行&実行→ホーム画面にパラメータ付きで戻すという順番で処理を行います。
パラメータが存在しなかったり、正しくない遷移の場合は強制的にホーム画面へパラメータ付きで戻すよう処理しています。
メッセージボックスの処理
画面で動くか試す前に、ホーム画面にパラメータ付きで戻ったときの処理を記述します。
完成目標は以下の画像のとおりです。
まずはindex.phpのmainタグ下のコメントアウト要素を解除し、line-blueクラスとc-button–bg-blueクラスを削除します。(パラメータによって赤と青を切り替えるため)
<!--以下のコメントアウトを解除-->
<section class="p-section p-section__full-screen" id="doneOperateBox">
<div class="p-message-box"> <!--line-blueクラスを削除-->
<p id="doneText">更新しました</p>
<button class="c-button" onclick="">OK</button> <!--c-button--bg-blueクラスを削除-->
</div>
</section>
次に、この要素をdataOperationプロパティがあり、その値がdeleteかerrorの時だけ表示するようif文を追記します。
<!--以下1行追記-->
<?php if ($_GET['dataOperation'] && ($_GET['dataOperation'] === 'delete' || $_GET['dataOperation'] === 'error')) : ?>
<section class="p-section p-section__full-screen" id="doneOperateBox">
<div class="p-message-box">
<p id="doneText">更新しました</p>
<button class="c-button" onclick="">OK</button>
</div>
</section>
<!--以下1行追記-->
<?php endif; ?>
条件文が少し複雑ですが、dataOperation=deleteやdataOperation=errorのときだけ要素が表示されます。
↓条件がfalseのとき
それではパラメータの値に応じて該当のクラス名やテキストを出力する処理を記述します。
<!--書き換え前-->
<div class="p-message-box line-blue">
<p id="doneText">操作が完了しました</p>
<button class="c-button c-button--bg-blue" onclick="">OK</button>
</div>
<!--書き換え後-->
<div class="p-message-box <?php echo ($_GET['dataOperation'] === 'error') ? 'line-red' : 'line-blue'; ?>">
<p id="doneText"><?php echo ($_GET['dataOperation'] === 'error') ? '正しく処理されませんでした' : '操作が完了しました'; ?></p>
<button class="c-button <?php echo ($_GET['dataOperation'] === 'error') ? 'c-button--bg-darkred' : 'c-button--bg-blue'; ?>" onclick="">OK</button>
</div>
全て三項演算子で判断して出力しています。
これで削除プログラムは完成ですが、現在のままだとモーダルが出ている間後ろがスクロールできるので、モーダルが表示されているときはスクロールできないような処理を「functions.js」に実装します。
if (doneOperateBox !== null) {
body.classList.add('openedModal');
} else {
body.classList.remove('openedModal');
}
まずはJavaScriptでモーダル要素が表示されているかで条件分岐を行い、モーダルが表示されているとき(!=null)はbodyタグにopenedModalクラスを付与し、表示されていないときはそのクラスを削除する処理を記述します。
CSSはすでに設定済なので、モーダルが表示されているときはスクロールできなくなります。
最後にOKボタンを押したらindex.php(パラメータなし)に戻るようにJavaScriptの関数を作成します。
const onClickOkButton = () => {
const url = new URL(window.location.href); //現在のURLを取得
url.searchParams.delete('dateOperation'); //パラメータdeleteOperationを削除
history.pushState('', '', url.pathname); //URLパラメータを削除したURL(index.php)に変更
location.reload(); //画面をリロード
}
関数が作成できたら、OKボタンのonclick属性に関数を登録します。
<button onclick="onClickOkButton();">OK</button> <!--onclick属性以外は省略しています-->
それでは実際に削除してみましょう。
OKを押すと削除が実行され完了メッセージボックスが表示されました。そしてOKを押すとメッセージボックスが消えます。
最後に
今回は収支データを画面から削除できる処理を追加しました。
家計簿データのような重要性がそこまで高くないデータをDBから削除するときは、DELETE文で削除してもリスクは少ないですが、個人情報など重要データはDELETE文で削除するのではなく、削除したかどうかのフラグを立てて操作するという方法もあります。
次回は収支データの編集が画面上でできる機能を実装していきます。
最後までお読みいただきありがとうございました。
コメント
素人ながら見よう見まねでこのサイトのプログラミングを書き勉強させていただいているものです。質問なのですが、上から2つ目のindex.phpのどこに書けばいいのでしょうか?
初歩的な質問で失礼します。
コメント頂きありがとうございます。
onclick属性にdeleteConfirmを追記する部分と認識しております。
index.php内で
i class="fa-regular fa-trash-can
を検索いただくと2件ヒットすると思いますので、その記述1行上のaタグのonclick属性にdeleteConfirm('');
を追記していただければ、削除イベントが発生すると思います。もし別のコード部分でしたら、お手数ですが再度コメントお願いいたします。