前回からは、一通り開発した家計簿システムを使ってもらい頂いたレビューの修正を行っています。
↓前回の記事はこちら
今回も同様にレビュー修正を行っていきます。
今回修正する点は以下の通りです。
・選択項目編集画面からホームへ戻ったときのセッション処理の追加
・収支データ出力箇所のページネーション機能の追加
選択項目編集画面からホームへ戻ったときのセッション処理の追加
現在、ホーム画面でデータを登録している途中で選択項目の編集へ遷移→ホーム画面へ戻るという行動を取ると、もともと入力していた値がリセットされてしまいます。
これを入力途中の値をセッションに保持し、選択項目編集画面から返ってきた際に復元される処理を追加します。
まずは編集ボタン押下で発生させるイベントを「functions.js」に作成します。
const onClickCatEdit = (buttonName) => {
//各カテゴリー、支払い方法、クレジットカードやスマホ決済の編集ボタン<a>を取得(id値は引数に指定)
const catEditButton = document.getElementById(buttonName);
//日付inputのvalueを取得
const date = document.getElementById('date').value;
//タイトルinputのvalueを取得
const title = document.getElementById('title').value;
//金額inputのvalueを取得
const amount = document.getElementById('amount').value;
//支出or収入のradioボタンの選択状態を取得
const type = typeChecked.value;
//支出カテゴリーselectのvalueを取得
const spendingCatValue = spendingCategory.value;
//支払い方法selectのvalueを取得
const paymentMethodValue = paymentMethod.value;
//押下された編集ボタン<a>のhref属性(遷移先)を取得
const oldHref = catEditButton.getAttribute('href');
//編集ボタンのhrefに追加するリンク(パラメータ)を変数に格納
const addHref = '&date=' + date + '&title=' + title + '&amount=' + amount + '&type=' + type + '&spendingCat=' + spendingCatValue + '&paymentMethod=' + paymentMethodValue;
//該当編集ボタンのhrefをパラメータ付きに書き換え
catEditButton.setAttribute('href', oldHref + addHref);
}
プログラムの大まかな流れは、各inputやselectの値を格納し、それらを含むパラメータ付きのURLを作りそれを該当編集ボタンのhrefとして書き換えるという内容です。
作成した関数を各編集ボタンにセットしていきます。
<!--支出カテゴリー編集ボタン 100行目付近-->
<a id="spendingcatEdit" class="c-button c-button--bg-gray" href="./item-edit.php?editItem=0" onclick="onClickCatEdit('spendingcatEdit');">編集</a>
<!--支払い方法編集ボタン 141行目付近-->
<a id="paymentmethodEdit" class="c-button c-button--bg-gray" href="./item-edit.php?editItem=2" onclick="onClickCatEdit('paymentmethodEdit');">編集</a>
<!--クレジットカード編集ボタン 160行目付近-->
<a id="creditEdit" class="c-button c-button--bg-gray" href="./item-edit.php?editItem=3" onclick="onClickCatEdit('creditEdit');">編集</a>
<!--スマホ決済編集ボタン 179行目付近-->
<a id="qrEdit" class="c-button c-button--bg-gray" href="./item-edit.php?editItem=4" onclick="onClickCatEdit('qrEdit');">編集</a>
関数を編集ボタンにセットできたら「item-edit.php」で渡ってきた入力途中の値をセッションに格納する処理を記述します。
//12行目付近に追加
if (isset($_GET['date']) && isset($_GET['title']) && isset($_GET['amount']) && isset($_GET['type']) && isset($_GET['spendingCat']) && isset($_GET['paymentMethod'])) {
$_SESSION['r_date'] = $_GET['date'];
$_SESSION['r_title'] = $_GET['title'];
$_SESSION['r_amount'] = $_GET['amount'];
$_SESSION['r_type'] = $_GET['type'];
$_SESSION['r_spendingCat'] = $_GET['spendingCat'];
$_SESSION['r_paymentMethod'] = $_GET['paymentMethod'];
}
上記を「$_GET[‘editItem’]」の処理を記述している下に追記します。
プログラムの内容は、各パラメータがセットされている場合に各値をセッションに保存しています。
遷移先にデータを渡しセッションに保存することができました。続いてセッションが保存された状態でホームに返された際の処理を記述していきます。
以下をindex.phpの共通ファイル読み込みの下に追記します。
if (isset($_SESSION['r_date']) && isset($_SESSION['r_title']) && isset($_SESSION['r_amount']) && isset($_SESSION['r_type']) &&isset($_SESSION['r_spendingCat']) && isset($_SESSION['r_paymentMethod'])) :
$r_date = $_SESSION['r_date'];
if ($_SESSION['r_title'] !== 'undefined') :
$r_title = $_SESSION['r_title'];
endif;
$r_amount = $_SESSION['r_amount'];
$r_type = $_SESSION['r_type'];
$r_spendingCat = $_SESSION['r_spendingCat'];
$r_paymentMethod = $_SESSION['r_paymentMethod'];
endif;
各セッションがセットされている場合にそれぞれのセッション値を変数に格納します。
最後に各inputに入力途中のデータを出力するようにvalue属性やchecked、selected出力部分を設定します。
(データがなければ何も出力されません)
<!--日付input-->
<input type="date" name="date" id="date" value="<?php echo (isset($r_date) ? $r_date : date("Y-m-d")); ?>" required>
<!--タイトルinput-->
<input id="title" type="text" name="title" id="title" maxlength="15" value="<?php echo $r_title; ?>" required>
<!--金額input-->
<input type="number" name="amount" id="amount" step="1" maxlength="7" pattern="^[0-9]+$" value="<?php echo $r_amount; ?>" required>
<!--支出radioボタン-->
<input id="spending" type="radio" name="type" value="0" onchange="onRadioChangeType(0);" <?php echo (isset($_SESSION['r_type']) && $r_type == 0) ? 'checked' : ''; ?> required>
<!--収入radioボタン-->
<input type="radio" name="type" id="income" value="1" onchange="onRadioChangeType(1);" <?php echo (isset($_SESSION['r_type']) && $r_type == 1) ? 'checked' : ''; ?>>
<!--支出カテゴリーoption-->
<option value="<?php echo h($id); ?>" <?php echo $r_spendingCat == $id ? 'selected' : ''; ?>><?php echo h($name); ?></option>
<!--支払い方法固定項目 141行目付近-->
<option value="<?php echo $i; ?>" id="<?php echo $fixedPaymentMethod_id[$i]; ?>" <?php echo $r_paymentMethod == $i+1 ? 'selected' : ''; ?>><?php echo $fixedPaymentMethod[$i]; ?></option>
<!--支払い方法ユーザー登録項目 150行目付近-->
<option value="<?php echo h($id); ?>" <?php echo $r_paymentMethod == $id ? 'selected' : ''; ?>><?php echo h($name); ?></option>
支出や収入が選択されている状態のときには、それ以下の選択項目が表示されるようにするため、以前作成した「record-edit.js」を読み込む記述をbody閉じタグの前の、scriptファイルを読み込ませている部分に追加します。
<script src="./js/functions.js"></script>
<!--↓以下追加-->
<script src="./js/record-edit.js"></script>
以上でデータ入力中に選択項目編集画面へ遷移→ホーム画面へ返ってくるという行動をとっても、入力中のデータが復元されます。
しかし登録ボタンを押下しても残り続けるので、登録ボタンで登録されたらセッションを削除する処理を最後に記述して完了です。
以下を「record-create.php」の末尾、登録処理完了後に返すページを指定する処理の登録の「登録ボタンが押下されたとき」の条件処理内に追記します。
if (isset($_POST['record_create']) && $_POST['record_create'] === '登録') :
header('Location: ./index.php');
//以下1行を追加 53行目付近
unset($_SESSION['r_date'], $_SESSION['r_title'], $_SESSION['r_amount'], $_SESSION['r_type'], $_SESSION['r_spendingcat'], $_SESSION['r_paymentMethod']);
elseif (isset($_POST['record_update']) && $_POST['record_update'] === '更新') :
header('Location: ./index.php?dataOperation=update');
endif;
以上で選択項目編集画面からホームへ戻ったときのセッション処理の追加実装は完了です。
追加で登録ボタンの下に入力データをリセットするボタンを実装します。
以下を登録ボタンの下(formタグの外)に追記します。
<input class="c-button c-button--bg-blue" type="submit" name="record_create" value="登録">
</form>
<!--以下追加 201行目付近-->
<form action="" method="POST">
<input type="submit" class="c-button c-button--bg-gray reset" name="record_reset" value="リセット">
</form>
それではこのボタンが押下されたときの処理をファイル冒頭に追記します。
//リセットボタンイベント
if (isset($_POST['record_reset'])) :
unset($_SESSION['r_date'], $_SESSION['r_title'], $_SESSION['r_amount'], $_SESSION['r_type'], $_SESSION['r_spendingcat'], $_SESSION['r_paymentMethod']);
header('location: ./index.php');
endif;
リセットボタンを押下すると「record_reset」がセットされた状態でPOST送信が行われるので、それを条件に置き処理を記述します。
ここではunsetで入力データを保存しているセッションを削除しリロードするという処理です。
セッションがないときはただ画面のリロードが行われて入力中のデータがリセットされます。
収支データ出力箇所のページネーション機能の追加
続いて収支データ表にページネーション機能を追加します。今回は10件ずつデータを表示するページネーションを実装します。
ページネーションを実装するに当たり以下のサイトを参考にさせていただきました。
これから記述、修正するプログラムはindex.phpのデータを出力するSQLなどの処理部分に記述していきます。
まず「$sql_dataoutput = ・・・」の前に1ページに表示する件数を格納する変数を定義します。
//276行目付近
$max_view = 10;
表示する件数を変更したい場合はここの数字を増減させるだけで変更できるようにしました。
そして今回は現在のページをパラメータで管理するのですが、何ページ目なのかによってSQLに入れる値を変えたいので、その変数の処理を上記「$max_view = 10;」の下に記述します。
if (!isset($_GET['page_id'])) :
$page_id = 1;
$page_param = $page_id - 1;
else :
$page_id = $_GET['page_id'];
$page_param = ($page_id - 1) * $max_view;
endif;
条件は「page_id」というパラメータがセットされているかいないかです。
このあとページネーションリンクに、現在のページを示すpage_idパラメータ付きのリンクを設定します。
まずパラメータがセットされていない時は$page_idに「1」を、$page_paramに「$page_id – 1」つまり0を入れます。
そしてパラメータがセットされているときは、$page_idにパラメータの値を、$page_paramに「($page_id – 1)* $max_view」を入れます。もし$page_idが2(2ページ目)の場合には「10」が入ります。
この$page_paramというのはこのあとSQLにセットする値です。それではSQLを少し修正します。
すでに記述しているSQL文の末尾に以下を追加します。
$sql_dataoutput = ' ・・・省略・・・
・・・省略・・・
・・・省略・・・ LIMIT ?, ?';
「?」を増やしたのでbind_paramも変更します。
$stmt_dataoutput->bind_param('ssiii', $searchDateFrom, $searchDateTo, $user_id, $page_param, $max_view);
まずSQLの末尾に追加した「LIMIT ?, ?」は「LIMIT 読み飛ばすデータ数, 表示するデータ数」という意味です。
1ページ目の場合には「LIMIT 0, 10」でデータを読み飛ばさず最新から順に10件を表示します。
2ページ目の場合は「LIMIT 10, 10」でデータを10行読み飛ばし、11件目から10件表示します。
以上を実装し全データ表示すると最新のデータから10件分のみ表示されました。
続いてページネーションを実装します。ページネーションは非表示テーブルの下に作成します。
まずページネーションを実装する上で、何ページ必要なのかを取得する必要があります。
そこで収支データ表に出力している条件と同じ条件のデータ数を求めるSQLを実行します。
<!--500行目付近-->
<div class="p-pagenation">
<?php
$sql = 'SELECT count(*) FROM records WHERE records.date >=? AND records.date <=? AND records.user_id = ?';
$stmt = $db->prepare($sql);
$stmt->bind_param('ssi', $searchDateFrom, $searchDateTo, $user_id);
sql_check($stmt, $db);
$stmt->bind_result($record_count);
$stmt->fetch();
$stmt->close();
$pages = ceil($record_count / $max_view);
?>
$sqlのFROM以下は収支データ表出力のSQLと同じです。COUNT(*)で条件に一致するデータ数を取得します。
その後はいつもどおり、値の設定や実行、結果の取得を行っています。そして最後の$pagesに必要なページ数を格納しています。
$pagesの計算式は取得したデータ数を1ページに表示する件数(10件)で割り、小数点以下は切り上げています。
例えばデータ数が16件だった場合、「16 / 10」で1.6となり切り上げて「2」(必要なページ数)が入ります。
ページ数が取得できたらfor文でページネーションを出力していきます。
<?php for ($i = 1; $i <= $pages; $i++) : ?>
<?php if ($i == $page_id) : ?>
<span><?php echo $i; ?></span>
<?php else : ?>
<a href="./index.php?page_id=<?php echo $i; ?>#data-table"><?php echo $i; ?></a>
<?php endif; ?>
<?php endfor; ?>
</div>
今回は現在のページはspanで出力し、それ以外の番号はaタグで出力します。
まずfor文は初期値「$i」に1を入れ、$iが$pagesより小さい間繰り返し、その都度$iに1を足します。
そのfor文内の処理はif文で条件分岐しています。
最初の条件は$iと$page_idが一致するときです。これは現在のページを出力する条件です。そのためspanタグでページネーションを出力しています。
それ以外の場合はaタグでページネーションを出力します。
spanタグのときは現在のページを出力するのみですが、aタグで他のページのリンクを出力する場合は、ホーム画面のルートにパラメータとアンカーリンク付きのhref属性を指定します。
アンカーリンクをつけるのはページ移動をするたびページ上部に戻ってしまうのを防ぐためです。
ページネーションリンクにアンカーリンクをつけたので、範囲検索や収支テーブルを囲っているdiv要素にidを追記します。
<!--213行目付近-->
<section class="p-section p-section__records-output" id="data-table">
以上でPCのページネーション機能は完成です。
続いてスマホのページネーション機能を追加していきます。
まずはbind_paramを修正します。
//539行目付近
$stmt_dataoutput->bind_param('ssiii', $searchDateFrom, $searchDateTo, $user_id, $page_param, $max_view);
続いてページネーションリンクを実装します。スマホ版ではPCと異なり「前へ」「次へ」という出力にします。
以下をデータがなかったときの要素出力の下に追記します。
<?php if ($count === 0) : ?>
<div class="p-sp-data-box nodata">
<p>データがありません</p>
</div>
<?php endif; ?>
<!-- ここから追加 -->
<div class="p-pagenation">
<?php if ($page_id > 1) : ?>
<a class="prev" href="./_index.php?page_id=<?php echo ($page_id - 1); ?>#data-table">前へ</a>
<?php endif; ?>
<?php if ($page_id < $pages) : ?>
<a class="next" href="./_index.php?page_id=<?php echo ($page_id + 1); ?>#data-table">次へ</a>
<?php endif; ?>
</div>
PC版でSQLを実行しているのでスマホ版でもう一度SQLを実行したりページ数を計算する必要はありません。
「前へ」と「次へ」のリンクを条件が一致する場合のみ出力するようにしています。
まず「前へ」のリンクは$page_idが「1」でないときに出力するため$page_id > 1という条件式になります。
続いて「次へ」のリンクは$page_id(現在何ページ目か)が$pages(必要なページ数)より小さいときに出力するため、$page_id > $pagesという条件式になります。
つまりページ数が1以外のときは常に「前へ」が出力され、現在のページ数と必要なページ数が同じ時以外(最終ページ以外)は常に「次へ」が出力されるということです。
そしてそれぞれのリンクにはアンカーリンクとpage_idパラメータの値に現在のページ数($page_id)に「1」を足したり引いた数がセットされています。
以上でページネーションの機能は完成です。
最後に
今回は選択項目編集画面からホームへ戻ったときのセッション処理の追加とページネーション機能を追加しました。
次回はカレンダーでいついくら使ったのか、いくら入ったのかが分かる機能を追加します。
最後までお読みいただきありがとうございました。
コメント