了解、「家族メンバー編集フォーム構築モード」起動。
familyMemberForm.js を新規作成し、家族(familyMembers)の登録・編集フォームとして以下を構築します。
| 機能 | 内容 |
|---|---|
| ✏️ 新規登録 / 編集 | モーダルで名前・続柄・世代など編集 |
| 📌 必須項目 | name, relationship, generation, memberType |
| 🔗 埋め込み | kaimyou(戒名)フォームとの連携も後で可能 |
| 🔁 更新後 | 保存後に onSave() コールバックでリスト再取得可能に |
public/
└── javascripts/
└── admin/
└── members/
├── familyMemberForm.js ✅ ← 今回追加
familyMemberForm.js// public/javascripts/admin/members/familyMemberForm.js
export function openFamilyMemberForm({ memberId, family = null, onSave }) {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.innerHTML = `
<div class="modal-content">
<h5>${family ? "家族の編集" : "家族を追加"}</h5>
<div class="row">
<div class="input-field col s12">
<input type="text" id="family-name" value="${family?.name || ""}">
<label for="family-name">氏名</label>
</div>
<div class="input-field col s12">
<input type="text" id="family-kana" value="${family?.kana || ""}">
<label for="family-kana">カナ</label>
</div>
<div class="input-field col s12">
<input type="text" id="family-relationship" value="${family?.relationship || ""}">
<label for="family-relationship">続柄</label>
</div>
<div class="input-field col s12">
<input type="text" id="family-generation" value="${family?.generation || ""}">
<label for="family-generation">世代</label>
</div>
<div class="input-field col s12">
<select id="member-type">
<option value="" disabled ${!family ? "selected" : ""}>選択してください</option>
${[
"家族",
"養子",
"分家先から実家を見る人",
"嫁ぎ先から実家を見る人",
"後見人",
"連絡先",
"その他",
]
.map(
(type) =>
`<option value="${type}" ${
family?.memberType === type ? "selected" : ""
}>${type}</option>`
)
.join("")}
</select>
<label for="member-type">種別</label>
</div>
<div class="input-field col s12">
<textarea id="family-memo" class="materialize-textarea">${family?.memo || ""}</textarea>
<label for="family-memo">備考</label>
</div>
</div>
</div>
<div class="modal-footer">
<button class="modal-close btn-flat">キャンセル</button>
<button id="save-family-btn" class="btn green">保存</button>
</div>
`;
document.body.appendChild(modal);
const instance = M.Modal.init(modal, { onCloseEnd: () => modal.remove() });
instance.open();
M.FormSelect.init(modal.querySelectorAll("select"));
document.getElementById("save-family-btn").addEventListener("click", async () => {
const payload = {
name: document.getElementById("family-name").value.trim(),
kana: document.getElementById("family-kana").value.trim(),
relationship: document.getElementById("family-relationship").value.trim(),
generation: document.getElementById("family-generation").value.trim(),
memberType: document.getElementById("member-type").value,
memo: document.getElementById("family-memo").value.trim(),
};
const url = family
? `/admin/members/${memberId}/family/${family._id}`
: `/admin/members/${memberId}/family`;
try {
const response = await fetch(url, {
method: family ? "PUT" : "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
const result = await response.json();
if (!response.ok || !result.success) {
throw new Error(result.message || "保存失敗");
}
M.toast({ html: "保存しました", classes: "green" });
instance.close();
onSave();
} catch (err) {
console.error("保存エラー:", err);
M.toast({ html: `エラー: ${err.message}`, classes: "red" });
}
});
}
import { openFamilyMemberForm } from "./familyMemberForm.js";
// ボタン例
const addButton = document.createElement("button");
addButton.classList.add("btn", "blue", "right");
addButton.innerHTML = `<i class="material-icons left">person_add</i>家族追加`;
addButton.addEventListener("click", () => {
openFamilyMemberForm({
memberId: member._id, // 該当する家 (member)
onSave: () => {
// 保存後のリロード処理(例:再フェッチなど)
renderMembersCollapsible(repoName, members, onBack);
},
});
});
| METHOD | URL | 内容 |
|---|---|---|
POST |
/admin/members/:id/family |
新規追加 |
PUT |
/admin/members/:id/family/:fid |
既存家族更新 |
kaimyouForm.js(戒名の詳細編集UIをモーダル化)addressForm.js(家族または家に住所を持たせたい場合)tagSelect.js(タグをフォームで動的に選択・補完)どこから続けますか?
Click here to try a new GPT!