リクエスト詳細
🐛 バグ報告
対応完了
対象アプリ: ChangePoint - 設計変更・仕様変更履歴管理システム
CSV出力ボタンが検索フォームのsubmitと競合しフィルタが無視される
## 1. 不具合の内容
list.php の検索フォームに「CSV出力」ボタンが `<button type="submit" name="export" value="csv">` として配置されている。しかしこのフォームの `method="get"` では、`<button type="submit" name="export" value="csv">` をクリックしたとき、ブラウザは **フォーム内の全 input/select の値と共に `export=csv` をクエリストリングに付加して GET リクエストを送る**。
問題は `status` タブリンクによるフィルタにある。タブは `<a href="index.php?page=list&status=審査中">` のようなリンクで遷移するため、URL に `status=審査中` が含まれる状態でページが表示される。しかしこのとき検索フォームの `<select name="status">` の selected 状態がタブと連動して `$status` 変数で初期化されている一方で、**フォームの hidden に `status` を持たないため、ユーザーがタブでフィルタを絞った後に CSV ボタンを押すと `select name="status"` の値(デフォルト空)が送信され、タブで選んだステータスフィルタが無視されて全件 CSV が出力される**。
さらに根本的な問題として、`export=csv` の判定が `isset($_GET['export'])` であるため、通常の「検索」ボタン(`type="submit"` で `name/value` なし)を押したときに URL に `export` キーが残っていると意図せず CSV ダウンロードが発火する可能性もある。
## 2. 根拠・発生しそうな条件
- `pages/list.php` の検索フォーム: `<form method="get">` 内に `<button type="submit" name="export" value="csv">` が存在
- タブリンク遷移後(URL: `?page=list&status=審査中`)にフォームを submit すると、`select name="status"` の初期値が `"審査中"` に正しく選択されていれば問題ないが、タブ遷移後にフォームを一切操作していない場合、select の表示上の選択と実際の送信値が一致しないケースがブラウザによって生じうる
- より確実に再現するのは: タブで「承認済」を選択 → フォームの status select を触らず CSV ボタンを押す → select の value が空で送信され全件出力される
- `list.php` 内で `$status = trim((string)($_GET['status'] ?? ''))` としており、フォーム送信時は select の値が優先されるため、タブの URL パラメータは上書きされる
## 3. 期待動作
CSV ボタンを押したとき、現在画面に表示されているフィルタ条件(ステータス・品番・変更区分・担当者・日付範囲)がすべて CSV 出力に反映されること。
## 4. 修正方針
CSV 出力ボタンを通常の `<button type="submit">` から切り離し、JavaScript で現在のフィルタ URL に `&export=csv` を付加して遷移する方式に変更する。
```html
<!-- 修正前 -->
<button type="submit" name="export" value="csv" class="btn-accent">CSV出力</button>
<!-- 修正後 -->
<button type="button" class="btn-accent" id="csvExportBtn">CSV出力</button>
<script>
document.getElementById('csvExportBtn').addEventListener('click', function() {
var form = this.closest('form');
var data = new FormData(form);
var params = new URLSearchParams();
data.forEach(function(v, k) { if(v !== '') params.set(k, v); });
params.set('export', 'csv');
window.location.href = 'index.php?' + params.toString();
});
</script>
```
これにより、フォームの現在の入力値を正確に拾って CSV 出力 URL を生成できる。既存の検索・フィルタ・タブ機能は一切変更不要。
list.php の検索フォームに「CSV出力」ボタンが `<button type="submit" name="export" value="csv">` として配置されている。しかしこのフォームの `method="get"` では、`<button type="submit" name="export" value="csv">` をクリックしたとき、ブラウザは **フォーム内の全 input/select の値と共に `export=csv` をクエリストリングに付加して GET リクエストを送る**。
問題は `status` タブリンクによるフィルタにある。タブは `<a href="index.php?page=list&status=審査中">` のようなリンクで遷移するため、URL に `status=審査中` が含まれる状態でページが表示される。しかしこのとき検索フォームの `<select name="status">` の selected 状態がタブと連動して `$status` 変数で初期化されている一方で、**フォームの hidden に `status` を持たないため、ユーザーがタブでフィルタを絞った後に CSV ボタンを押すと `select name="status"` の値(デフォルト空)が送信され、タブで選んだステータスフィルタが無視されて全件 CSV が出力される**。
さらに根本的な問題として、`export=csv` の判定が `isset($_GET['export'])` であるため、通常の「検索」ボタン(`type="submit"` で `name/value` なし)を押したときに URL に `export` キーが残っていると意図せず CSV ダウンロードが発火する可能性もある。
## 2. 根拠・発生しそうな条件
- `pages/list.php` の検索フォーム: `<form method="get">` 内に `<button type="submit" name="export" value="csv">` が存在
- タブリンク遷移後(URL: `?page=list&status=審査中`)にフォームを submit すると、`select name="status"` の初期値が `"審査中"` に正しく選択されていれば問題ないが、タブ遷移後にフォームを一切操作していない場合、select の表示上の選択と実際の送信値が一致しないケースがブラウザによって生じうる
- より確実に再現するのは: タブで「承認済」を選択 → フォームの status select を触らず CSV ボタンを押す → select の value が空で送信され全件出力される
- `list.php` 内で `$status = trim((string)($_GET['status'] ?? ''))` としており、フォーム送信時は select の値が優先されるため、タブの URL パラメータは上書きされる
## 3. 期待動作
CSV ボタンを押したとき、現在画面に表示されているフィルタ条件(ステータス・品番・変更区分・担当者・日付範囲)がすべて CSV 出力に反映されること。
## 4. 修正方針
CSV 出力ボタンを通常の `<button type="submit">` から切り離し、JavaScript で現在のフィルタ URL に `&export=csv` を付加して遷移する方式に変更する。
```html
<!-- 修正前 -->
<button type="submit" name="export" value="csv" class="btn-accent">CSV出力</button>
<!-- 修正後 -->
<button type="button" class="btn-accent" id="csvExportBtn">CSV出力</button>
<script>
document.getElementById('csvExportBtn').addEventListener('click', function() {
var form = this.closest('form');
var data = new FormData(form);
var params = new URLSearchParams();
data.forEach(function(v, k) { if(v !== '') params.set(k, v); });
params.set('export', 'csv');
window.location.href = 'index.php?' + params.toString();
});
</script>
```
これにより、フォームの現在の入力値を正確に拾って CSV 出力 URL を生成できる。既存の検索・フィルタ・タブ機能は一切変更不要。
💬 返信 (3)
🛠 開発を開始しました (バグ修正 (changepoint))
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
ご要望ありがとうございます。AI 開発ワーカーが実装を開始します。
通常 5〜30 分で Pull Request を作成し、レビュー後にリリースされます。
📝 開発が完了しました
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
ご要望いただいた内容の実装が完了し、最終チェック段階に入りました。
レビュー (自動) → リリース、の流れで進みます。
もう少々お待ちください。
✅ リリース完了のお知らせ
ご要望いただいた「ChangePoint - 設計変更・仕様変更履歴管理システム」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=changepoint
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/changepoint/
ご利用ありがとうございます!
ご要望いただいた「ChangePoint - 設計変更・仕様変更履歴管理システム」を実装し、リリースいたしました。
【ご利用方法】
ダッシュボード: https://www.aiapps.jp/?action=dashboard
アプリ詳細: https://www.aiapps.jp/apps/show.php?slug=changepoint
デモ環境は 1 時間以内に自動構築されます:
https://www.aiapps.jp/demo/changepoint/
ご利用ありがとうございます!
Echo
Iris