個人情報管理です。各項目は、仮の項目でご自由にカスタマイズ可能です。詳細は、仕様の変更・削除・機能追加・修正・デザイン変更・目的変更等も制限がありません。コードを公開しますので、参考になればご自由に使用してください。

仕様 |
1.ID(10桁指定) 氏名 職業(選択方式) 郵便番号(基本フォーマット) 電話番号(12桁) 住所(最大100文字) 備考(最大100文字) |
2.全ての入力完了後に登録ボタン可 |
3.データの個別削除 |
4.全データの削除 |
5.IDの降順ソート |
6.職業種別の検索機能 |
7.データ管理 サーバー(CSV) |
ご使用について |
本プログラムは、動作確認を行っておりますが、ソースの参考やコピー&ペースト等による完成後の不具合が有りましても、管理者は責任の回避ができるものとします。 また、デザインやソースコードをすべて使用した場合は、どこか片隅に小さくMOMOPLANと書いて頂ければ嬉しく思います。 |
ファイルの構成(参考) |
jyunbanmati/date/date.csv ├── index.html ├── main.js ├── public_data.php ├── style.css |
MAIN.JSへジャンプ public_data.phpへジャンプ styles.cssへジャンプ CSVへジャンプ |
HTML(index.html) |
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>データ管理フォーム</title>
</head>
<body>
<center><font color="#5511c2"><h1>データ管理フォーム</h1></font></center>
<form id="dataForm">
<label>ID (10桁): <input type="text" id="id" maxlength="10" placeholder="例: 10桁を入力" required></label>
<label>氏名 (16文字以内): <input type="text" id="name" maxlength="16" required></label>
<label>職業:
<select id="job">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
<option value="F">F</option>
</select>
</label>
<label>郵便番号 (000-0000): <input type="text" id="zip" pattern="^[0-9]{3}-[0-9]{4}$" placeholder="例: (000-0000)" required></label>
<label>電話番号 (12桁以内): <input type="text" id="phone" maxlength="12" required></label>
<label>住所 (最大100文字): <input type="text" id="address" maxlength="100"></label>
<label>備考 (最大100文字): <input type="text" id="note" maxlength="100"></label>
<button type="submit">登録</button>
</form>
<table id="dataTable">
<thead>
<tr>
<th>ID</th>
<th>氏名</th>
<th>職業</th>
<th>郵便番号</th>
<th>電話番号</th>
<th>住所</th>
<th>備考</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
<button id="clearAll">全削除</button>
<button id="sortDesc">降順ソート</button>
<button id="search">検索</button>
<button id="resetView" style="display: none;">戻る</button>
<script src="main.js"></script>
</body>
</html>
JS(main.js) |
document.addEventListener('DOMContentLoaded', function() {
const registerBtn = document.querySelector('button[type="submit"]');
const inputFields = Array.from(document.querySelectorAll('#dataForm input, #dataForm select, #dataForm textarea'));
// **初期状態で登録ボタンを無効化**
registerBtn.disabled = true;
// **入力欄の変更を監視し、全て入力されたらボタンを有効化**
inputFields.forEach(field => {
field.addEventListener('input', validateForm);
field.addEventListener('blur', validateForm); // フォーカスが外れたらチェック
});
function validateForm() {
const allFilled = inputFields.every(field => field.value.trim() !== '');
registerBtn.disabled = !allFilled;
}
});
// 初期データ読み込み(CSVから取得してテーブルに表示)
window.addEventListener('load', function() {
fetch('public_data.php')
.then(response => response.json())
.then(data => {
const tableBody = document.querySelector('#dataTable tbody');
tableBody.innerHTML = ''; // 既存データをクリア
data.data.forEach(row => {
const newRow = `<tr>
<td>${row[0]}</td>
<td>${row[1]}</td>
<td>${row[2]}</td>
<td>${row[3]}</td>
<td>${row[4]}</td>
<td>${row[5]}</td>
<td>${row[6]}</td>
<td><button class="deleteBtn">削除</button></td>
</tr>`;
tableBody.insertAdjacentHTML('beforeend', newRow);
});
})
.catch(error => console.error("データ取得エラー:", error));
});
// フォーム送信(登録)
document.getElementById('dataForm').addEventListener('submit', function(event) {
event.preventDefault();
const id = document.getElementById('id').value.trim();
const name = document.getElementById('name').value.trim();
const job = document.getElementById('job').value;
const zip = document.getElementById('zip').value.trim();
const phone = document.getElementById('phone').value.trim();
const address = document.getElementById('address').value.trim();
const note = document.getElementById('note').value.trim();
const row = `<tr>
<td>${id}</td>
<td>${name}</td>
<td>${job}</td>
<td>${zip}</td>
<td>${phone}</td>
<td>${address}</td>
<td>${note}</td>
<td><button class="deleteBtn">削除</button></td>
</tr>`;
document.querySelector('#dataTable tbody').insertAdjacentHTML('beforeend', row);
document.getElementById('dataForm').reset();
saveData();
});
// 各レコードの削除
document.addEventListener('click', function(event) {
if (event.target.classList.contains('deleteBtn')) {
const row = event.target.closest('tr'); // 削除対象の行を明確に取得
if (row) {
row.remove(); // 行を削除
saveData(); // CSVに変更を反映
} else {
console.error("削除対象の行が見つかりません");
}
}
});
// **全削除(テーブル&CSV連動)**
document.getElementById('clearAll').addEventListener('click', function() {
document.querySelector('#dataTable tbody').innerHTML = ''; // テーブルをクリア
// **CSVのデータも完全クリア**
fetch('public_data.php', {
method: 'POST',
body: JSON.stringify({clear: true}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => console.log(data.message))
.catch(error => console.error("全削除エラー:", error));
});
// CSVファイルへデータ保存
function saveData() {
const tableData = [];
document.querySelectorAll('#dataTable tbody tr').forEach(row => {
const rowData = Array.from(row.children).slice(0, 7).map(td => td.textContent.trim());
tableData.push(rowData.join(','));
});
fetch('public_data.php', {
method: 'POST',
body: JSON.stringify({data: tableData}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => console.log(data.message))
.catch(error => console.error("データ保存エラー:", error));
}
document.getElementById('sortDesc').addEventListener('click', function() {
console.log("ソートボタンがクリックされました"); // デバッグログ
const tableBody = document.querySelector('#dataTable tbody');
const rows = Array.from(tableBody.querySelectorAll('tr'));
console.log("取得した行:", rows); // デバッグログ
// **IDを数値として扱うために修正**
rows.sort((a, b) => {
const idA = parseInt(a.cells[0].textContent.trim(), 10); // 数値へ変換
const idB = parseInt(b.cells[0].textContent.trim(), 10);
console.log(`比較: ${idA} vs ${idB}`); // 比較のログ
return idB - idA; // 数値比較
});
console.log("ソート後のデータ:", rows); // ソート結果のログ
// **ソートした行をテーブルに反映**
tableBody.innerHTML = ''; // クリア
rows.forEach(row => tableBody.appendChild(row));
});
document.getElementById('search').addEventListener('click', function() {
const searchTerm = prompt("検索する職業を入力してください(例: A, B, C, D, E, F):");
console.log("検索ワード:", searchTerm); // デバッグログ
if (!searchTerm) return; // キャンセルされた場合は何もしない
const tableBody = document.querySelector('#dataTable tbody');
const rows = Array.from(tableBody.querySelectorAll('tr'));
// **検索前にすべての行を表示**
rows.forEach(row => row.style.display = "");
rows.forEach(row => {
const job = row.cells[2]?.textContent.trim(); // 職業欄(3列目)
console.log(`比較: ${searchTerm} vs ${job}`); // デバッグログ
if (job !== searchTerm) {
row.style.display = "none"; // 検索対象外を非表示
}
});
// **「戻るボタン」を有効にする**
document.getElementById('resetView').style.display = "block";
});
// **戻るボタンでデータを元に戻す**
document.getElementById('resetView').addEventListener('click', function() {
const rows = Array.from(document.querySelectorAll('#dataTable tbody tr'));
rows.forEach(row => row.style.display = ""); // すべての行を再表示
// **戻るボタンを非表示に戻す**
document.getElementById('resetView').style.display = "none";
});
PHP(public_data.php) |
<?php
$file = 'date/date.csv';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
if (isset($data['clear']) && $data['clear'] === true) {
// **CSVファイルの内容を完全削除**
$fp = fopen($file, 'w'); // 空のファイルを作成(上書き)
fclose($fp);
echo json_encode(["message" => "CSVクリア完了"]);
} else if (!empty($data['data'])) {
// **CSVデータの更新**
$fp = fopen($file, 'w');
foreach ($data['data'] as $row) {
fputcsv($fp, explode(',', $row));
}
fclose($fp);
echo json_encode(["message" => "データ保存完了"]);
} else {
echo json_encode(["message" => "エラー: データが空です"]);
}
} else {
// **CSVデータの読み込み**
$csvData = [];
if (file_exists($file) && ($fp = fopen($file, 'r')) !== false) {
while (($row = fgetcsv($fp)) !== false) {
$csvData[] = $row;
}
fclose($fp);
}
echo json_encode(["data" => $csvData]);
}
?>
CSS(styles.css) |
body {
font-family: Arial, sans-serif;
background-image: url("s-brick008.gif");
}
/* テーブル全体のスタイル */
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
/* ヘッダー部分(タイトル行)のスタイル */
thead {
background-color: #78ff95; /* 視認性の高い青色 */
color: rgb(24, 23, 23);
font-weight: bold;
}
/* ヘッダーの各セルのスタイル */
th {
padding: 10px;
border: 2px solid #8abbf0;
text-align: center;
}
/* データセル(本文)のスタイル */
td {
padding: 8px;
border: 1px solid #ddd;
text-align: center;
}
/* 奇数行・偶数行の色を交互に変更して視認性UP */
tbody tr:nth-child(odd) {
background-color: #f9f9f9;
}
tbody tr:nth-child(even) {
background-color: #e9ecef;
}
/* 削除ボタン(赤) */
.deleteBtn {
background-color: #dc3545;
color: white;
border: none;
padding: 8px 12px;
cursor: pointer;
font-weight: bold;
border-radius: 6px; /* 角を丸める */
}
.deleteBtn:hover {
background-color: #c82333;
}
/* 登録ボタン(青) */
button[type="submit"] {
background-color: #007BFF;
color: white;
border: none;
padding: 6px 10px;
cursor: pointer;
font-weight: bold;
border-radius: 6px; /* 角を丸める */
}
button[type="submit"]:hover {
background-color: #0056b3;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
CSV |
0123456987,dddddd,D,123-1237,77777777,東京都大田区,ssssss
0123456987,dddddd,C,123-1234,0312456981,wwwwwww,rrrrrrrrrrr
0123456987,ああああ,D,123-1237,0312456981,東京都大田区,ssssss
以上です、失礼します。