[ADD]:旧システムのjspファイルを追加。htmlに起こした後、不要になったら削除予定

This commit is contained in:
h-seya
2026-09-18 09:23:07 +09:00
parent 436dbb4665
commit 29bea44e14
5 changed files with 3868 additions and 0 deletions

View File

@@ -0,0 +1,857 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>寄贈申請内容確認</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Yu Gothic", "Meiryo", sans-serif;
}
body {
background: #f5f7fa;
color: #333;
}
/* =========================
ヘッダー
========================= */
.header {
height: 60px;
background: #fff;
border-bottom: 1px solid #e5e7eb;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
}
.logo {
font-size: 20px;
font-weight: bold;
color: #1b3768;
}
.header-right {
display: flex;
align-items: center;
gap: 16px;
}
.notification {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
font-size: 18px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.2s;
}
.notification:hover {
background: #f0f4fa;
}
.notification-badge {
position: absolute;
top: 3px;
right: 3px;
width: 7px;
height: 7px;
background: #dc2626;
border-radius: 50%;
border: 1px solid #fff;
}
.account {
padding: 8px 10px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s, color 0.2s;
}
.account:hover {
background: #f0f4fa;
color: #1659d4;
}
.logout-btn {
padding: 8px 15px;
background: #fff;
border: 1px solid #d1d5db;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s,
border-color 0.2s,
color 0.2s;
}
.logout-btn:hover {
background: #f0f4fa;
border-color: #1659d4;
color: #1659d4;
}
/* =========================
レイアウト
========================= */
.wrapper {
display: flex;
min-height: calc(100vh - 60px);
}
/* =========================
サイドメニュー
========================= */
.sidebar {
width: 220px;
background: #002b66;
color: #fff;
}
.sidebar-title {
padding: 18px;
font-size: 13px;
border-bottom: 1px solid rgba(255,255,255,.1);
}
.menu {
list-style: none;
}
.menu li {
padding: 16px 20px;
cursor: pointer;
transition: background-color 0.2s;
}
.menu li:hover {
background: #0d477f;
}
.menu li.active {
background: #1158d8;
border-radius: 4px;
margin: 8px;
}
/* =========================
メイン
========================= */
.main {
flex: 1;
padding: 24px;
}
.breadcrumb {
font-size: 12px;
color: #64748b;
margin-bottom: 15px;
}
.page-title {
font-size: 38px;
color: #173a70;
margin-bottom: 10px;
}
.description {
font-size: 14px;
margin-bottom: 4px;
}
.required-note {
color: #d9534f;
font-size: 12px;
margin-bottom: 18px;
}
/* =========================
カード
========================= */
.card {
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 4px;
}
.card-body {
padding: 25px;
}
.section-title {
font-weight: bold;
margin-bottom: 15px;
color: #1f3a64;
}
/* =========================
フォーム
========================= */
.form-grid {
display: flex;
flex-direction: column;
gap: 18px;
}
.form-group {
display: flex;
align-items: flex-start;
}
.form-group label {
width: 140px;
flex-shrink: 0;
font-size: 13px;
font-weight: bold;
padding-top: 10px;
}
.input-area {
flex: 1;
max-width: 700px;
}
.required {
color: #d9534f;
font-size: 11px;
}
.optional {
color: #555;
font-size: 11px;
}
input[type="text"],
input[type="date"],
select,
textarea {
width: 100%;
border: 1px solid #d6dbe3;
border-radius: 4px;
padding: 10px;
font-size: 13px;
background: #fff;
}
input[type="text"]:focus,
input[type="date"]:focus,
select:focus,
textarea:focus {
outline: none;
border-color: #1659d4;
box-shadow: 0 0 0 2px rgba(22, 89, 212, 0.1);
}
input[readonly] {
background: #f3f4f6;
}
textarea {
resize: none;
height: 90px;
}
.help {
font-size: 11px;
color: #6b7280;
margin-top: 4px;
}
.counter {
text-align: right;
font-size: 11px;
color: #888;
margin-top: 3px;
}
/* =========================
必須・任意項目の区切り
========================= */
.optional-section {
margin-top: 25px;
padding-top: 22px;
border-top: 1px solid #e5e7eb;
}
.optional-section-title {
font-weight: bold;
color: #1f3a64;
margin-bottom: 15px;
}
/* =========================
ボタン
========================= */
.button-area {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
.btn {
min-width: 120px;
padding: 10px 20px;
border-radius: 4px;
border: 1px solid #d1d5db;
background: #fff;
cursor: pointer;
font-weight: bold;
transition: background-color 0.2s,
border-color 0.2s,
color 0.2s;
}
.btn:hover {
background: #f0f4fa;
border-color: #1659d4;
color: #1659d4;
}
.btn-primary {
background: #1158d8;
border: none;
color: #fff;
}
.btn-primary:hover {
background: #0d47b5;
color: #fff;
}
.right-btns {
display: flex;
gap: 12px;
}
/* =========================
フッター
========================= */
.footer {
text-align: center;
margin-top: 25px;
font-size: 12px;
color: #666;
}
/* =========================
レスポンシブ
========================= */
@media (max-width: 700px) {
.header {
padding: 0 12px;
}
.logo {
font-size: 16px;
}
.account {
display: none;
}
.sidebar {
width: 180px;
}
.main {
padding: 18px;
}
.page-title {
font-size: 30px;
}
.form-group {
flex-direction: column;
}
.form-group label {
width: 100%;
padding-top: 0;
margin-bottom: 6px;
}
.input-area {
width: 100%;
max-width: none;
}
.button-area {
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.right-btns {
justify-content: flex-end;
}
}
@media (max-width: 480px) {
.sidebar {
display: none;
}
.main {
padding: 15px;
}
.page-title {
font-size: 25px;
}
.card-body {
padding: 18px;
}
.right-btns {
flex-direction: column;
}
.btn {
width: 100%;
}
}
</style>
</head>
<body>
<header class="header">
<div class="logo">
📖 ShareBooks
</div>
<div class="header-right">
<!-- サインイン中アカウント -->
<span class="account">
山田 太郎 さん(一般ユーザ)
</span>
<!-- ログアウト -->
<button type="button" class="logout-btn">
ログアウト
</button>
</div>
</header>
<div class="wrapper">
<!-- =========================
サイドメニュー
========================= -->
<aside class="sidebar">
<div class="sidebar-title">
一般メニュー
</div>
<ul class="menu">
<li>
🏠 トップメニュー
</li>
<li class="active">
新規図書申請
</li>
</ul>
</aside>
<!-- =========================
メイン
========================= -->
<main class="main">
<div class="breadcrumb">
トップメニュー > 新規図書申請>申請内容確認
</div>
<h1 class="page-title">
寄贈申請内容確認
</h1>
<div class="description">
入力した内容に間違いがないかご確認ください。よろしければ「申請する」ボタンを押してください。
</div>
<div class="required-note">
(※)は必須項目です。
</div>
<form action="BookDonationConfirmServlet" method="post">
<div class="card">
<div class="card-body">
<!-- =========================
申請者情報
========================= -->
<div class="section-title">
申請者情報(ログイン中のアカウント情報)
</div>
<div class="form-grid">
<div class="form-group">
<label>
社員ID
</label>
<div class="input-area">
<input
type="text"
value="123456"
readonly>
</div>
</div>
<div class="form-group">
<label>
部署
</label>
<div class="input-area">
<input
type="text"
value="システム開発部"
readonly>
</div>
</div>
<div class="form-group">
<label>
氏名
</label>
<div class="input-area">
<input
type="text"
value="山田 太郎"
readonly>
</div>
</div>
</div>
<br>
<hr style="border:1px solid #edf0f2;">
<br>
<!-- =========================
必須項目
========================= -->
<div class="section-title">
本の情報(必須項目)
</div>
<div class="form-grid">
<!-- タイトル -->
<div class="form-group">
<label>
<span class="required">(※)</span>
タイトル
</label>
<div class="input-area">
<input
type="text"
name="title"
placeholder="タイトルを入力してください">
</div>
</div>
<!-- 著者名 -->
<div class="form-group">
<label>
<span class="required">(※)</span>
著者名
</label>
<div class="input-area">
<input
type="text"
name="author"
placeholder="著者名を入力してください">
</div>
</div>
<!-- 本の状態 -->
<div class="form-group">
<label>
<span class="required">(※)</span>
本の状態
</label>
<div class="input-area">
<select name="bookCondition">
<option value="">
選択してください
</option>
<option value="0">
0:不明
</option>
<option value="1">
1:新品同様・ほぼ未使用
</option>
<option value="2">
2:良好・目立つ傷や汚れ無し
</option>
<option value="3">
3:使用感あり・多少の折れ、擦れあり
</option>
<option value="4">
4:傷みあり・目立つ傷、汚れ、書き込みあり
</option>
</select>
</div>
</div>
</div>
<!-- =========================
任意項目
========================= -->
<div class="optional-section">
<div class="optional-section-title">
本の情報(任意項目)
</div>
<div class="form-grid">
<!-- 出版社 -->
<div class="form-group">
<label>
出版社
<span class="optional">(任意)</span>
</label>
<div class="input-area">
<input
type="text"
name="publisher"
placeholder="出版社を入力してください">
</div>
</div>
<!-- ISBN -->
<div class="form-group">
<label>
ISBN
<span class="optional">(任意)</span>
</label>
<div class="input-area">
<input
type="text"
name="isbn"
placeholder="ISBNがある場合は入力してください">
</div>
<div class="help">
</div>
</div>
<!-- 出版日 -->
<div class="form-group">
<label>
出版日
<span class="optional">(任意)</span>
</label>
<div class="input-area">
<input
type="date"
name="publishDate">
<div class="help">
※出版日が分かる場合に入力してください。
</div>
</div>
</div>
<!-- 備考 -->
<div class="form-group">
<label>
備考
<span class="optional">(任意)</span>
</label>
<div class="input-area">
<textarea
name="remarks"
placeholder="付属品の有無(CD/DVD等)や、本の概要が分かるAmazon等のURLなどをご記入ください"></textarea>
<div class="counter">
0 / 300
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- =========================
ボタン
========================= -->
<div class="button-area">
<button
type="button"
class="btn">
トップメニューへ戻る
</button>
<div class="right-btns">
<button
type="reset"
class="btn">
修正
</button>
<button
type="submit"
class="btn btn-primary">
確定
</button>
</div>
</div>
</form>
<div class="footer">
© 2026 社内備品・図書管理システム
</div>
</main>
</div>
</body>
</html>

View File

@@ -0,0 +1,762 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>登録内容確認</title>
<style>
*{
margin:0;
padding:0;
box-sizing:border-box;
font-family:"Yu Gothic","Meiryo",sans-serif;
}
body{
background:#f5f7fa;
color:#333;
}
/* ヘッダー */
.header{
height:60px;
background:#fff;
border-bottom:1px solid #e5e7eb;
display:flex;
justify-content:space-between;
align-items:center;
padding:0 20px;
}
.logo{
font-size:18px;
font-weight:bold;
color:#173a70;
}
.header-right{
display:flex;
align-items:center;
gap:20px;
}
.logout-btn{
padding:8px 16px;
border:1px solid #d0d7de;
background:#fff;
border-radius:4px;
cursor:pointer;
}
/* レイアウト */
.wrapper{
display:flex;
min-height:calc(100vh - 60px);
}
/* サイドバー */
.sidebar{
width:220px;
background:#002b66;
color:#fff;
}
.sidebar-title{
padding:18px;
border-bottom:1px solid rgba(255,255,255,.1);
font-size:13px;
}
.menu{
list-style:none;
}
.menu li{
padding:16px 20px;
cursor: pointer;
transition:
background-color 0.2s ease;
}
.menu li:hover {
background: #0c438f;
}
.menu li.active{
background: #1659d4;
}
/* メイン */
.main{
flex:1;
padding:24px;
}
.breadcrumb{
font-size:12px;
color:#6b7280;
margin-bottom:18px;
}
.page-title{
font-size:42px;
font-weight:bold;
color:#173a70;
margin-bottom:10px;
}
.description{
font-size:14px;
margin-bottom:20px;
}
/* カード */
.card{
background:#fff;
border:1px solid #e5e7eb;
border-radius:4px;
}
.card-header{
padding:14px 18px;
border-bottom:1px solid #e5e7eb;
font-weight:bold;
}
.content{
padding:20px;
}
/* 確認テーブル */
.confirm-table{
width:100%;
border-collapse:collapse;
}
.confirm-table th,
.confirm-table td{
padding:16px 12px;
border-bottom:1px solid #edf0f2;
text-align:left;
font-size:14px;
}
.confirm-table th{
width:15%;
color:#1f3a64;
font-weight:bold;
}
.confirm-table td{
width:35%;
}
.help-text{
display:block;
margin-top:5px;
font-size:11px;
color:#777;
}
/* 確認事項 */
.notice-box{
margin-top:18px;
background:#fff9ea;
border-top:1px solid #efdfaa;
padding:18px;
}
.notice-title{
font-weight:bold;
margin-bottom:10px;
color:#173a70;
}
.notice-box ul{
margin-left:18px;
}
.notice-box li{
margin-bottom:8px;
font-size:13px;
}
/* ボタン */
.button-area{
margin-top:18px;
display:flex;
justify-content:space-between;
align-items:center;
}
.btn{
min-width:120px;
padding:10px 20px;
border-radius:4px;
border:1px solid #d0d7de;
background:#fff;
cursor:pointer;
font-weight:bold;
}
.btn-primary{
background:#1158d8;
color:#fff;
border:none;
}
.right-buttons{
display:flex;
gap:12px;
}
.footer{
text-align:center;
color:#666;
font-size:12px;
margin-top:28px;
}
/* 登録完了ポップアップ */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.45);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.modal {
width: 460px;
background: #fff;
border-radius: 6px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
padding: 30px;
text-align: center;
}
.modal-message {
font-size: 18px;
font-weight: bold;
color: #173a70;
margin-bottom: 30px;
}
.modal-buttons {
display: flex;
justify-content: center;
gap: 15px;
}
.modal-buttons form {
margin: 0;
}
.modal-btn {
min-width: 150px;
padding: 11px 20px;
border: 1px solid #d0d7de;
border-radius: 4px;
background: #fff;
color: #333;
font-weight: bold;
cursor: pointer;
}
.modal-btn:hover {
background: #f1f5fa;
border-color: #1659d4;
color: #1659d4;
}
.modal-btn-primary {
background: #1158d8;
border-color: #1158d8;
color: #fff;
}
.modal-btn-primary:hover {
background: #0d47b5;
border-color: #0d47b5;
color: #fff;
}
</style>
</head>
<body>
<header class="header">
<div class="logo">
📖 ShareBooks
</div>
<div class="header-right">
<span>
山田 太郎 さん(管理者)
</span>
<form method="post"
action="${pageContext.request.contextPath}/logout"
style="display:inline;">
<button
type="submit"
class="logout-btn"
onclick="return confirmLogout()">
ログアウト
</button>
</form>
</div>
</header>
<div class="wrapper">
<!-- =========================
Sidebar
========================= -->
<aside class="sidebar">
<div class="sidebar-title">
管理者画面
</div>
<ul class="menu">
<li onclick="goTopMenu()">
🏠 トップメニュー
</li>
<li class="active">
➕ 新規図書登録
</li>
<li onclick="goBook()">
📚 社内図書一覧
</li>
</ul>
</aside>
<!-- =========================
Main
========================= -->
<main class="main">
<div class="breadcrumb">
トップメニュー > 新規図書登録 > 図書登録内容確認
</div>
<h1 class="page-title">
図書登録内容確認
</h1>
<div class="description">
入力した内容に間違いがないかご確認ください。
よろしければ「登録する」ボタンを押してください。
</div>
<!-- =========================
登録処理用Form
========================= -->
<form method="post"
action="${pageContext.request.contextPath}/insertBook">
<div class="card">
<div class="card-header">
図書情報
</div>
<div class="content">
<table class="confirm-table">
<!-- =========================
図書管理ID
========================= -->
<tr>
<th>図書管理ID</th>
<td>
${book.bookManageId}
<span class="help-text">
※自動採番されます(例:BK0001、BK0002、...)
</span>
<input
type="hidden"
name="bookManageId"
value="${book.bookManageId}">
</td>
</tr>
<!-- =========================
登録日
========================= -->
<tr>
<th>登録日</th>
<td>
${registeredAt}
<span class="help-text">
※自動取得されます
</span>
<input
type="hidden"
name="registeredAt"
value="${registeredAt}">
</td>
</tr>
<!-- =========================
タイトル
========================= -->
<tr>
<th>タイトル</th>
<td>
${book.title}
<input
type="hidden"
name="title"
value="${book.title}">
</td>
</tr>
<!-- =========================
著者名
========================= -->
<tr>
<th>著者名</th>
<td>
${book.author}
<input
type="hidden"
name="author"
value="${book.author}">
</td>
</tr>
<!-- =========================
カテゴリ
========================= -->
<tr>
<th>カテゴリ</th>
<td>
${book.categoryName}
<input
type="hidden"
name="categoryId"
value="${book.categoryId}">
</td>
</tr>
<!-- =========================
サブカテゴリ
========================= -->
<tr>
<th>サブカテゴリ</th>
<td>
${book.subcategoryName}
<input
type="hidden"
name="bookSubcategoryId"
value="${book.bookSubcategoryId}">
</td>
</tr>
<!-- =========================
ISBN
========================= -->
<tr>
<th>ISBN</th>
<td>
${book.isbn}
<input
type="hidden"
name="isbn"
value="${book.isbn}">
</td>
</tr>
<!-- =========================
出版社
========================= -->
<tr>
<th>出版社</th>
<td>
${book.publisher}
<input
type="hidden"
name="publisher"
value="${book.publisher}">
</td>
</tr>
<!-- =========================
出版日
========================= -->
<tr>
<th>出版日</th>
<td>
${book.publicationDate}
<input
type="hidden"
name="publishDate"
value="${book.publicationDate}">
</td>
</tr>
<!-- =========================
保管場所
========================= -->
<tr>
<th>保管場所</th>
<td>
${book.locationName}
<input
type="hidden"
name="locationId"
value="${book.locationId}">
</td>
</tr>
<!-- =========================
寄贈者
========================= -->
<tr>
<th>寄贈者(任意)</th>
<td>
${book.donorId}
<input
type="hidden"
name="donorId"
value="${book.donorId}">
</td>
</tr>
<!-- =========================
備考
========================= -->
<tr>
<th>備考(任意)</th>
<td>
${book.description}
<input
type="hidden"
name="description"
value="${book.description}">
</td>
</tr>
</table>
<!-- =========================
確認事項
========================= -->
<div class="notice-box">
<div class="notice-title">
確認事項
</div>
<ul>
<li>
登録後、図書一覧に表示されます。
</li>
<li>
登録内容は、図書の管理や検索に利用されますので、
正確に登録してください。
</li>
<li>
登録後に内容を変更する場合は、
図書情報編集画面から行ってください。
</li>
</ul>
</div>
</div>
</div>
<!-- =========================
Buttons
========================= -->
<div class="button-area">
<button
type="button"
class="btn"
onclick="history.back();">
入力画面へ戻る
</button>
<div class="right-buttons">
<button
type="reset"
class="btn">
クリア
</button>
<button
type="submit"
name="action"
value="register"
class="btn btn-primary">
登録する
</button>
</div>
</div>
</form>
<div class="footer">
© 2026 社内備品・図書管理システム
</div>
</main>
</div>
<% if (request.getAttribute("registerSuccess") != null) { %>
<div id="registerModal" class="modal-overlay">
<div class="modal">
<div class="modal-message">
新規図書の登録が完了しました!
</div>
<div class="modal-buttons">
<!-- 続けて追加 -->
<form method="get"
action="${pageContext.request.contextPath}/insertBook">
<button type="submit" class="modal-btn">
続けて追加
</button>
</form>
<!-- 図書一覧へ戻る -->
<form method="get"
action="${pageContext.request.contextPath}/BookServlet">
<button type="submit"
class="modal-btn modal-btn-primary">
図書一覧へ戻る
</button>
</form>
</div>
</div>
</div>
<% } %>
<script>
function confirmLogout(){
const result = window.confirm("本当にログアウトしてよろしいですか?");
return result;
}
function goTopMenu() {
location.href = "${pageContext.request.contextPath}/topmenu.jsp";
}
function goBook() {
location.href = "${pageContext.request.contextPath}/book.jsp";
}
</script>
</body>
</html>

View File

@@ -0,0 +1,729 @@
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="bookequ_manage_system.entity.Account"%>
<%@ page import="bookequ_manage_system.entity.Book"%>
<%@ page import="java.util.List"%>
<%-- EmployeeクラスまたはAccountクラスのパッケージを指定 --%>
<%@ page import="bookequ_manage_system.entity.Account"%>
<%
// サーブレットから渡された社員リストを取得
List<Account> employeeList = (List<Account>) request.getAttribute("employeeList");
%>
<%
/*
* LoginServletで保存されたAccountをセッションから取得する。
* JSPには暗黙的に session が用意されているため、
* HttpSession session = ... のような宣言はしない。
*/
if (session.getAttribute("account") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
return;
}
Account account = (Account) session.getAttribute("account");
/*
* Account.java の adminFlag を利用する。
* 1 = 管理者
* 0 = 一般ユーザ
*/
boolean isAdmin = account.getAdminFlag() == 1;
int employeeId = account.getEmployeeId();
String roleName = isAdmin ? "管理者" : "一般ユーザ";
/*
* LoginServletでセッションに保存した社員名を取得する。
* topmenu.jsp / book.jsp と同じ employeeName を使用する。
* 社員名がセッションにない場合は社員IDを表示する。
*/
Object employeeNameObject = session.getAttribute("employeeName");
String employeeName;
if (employeeNameObject != null && !employeeNameObject.toString().trim().isEmpty()) {
employeeName = employeeNameObject.toString();
} else {
employeeName = "社員ID:" + employeeId;
}
/*
* BookLendServletから request.setAttribute("book", book) で渡された
* 貸出対象の図書情報を受け取る。
*/
Book book = (Book) request.getAttribute("book");
String bookManageId = "";
String title = "";
String author = "";
String isbn = "";
if (book != null) {
bookManageId = book.getBookManageId() != null ? book.getBookManageId() : "";
title = book.getTitle() != null ? book.getTitle() : "";
author = book.getAuthor() != null ? book.getAuthor() : "";
isbn = (book.getIsbn() != null && !book.getIsbn().trim().isEmpty()) ? book.getIsbn() : "-";
}
%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>図書貸出処理</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Yu Gothic", "Meiryo", sans-serif;
color: #18243a;
font-size: 14px;
background: #fff;
}
a {
text-decoration: none;
color: inherit;
}
button, input, select {
font-family: inherit;
}
/* ===== ヘッダー:topmenu.jsp / book.jsp と統一 ===== */
.header {
height: 56px;
border-bottom: 1px solid #d8e0e8;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 18px;
background: #fff;
}
.header-title {
font-size: 21px;
font-weight: 700;
display: flex;
align-items: center;
gap: 8px;
}
.book-icon {
font-size: 24px;
}
.header-right {
display: flex;
align-items: center;
gap: 16px;
}
.bell {
font-size: 21px;
position: relative;
}
.badge {
position: absolute;
top: -5px;
right: -6px;
background: #e33;
color: #fff;
border-radius: 9px;
min-width: 12px;
height: 12px;
line-height: 12px;
text-align: center;
font-size: 9px;
}
.user {
font-size: 13px;
font-weight: 600;
}
.logout {
height: 32px;
padding: 0 12px;
border: 1px solid #a8b3c0;
border-radius: 5px;
background: #fff;
font-size: 13px;
font-weight: bold;
cursor: pointer;
}
.logout:hover {
background: #f2f5f8;
}
/* ===== レイアウト ===== */
.layout {
display: flex;
min-height: calc(100vh - 56px);
}
/* ===== サイドバー:book.jsp と統一 ===== */
.sidebar {
width: 180px;
flex: 0 0 180px;
background: #082957;
color: #fff;
padding: 10px 7px;
}
.side-label {
font-size: 12px;
font-weight: bold;
margin: 3px 7px 10px;
}
.side-menu {
min-height: 42px;
display: flex;
align-items: center;
gap: 7px;
padding: 0 7px;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
margin-bottom: 4px;
}
.side-menu:hover {
background: #104c91;
}
.side-menu.active {
background: #1267d9;
}
.side-icon {
font-size: 15px;
width: 18px;
text-align: center;
}
/* ===== メイン ===== */
.content {
flex: 1;
min-width: 0;
padding: 16px 20px 30px;
overflow-x: auto;
}
.breadcrumb {
font-size: 12px;
color: #657184;
margin-bottom: 8px;
}
.breadcrumb span {
margin: 0 7px;
}
.title {
font-size: 26px;
margin: 0 0 4px;
color: #143a70;
}
.description {
font-size: 13px;
font-weight: bold;
color: #4d596b;
margin: 0 0 16px;
}
/* ===== カード ===== */
.card {
background: #fff;
border: 1px solid #e0e5eb;
border-radius: 4px;
margin-bottom: 14px;
box-shadow: 0 1px 4px rgba(30, 52, 77, 0.06);
}
.card-header {
padding: 10px 13px;
font-size: 14px;
font-weight: bold;
border-bottom: 1px solid #e0e5eb;
background: #fafbfd;
}
.card-body {
padding: 12px;
}
/* ===== 図書情報 ===== */
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table th, .info-table td {
border: 1px solid #e0e5eb;
padding: 9px 12px;
text-align: left;
font-size: 13px;
}
.info-table th {
width: 160px;
background: #f5f7fa;
font-weight: bold;
}
/* ===== 入力欄 ===== */
.form-row {
margin-bottom: 13px;
display: flex;
align-items: center;
}
.form-row label {
width: 110px;
font-weight: bold;
font-size: 13px;
}
input[type="text"], input[type="date"], select {
width: 320px;
height: 38px;
padding: 8px 10px;
border: 1px solid #ced4da;
border-radius: 4px;
background: #fff;
font-size: 13px;
}
input[readonly] {
background: #f5f7fa;
}
input:focus, select:focus {
outline: none;
border-color: #1267d9;
box-shadow: 0 0 0 2px rgba(18, 103, 217, 0.10);
}
.loan-section {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
margin-top: 4px;
}
.loan-box {
min-width: 0;
}
.loan-box label {
display: block;
margin-bottom: 7px;
font-weight: bold;
font-size: 13px;
}
.loan-box input {
width: 100%;
}
.required {
color: #e5484d;
font-size: 11px;
}
.note {
font-size: 11px;
color: #666;
margin-top: 5px;
line-height: 1.5;
}
.error {
color: #e5484d;
margin-top: 4px;
font-size: 11px;
}
.warning-area {
background-color: #fff8e8;
padding: 12px 15px;
border-top: 1px solid #f0e1a1;
color: #555;
font-size: 12px;
line-height: 1.6;
}
.warning-area ul {
margin: 5px 0 0 20px;
padding: 0;
}
/* ===== ボタン ===== */
.button-area {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 18px;
}
.btn {
min-height: 36px;
padding: 7px 18px;
border-radius: 4px;
border: 1px solid #c8d0da;
cursor: pointer;
background: #fff;
font-size: 13px;
font-weight: bold;
}
.btn:hover {
background: #f3f6f9;
}
.btn-primary {
background: #1267d9;
color: #fff;
border: 1px solid #1267d9;
}
.btn-primary:hover {
background: #0d58bd;
}
.right-buttons {
display: flex;
gap: 10px;
}
/* ===== レスポンシブ ===== */
@media ( max-width : 900px) {
.header-right {
gap: 8px;
}
.user {
font-size: 12px;
}
.loan-section {
grid-template-columns: 1fr;
}
}
@media ( max-width : 650px) {
.sidebar {
width: 150px;
flex-basis: 150px;
}
.header-title {
font-size: 16px;
}
.bell, .user {
display: none;
}
.content {
padding: 12px;
}
.form-row {
align-items: flex-start;
flex-direction: column;
gap: 6px;
}
.form-row label {
width: auto;
}
input[type="text"], input[type="date"], select {
width: 100%;
}
}
</style>
</head>
<body>
<!-- ===== ヘッダー ===== -->
<header class="header">
<div class="header-title">
<span class="book-icon">📖</span> ShareBooks
</div>
<div class="header-right">
<!-- topmenu.jsp / book.jsp と同じセッションの社員名を表示 -->
<span class="user"><%=employeeName%>(<%=roleName%>)</span>
<!-- ログアウト確認後、/logout → セッション破棄 → login.jsp を想定 -->
<form action="${pageContext.request.contextPath}/logout"
method="post" onsubmit="return confirm('ログアウトしますか?');">
<button type="submit" class="logout">ログアウト</button>
</form>
</div>
</header>
<div class="layout">
<!-- ===== サイドバー ===== -->
<aside class="sidebar">
<div class="side-label">
<%=isAdmin ? "共通画面" : "一般メニュー"%>
</div>
<!-- トップメニュー → topmenu.jsp -->
<a class="side-menu"
href="${pageContext.request.contextPath}/topmenu.jsp"> <span
class="side-icon">⌂</span> トップメニュー
</a>
<%
if (isAdmin) {
%>
<!-- 管理者のみ新規図書登録を表示(book.jsp と同じ構成) -->
<a class="side-menu"
href="${pageContext.request.contextPath}/book/registration"> <span
class="side-icon">⊞</span> 新規図書登録
</a>
<%
}
%>
<!-- 社内図書一覧 → BookServlet -->
<a class="side-menu active"
href="${pageContext.request.contextPath}/BookServlet"> <span
class="side-icon">📖</span> 社内図書一覧
</a>
</aside>
<!-- ===== メイン ===== -->
<main class="content">
<div class="breadcrumb">
<a href="${pageContext.request.contextPath}/topmenu.jsp">トップメニュー</a>
<span>›</span> <a
href="${pageContext.request.contextPath}/BookServlet">社内図書一覧</a> <span>›</span>
図書貸出処理
</div>
<h1 class="title">図書貸出処理</h1>
<p class="description">以下の図書を貸出します。貸出先と貸出日・返却予定日を入力してください。</p>
<!-- ===== DB更新用の form エリア(ここから開始) ===== -->
<form id="loanForm"
action="${pageContext.request.contextPath}/book/loan" method="post">
<!-- サーブレットへ送信する隠し図書ID(数値IDおよび管理ID) -->
<input type="hidden" name="bookId"
value="<%=book != null ? book.getBookId() : ""%>"> <input
type="hidden" name="bookManageId" value="<%=bookManageId%>">
<!-- ===== 図書情報 ===== -->
<div class="card">
<div class="card-header">図書情報</div>
<div class="card-body">
<table class="info-table">
<tr>
<th>図書管理ID</th>
<td><%=bookManageId%></td>
</tr>
<tr>
<th>タイトル</th>
<td><%=title%></td>
</tr>
<tr>
<th>著者名</th>
<td><%=author%></td>
</tr>
<tr>
<th>ISBN</th>
<td><%=isbn%></td>
</tr>
</table>
</div>
</div>
<!-- ===== 社員情報 ===== -->
<div class="card">
<div class="card-header">社員情報</div>
<div class="card-body">
<div class="form-row">
<label for="employeeSelect">社員ID</label> <select
id="employeeSelect" name="employeeId"
onchange="updateEmployeeName()">
<option value="">社員IDを選択してください</option>
<%
if (employeeList != null) {
for (Account emp : employeeList) {
%>
<option value="<%=emp.getEmployeeId()%>"
data-name="<%=emp.getEmployeeName()%>">
<%=emp.getEmployeeId()%>
</option>
<%
}
}
%>
</select>
</div>
<div class="form-row">
<label for="employeeName">社員名</label> <input type="text"
id="employeeName" value="" placeholder="社員名が表示されます" readonly>
</div>
<hr
style="margin: 18px 0; border: 0; border-top: 1px solid #e5e9ef;">
<div class="loan-section">
<div class="loan-box">
<label> 貸出日 <span class="required">(自動取得)</span>
</label> <input type="date" id="loanDate" name="loanDate" value="">
<div class="note">※ 現在の日付が自動で設定されます。</div>
</div>
<div class="loan-box">
<label> 貸出期間日数 <span class="required">(任意)</span>
</label> <input type="text" id="loanDays" placeholder="日数を入力してください">
<div class="note">※ 数値(1以上)で入力してください。</div>
</div>
<div class="loan-box">
<label> 返却予定日 <span class="required">(必須)</span>
</label> <input type="date" id="returnDate" name="returnDate">
<div class="note">※ カレンダーから日付を選択してください。</div>
<div class="error">※ 現在の日付より前は選択できません。</div>
</div>
</div>
</div>
<div class="warning-area">
<strong>注意事項</strong>
<ul>
<li>貸出処理を行うと、対象の図書のステータスが「貸出中」に変更されます。</li>
<li>返却予定日を必ず指定してください。</li>
</ul>
</div>
</div>
<div class="button-area">
<a class="btn"
href="${pageContext.request.contextPath}/BookServlet">図書一覧へ戻る</a>
<div class="right-buttons">
<button type="button" class="btn" onclick="clearForm()">クリア</button>
<button type="button" class="btn btn-primary"
onclick="submitLoan()">貸出する</button>
</div>
</div>
</form>
<!-- ===== DB更新用の form エリア(ここまで) ===== -->
</main>
</div>
<script>
/* ===== 社員ID選択時に社員名を自動セット ===== */
function updateEmployeeName() {
const select = document.getElementById('employeeSelect');
const selectedOption = select.options[select.selectedIndex];
// selectされたoptionタグから data-name 属性の値(社員名)を取得
const name = selectedOption.getAttribute('data-name');
// 社員名欄に反映(未選択の場合は空文字)
document.getElementById('employeeName').value = name ? name : '';
}
/* ===== 貸出日を現在日に設定 ===== */
(function() {
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
const todayString = yyyy + '-' + mm + '-' + dd;
const loanDate = document.getElementById('loanDate');
const returnDate = document.getElementById('returnDate');
loanDate.value = todayString;
returnDate.min = todayString;
})();
/* ===== 貸出期間日数から返却予定日を計算 ===== */
document.getElementById('loanDays')
.addEventListener(
'input',
function() {
const days = parseInt(this.value, 10);
const loanDateValue = document
.getElementById('loanDate').value;
if (Number.isNaN(days) || days < 1
|| !loanDateValue) {
return;
}
const date = new Date(loanDateValue + 'T00:00:00');
date.setDate(date.getDate() + days);
const yyyy = date.getFullYear();
const mm = String(date.getMonth() + 1).padStart(2,
'0');
const dd = String(date.getDate()).padStart(2, '0');
document.getElementById('returnDate').value = yyyy
+ '-' + mm + '-' + dd;
});
/* ===== クリア ===== */
function clearForm() {
document.getElementById('employeeSelect').selectedIndex = 0;
document.getElementById('employeeName').value = '';
document.getElementById('loanDays').value = '';
document.getElementById('returnDate').value = '';
const today = new Date();
const yyyy = today.getFullYear();
const mm = String(today.getMonth() + 1).padStart(2, '0');
const dd = String(today.getDate()).padStart(2, '0');
document.getElementById('loanDate').value = yyyy + '-' + mm + '-'
+ dd;
}
/* ===== 貸出ボタン ===== */
function submitLoan() {
const employeeId = document.getElementById('employeeSelect').value;
const returnDate = document.getElementById('returnDate').value;
if (!employeeId) {
alert('社員IDを選択してください。');
return;
}
if (!returnDate) {
alert('返却予定日を入力してください。');
return;
}
if (confirm('この図書を貸出しますか?')) {
// OK選択時にフォーム送信を実行し、DB処理へ遷移
document.getElementById('loanForm').submit();
}
}
</script>
</body>
</html>

View File

@@ -0,0 +1,753 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="bookequ_manage_system.entity.Account"%>
<%@ page import="bookequ_manage_system.entity.Book"%>
<%@ page import="java.text.SimpleDateFormat"%>
<%
if (session.getAttribute("account") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
return;
}
Account account = (Account) session.getAttribute("account");
boolean isAdmin = account.getAdminFlag() == 1;
int employeeId = account.getEmployeeId();
String roleName = isAdmin ? "管理者" : "一般ユーザ";
// サーブレットから受け取ったBookオブジェクト
Book book = (Book) request.getAttribute("book");
if (book == null) {
book = new Book();
}
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy/MM/dd HH:mm");
%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>【図書】情報更新入力</title>
<style>
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
min-height: 100%;
font-family: "Noto Sans JP", "Yu Gothic", "YuGothic", "Meiryo", Arial,
sans-serif;
color: #333;
background: #fff;
font-size: 13px;
}
.page {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Header */
.header {
height: 58px;
border-bottom: 1px solid #d8e0e8;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 18px 0 20px;
background: #fff;
}
.header-title {
font-size: 20px;
font-weight: 700;
display: flex;
gap: 9px;
align-items: center;
}
.header-right {
display: flex;
align-items: center;
gap: 18px;
}
.user {
font-size: 13px;
font-weight: 600;
}
.bell {
font-size: 22px;
position: relative;
}
.badge {
position: absolute;
top: -3px;
right: -5px;
background: #e33;
color: #fff;
border-radius: 9px;
font-size: 8px;
min-width: 13px;
text-align: center;
}
.logout {
height: 34px;
padding: 0 14px;
border: 1px solid #a8b3c0;
border-radius: 5px;
background: #fff;
font-weight: bold;
cursor: pointer;
}
/* Main layout */
.main {
flex: 1;
display: flex;
min-height: calc(100vh - 56px);
}
/* Sidebar */
.sidebar {
width: 116px;
flex: 0 0 150px;
background: #002d5b;
color: #fff;
padding-top: 17px;
}
.side-title {
padding: 0 12px 10px;
font-size: 8px;
color: #d9e4f0;
}
.menu-item {
height: 40px;
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
color: #fff;
font-size: 10px;
font-weight: 600;
}
.menu-item.active {
background: #1264b4;
}
.menu-icon {
width: 16px;
text-align: center;
font-size: 14px;
}
/* Content */
.content {
flex: 1;
min-width: 0;
padding: 17px 14px 20px;
background: #fff;
}
.breadcrumb {
font-size: 8px;
color: #6f8094;
margin-bottom: 9px;
}
.breadcrumb span {
margin: 0 5px;
color: #9aa4ae;
}
.page-title {
margin: 0;
font-size: 18px;
font-weight: 700;
color: #333;
line-height: 1.4;
}
.description {
margin: 2px 0 13px;
font-size: 9px;
color: #777;
}
/* Form card */
.form-card {
border: 1px solid #e0e0e0;
border-radius: 3px;
padding: 13px 11px 15px;
box-shadow: 0 0 2px rgba(0, 0, 0, .02);
}
.section-title {
margin: 0 0 10px;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
font-size: 11px;
font-weight: 700;
color: #333;
}
.system-info-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
column-gap: 34px;
margin-bottom: 12px;
}
.input-fields {
display: flex;
flex-direction: column;
gap: 10px;
}
.optional-fields {
margin-top: 14px;
padding-top: 14px;
border-top: 1px solid #eee;
}
.field {
display: grid;
grid-template-columns: 76px minmax(0, 1fr);
align-items: center;
column-gap: 8px;
min-width: 0;
}
.label {
font-size: 9px;
font-weight: 600;
color: #333;
white-space: nowrap;
}
.required {
color: #e53935;
font-size: 8px;
margin-left: 2px;
font-weight: 500;
}
.optional {
color: #333;
font-size: 8px;
margin-left: 2px;
font-weight: 500;
}
.control {
width: 100%;
height: 28px;
padding: 0 9px;
border: 1px solid #ddd;
border-radius: 3px;
background: #fff;
color: #333;
font-size: 9px;
outline: none;
}
.control:focus {
border-color: #2d6fb7;
box-shadow: 0 0 0 2px rgba(45, 111, 183, .08);
}
.control[readonly] {
background: #f3f5f8;
color: #555;
}
select.control {
appearance: auto;
padding-right: 5px;
}
input[type="date"].control {
color: #555;
}
.with-note {
display: flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.with-note .control {
flex: 1;
min-width: 0;
}
.note {
flex: 0 0 auto;
color: #777;
font-size: 8px;
white-space: nowrap;
}
/* Memo */
.memo-section {
margin-top: 16px;
border: 1px solid #e0e0e0;
border-radius: 3px;
padding: 12px 11px 14px;
}
.memo-row {
display: grid;
grid-template-columns: 76px minmax(0, 1fr) 82px;
gap: 8px;
align-items: start;
}
textarea.control {
height: 60px;
resize: vertical;
padding: 8px 9px;
line-height: 1.5;
}
.memo-note {
color: #777;
font-size: 8px;
padding-top: 7px;
white-space: nowrap;
}
/* Bottom area */
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 12px;
}
.back-button {
min-width: 82px;
height: 30px;
border: 1px solid #bbb;
border-radius: 3px;
background: #fff;
color: #444;
font-size: 9px;
font-weight: 600;
}
.actions {
display: flex;
gap: 10px;
}
.clear-button, .confirm-button {
height: 30px;
min-width: 70px;
border-radius: 3px;
font-size: 9px;
font-weight: 600;
cursor: pointer;
}
.clear-button {
border: 1px solid #c7c7c7;
background: #fff;
color: #555;
}
.confirm-button {
min-width: 86px;
border: 1px solid #005bb5;
background: #0967c3;
color: #fff;
}
.confirm-button:hover {
background: #0759aa;
}
.clear-button:hover, .back-button:hover {
background: #f7f7f7;
}
.help {
margin-top: 7px;
font-size: 8px;
color: #3975ad;
}
.help::before {
content: "●";
font-size: 5px;
margin-right: 4px;
}
</style>
</head>
<body>
<div class="page">
<header class="header">
<div class="header-title">
<span class="book-icon">📖</span> ShareBooks
</div>
<div class="header-right">
<span class="user">
<%=session.getAttribute("employeeName")%>(<%=roleName%>)
</span>
<form action="${pageContext.request.contextPath}/logout"
method="post" onsubmit="return confirm('ログアウトしますか?');">
<button type="submit" class="logout">ログアウト</button>
</form>
</div>
</header>
<div class="main">
<aside class="sidebar">
<div class="side-title">管理者画面</div>
<div class="menu-item"
onclick="location.href='${pageContext.request.contextPath}/topmenu.jsp';"
style="cursor: pointer;">
<span class="menu-icon">🏠</span><span>トップメニュー</span>
</div>
<div class="menu-item active"
onclick="location.href='${pageContext.request.contextPath}/BookServlet';"
style="cursor: pointer;">
<span class="menu-icon">📖</span><span>社内図書一覧</span>
</div>
</aside>
<main class="content">
<div class="breadcrumb">
トップメニュー <span>›</span> 社内図書一覧 <span>›</span> 図書情報更新入力
</div>
<h1 class="page-title">図書情報更新入力</h1>
<p class="description">図書の情報を編集してください。変更しない項目はそのままにしてください。</p>
<form id="bookForm"
action="${pageContext.request.contextPath}/book/updateConfirm"
method="post">
<section class="form-card">
<h2 class="section-title">図書基本情報</h2>
<div class="system-info-row">
<div class="field">
<label class="label" for="bookManagementId">図書管理ID</label>
<div class="with-note">
<input id="bookManagementId" name="bookManagementId"
type="text" class="control"
value="<%=book.getBookManageId() != null ? book.getBookManageId() : ""%>"
readonly> <span class="note">※変更できません</span>
</div>
</div>
<div class="field">
<label class="label" for="registeredAt">登録日時</label>
<div class="with-note">
<input id="registeredAt" name="registeredAt" type="text"
class="control"
value="<%=book.getCreatedAt() != null ? sdfDateTime.format(book.getCreatedAt()) : ""%>"
readonly> <span class="note">※変更できません</span>
</div>
</div>
<div class="field">
<label class="label" for="updatedAt">更新日時</label>
<div class="with-note">
<input id="updatedAt" name="updatedAt" type="text"
class="control"
value="<%=book.getUpdatedAt() != null ? sdfDateTime.format(book.getUpdatedAt()) : ""%>"
readonly> <span class="note">※変更できません</span>
</div>
</div>
</div>
<div class="input-fields">
<div class="field">
<label class="label" for="isbn">ISBN<span
class="required">(必須)</span></label> <input id="isbn" name="isbn"
type="text" class="control"
value="<%=book.getIsbn() != null ? book.getIsbn() : ""%>"
required>
</div>
<div class="field">
<label class="label" for="title">タイトル<span
class="required">(必須)</span></label> <input id="title" name="title"
type="text" class="control"
value="<%=book.getTitle() != null ? book.getTitle() : ""%>"
required>
</div>
<div class="field">
<label class="label" for="author">著者名<span
class="required">(必須)</span></label> <input id="author" name="author"
type="text" class="control"
value="<%=book.getAuthor() != null ? book.getAuthor() : ""%>"
required>
</div>
<div class="field">
<label class="label" for="category">カテゴリ<span
class="required">(必須)</span></label>
<select id="category" name="category" class="control" onchange="updateSubCategories()" required>
<%
String cat = (book.getCategoryName() != null) ? book.getCategoryName() : "";
%>
<option value="1" <%="AI・データ分析".equals(cat) || "1".equals(cat) ? "selected" : ""%>>AI・データ分析</option>
<option value="2" <%="クラウド".equals(cat) || "2".equals(cat) ? "selected" : ""%>>クラウド</option>
<option value="3" <%="プログラミング".equals(cat) || "3".equals(cat) ? "selected" : ""%>>プログラミング</option>
<option value="4" <%="ネットワーク".equals(cat) || "4".equals(cat) ? "selected" : ""%>>ネットワーク</option>
<option value="5" <%="Web技術".equals(cat) || "5".equals(cat) ? "selected" : ""%>>Web技術</option>
<option value="6" <%="データベース".equals(cat) || "6".equals(cat) ? "selected" : ""%>>データベース</option>
<option value="7" <%="ITマネジメント".equals(cat) || "7".equals(cat) ? "selected" : ""%>>ITマネジメント</option>
<option value="8" <%="コンピュータ基礎".equals(cat) || "8".equals(cat) ? "selected" : ""%>>コンピュータ基礎</option>
<option value="9" <%="セキュリティ".equals(cat) || "9".equals(cat) ? "selected" : ""%>>セキュリティ</option>
<option value="10" <%="IT資格".equals(cat) || "10".equals(cat) ? "selected" : ""%>>IT資格</option>
</select>
</div>
<div class="field">
<label class="label" for="subCategory">サブカテゴリ<span
class="required">(必須)</span></label>
<select id="subCategory" name="subCategory" class="control" required>
<!-- JavaScriptで動的生成 -->
</select>
</div>
<div class="field">
<label class="label" for="location">保管場所<span
class="required">(必須)</span></label> <select id="location"
name="location" class="control" required>
<%
String loc = book.getLocationName() != null ? book.getLocationName() : "1";
%>
<option value="1" <%="1".equals(loc) || "未確定".equals(loc) ? "selected" : ""%>>未確定</option>
<option value="2" <%="2".equals(loc) || "開発エリア書棚".equals(loc) ? "selected" : ""%>>開発エリア書棚</option>
<option value="3" <%="3".equals(loc) || "会議室前ラック".equals(loc) ? "selected" : ""%>>会議室前ラック</option>
</select>
</div>
<div class="field">
<label class="label" for="statusText">貸出状態</label>
<div class="with-note">
<%
int st = book.getBookStatus();
String statusLabel = "貸出可";
if (st == 1) statusLabel = "貸出中";
else if (st == 2) statusLabel = "利用停止";
%>
<input id="statusText" type="text" class="control" value="<%=statusLabel%>" readonly>
<input id="status" type="hidden" name="status" value="<%=statusLabel%>">
<span class="note">※変更できません</span>
</div>
</div>
<div class="field">
<label class="label" for="bookCondition">本の状態<span
class="required">(必須)</span></label> <select id="bookCondition"
name="bookCondition" class="control" required>
<%
int cond = book.getCondition();
%>
<option value="1" <%=cond == 1 ? "selected" : ""%>>新品同様 : ほぼ未使用</option>
<option value="2" <%=cond == 2 ? "selected" : ""%>>良好 : 目立つ傷や汚れ無し</option>
<option value="3" <%=cond == 3 ? "selected" : ""%>>使用感あり : 多少の折れ、擦れあり</option>
<option value="4" <%=cond == 4 ? "selected" : ""%>>傷みあり : 目立つ傷、汚れ、書き込みあり</option>
</select>
</div>
</div>
<div class="input-fields optional-fields">
<div class="field">
<label class="label" for="publisher">出版社<span
class="optional">(任意)</span></label> <input id="publisher"
name="publisher" type="text" class="control"
value="<%=book.getPublisher() != null ? book.getPublisher() : ""%>">
</div>
<div class="field">
<label class="label" for="publishedDate">出版日<span
class="optional">(任意)</span></label> <input id="publishedDate"
name="publishedDate" type="date" class="control"
value="<%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%>">
</div>
<div class="field">
<label class="label" for="donor">寄贈者ID<span
class="optional">(任意)</span></label> <input id="donor" name="donor"
type="text" class="control"
value="<%=book.getDonorName() != null ? book.getDonorName() : ""%>">
</div>
<div class="field">
<label class="label" for="url">URL<span class="optional">(任意)</span></label>
<div class="with-note">
<input id="url" name="url" type="url" class="control" value="">
<span class="note">※任意の場合は空欄でも可</span>
</div>
</div>
</div>
</section>
<section class="memo-section">
<div class="memo-row">
<label class="label" for="memo">備考<span class="optional">(任意)</span></label>
<textarea id="memo" name="memo" class="control"><%=book.getDescription() != null ? book.getDescription() : ""%></textarea>
<span class="memo-note">※任意の場合は空欄でも可</span>
</div>
</section>
<div class="bottom">
<button type="button" class="back-button"
onclick="location.href='${pageContext.request.contextPath}/BookServlet';">図書一覧へ戻る</button>
<div class="actions">
<button type="reset" class="clear-button" onclick="setTimeout(updateSubCategories, 10);">クリア</button>
<button type="button" class="confirm-button"
onclick="confirmUpdate();">確認へ</button>
</div>
</div>
<div class="help">「確認へ」ボタンを押すと、入力内容の確認画面に進みます。</div>
</form>
</main>
</div>
</div>
<script>
// 画像1・2のDBテーブル構造に対応するマスタデータ
const subCategories = {
"1": [
{ id: 1, name: "人工知能・機械学習" },
{ id: 2, name: "統計・データ分析" },
{ id: 3, name: "自然言語処理・生成AI" }
],
"2": [
{ id: 4, name: "AWS・クラウド基盤" },
{ id: 5, name: "クラウドサービス" },
{ id: 6, name: "クラウドアーキテクチャ・運用" },
{ id: 7, name: "コンテナ・FinOps" }
],
"3": [
{ id: 8, name: "Java・C#・C言語" },
{ id: 9, name: "Web・スクリプト言語" },
{ id: 10, name: "モダン言語" },
{ id: 11, name: "アルゴリズム・設計" }
],
"4": [
{ id: 12, name: "TCP/IP・プロトコル" },
{ id: 13, name: "ネットワーク構築・運用" },
{ id: 14, name: "無線・DNS・HTTP" },
{ id: 15, name: "ネットワークセキュリティ・Linux" }
],
"5": [
{ id: 16, name: "Web基礎・HTML/CSS" },
{ id: 17, name: "JavaScript・Node.js・React" },
{ id: 18, name: "Webデザイン・アクセシビリティ" },
{ id: 19, name: "Web API・セキュリティ" }
],
"6": [
{ id: 20, name: "SQL基礎・リファレンス" },
{ id: 21, name: "データベース設計・モデリング" },
{ id: 22, name: "SQLチューニング・分析" },
{ id: 23, name: "DBスペシャリスト・実践" }
],
"7": [
{ id: 24, name: "プロジェクト・アジャイル管理" },
{ id: 25, name: "ITサービス・開発管理" },
{ id: 26, name: "品質・テスト・要件定義" }
],
"8": [
{ id: 27, name: "コンピュータ入門・アーキテクチャ" },
{ id: 28, name: "OS・Linux" },
{ id: 29, name: "プログラム・データ構造" },
{ id: 30, name: "情報理論・ネットワーク" },
{ id: 31, name: "論理回路・システム" }
],
"9": [
{ id: 32, name: "情報セキュリティ・Web防御" },
{ id: 33, name: "ネットワーク・サイバー防御" },
{ id: 34, name: "認証・ゼロトラスト" },
{ id: 35, name: "暗号・インシデント対応" },
{ id: 36, name: "セキュリティ管理・開発" }
],
"10": [
{ id: 37, name: "ITパスポート・基本情報" },
{ id: 38, name: "高度情報処理試験" },
{ id: 39, name: "情報セキュリティ系資格" }
]
};
// サーブレット側で保持している現在のサブカテゴリー値
const currentSubCat = "<%=(book.getSubcategoryName() != null) ? book.getSubcategoryName() : ""%>";
function updateSubCategories() {
const catSelect = document.getElementById("category");
const subSelect = document.getElementById("subCategory");
const selectedCat = catSelect.value;
subSelect.innerHTML = "";
const options = subCategories[selectedCat] || [];
options.forEach(item => {
const opt = document.createElement("option");
opt.value = item.id;
opt.textContent = item.name;
if (currentSubCat === String(item.id) || currentSubCat === item.name) {
opt.selected = true;
}
subSelect.appendChild(opt);
});
}
// 初期表示時の初期化処理
window.addEventListener("DOMContentLoaded", function() {
updateSubCategories();
});
function confirmUpdate() {
const requiredFields = [ document.getElementById("isbn"),
document.getElementById("title"),
document.getElementById("author"),
document.getElementById("category"),
document.getElementById("subCategory"),
document.getElementById("location"),
document.getElementById("status"),
document.getElementById("bookCondition") ];
const empty = requiredFields.some(function(field) {
return !field.value.trim();
});
if (empty) {
alert("必須項目を入力してください。");
return;
}
const isbn = document.getElementById("isbn").value.replace(
/[-\s]/g, "");
if (!/^(?:\d{10}|\d{13})$/.test(isbn)) {
alert("ISBNは10桁または13桁で入力してください。");
return;
}
const url = document.getElementById("url").value.trim();
if (url !== "") {
try {
new URL(url);
} catch (e) {
alert("URLの形式が正しくありません。");
return;
}
}
document.getElementById("bookForm").submit();
}
</script>
</body>
</html>

View File

@@ -0,0 +1,767 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="bookequ_manage_system.entity.Book"%>
<%@ page import="java.text.SimpleDateFormat"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.HashMap"%>
<%
Book book = (Book) request.getAttribute("book");
if (book == null) {
book = new Book();
}
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy/MM/dd");
// 表示用カテゴリーマップ
Map<String, String> categoryMap = new HashMap<>();
categoryMap.put("1", "AI・データ分析");
categoryMap.put("2", "クラウド");
categoryMap.put("3", "プログラミング");
categoryMap.put("4", "ネットワーク");
categoryMap.put("5", "Web技術");
categoryMap.put("6", "データベース");
categoryMap.put("7", "ITマネジメント");
categoryMap.put("8", "コンピュータ基礎");
categoryMap.put("9", "セキュリティ");
categoryMap.put("10", "IT資格");
// 表示用サブカテゴリーマップ
Map<String, String> subCategoryMap = new HashMap<>();
subCategoryMap.put("1", "人工知能・機械学習");
subCategoryMap.put("2", "統計・データ分析");
subCategoryMap.put("3", "自然言語処理・生成AI");
subCategoryMap.put("4", "AWS・クラウド基盤");
subCategoryMap.put("5", "クラウドサービス");
subCategoryMap.put("6", "クラウドアーキテクチャ・運用");
subCategoryMap.put("7", "コンテナ・FinOps");
subCategoryMap.put("8", "Java・C#・C言語");
subCategoryMap.put("9", "Web・スクリプト言語");
subCategoryMap.put("10", "モダン言語");
subCategoryMap.put("11", "アルゴリズム・設計");
subCategoryMap.put("12", "TCP/IP・プロトコル");
subCategoryMap.put("13", "ネットワーク構築・運用");
subCategoryMap.put("14", "無線・DNS・HTTP");
subCategoryMap.put("15", "ネットワークセキュリティ・Linux");
subCategoryMap.put("16", "Web基礎・HTML/CSS");
subCategoryMap.put("17", "JavaScript・Node.js・React");
subCategoryMap.put("18", "Webデザイン・アクセシビリティ");
subCategoryMap.put("19", "Web API・セキュリティ");
subCategoryMap.put("20", "SQL基礎・リファレンス");
subCategoryMap.put("21", "データベース設計・モデリング");
subCategoryMap.put("22", "SQLチューニング・分析");
subCategoryMap.put("23", "DBスペシャリスト・実践");
subCategoryMap.put("24", "プロジェクト・アジャイル管理");
subCategoryMap.put("25", "ITサービス・開発管理");
subCategoryMap.put("26", "品質・テスト・要件定義");
subCategoryMap.put("27", "コンピュータ入門・アーキテクチャ");
subCategoryMap.put("28", "OS・Linux");
subCategoryMap.put("29", "プログラム・データ構造");
subCategoryMap.put("30", "情報理論・ネットワーク");
subCategoryMap.put("31", "論理回路・システム");
subCategoryMap.put("32", "情報セキュリティ・Web防御");
subCategoryMap.put("33", "ネットワーク・サイバー防御");
subCategoryMap.put("34", "認証・ゼロトラスト");
subCategoryMap.put("35", "暗号・インシデント対応");
subCategoryMap.put("36", "セキュリティ管理・開発");
subCategoryMap.put("37", "ITパスポート・基本情報");
subCategoryMap.put("38", "高度情報処理試験");
subCategoryMap.put("39", "情報セキュリティ系資格");
// 表示用 保管場所マップ
Map<String, String> locationMap = new HashMap<>();
locationMap.put("1", "未確定");
locationMap.put("2", "開発エリア書棚");
locationMap.put("3", "会議室前ラック");
// 表示用 貸出状態マップ
Map<Integer, String> statusMap = new HashMap<>();
statusMap.put(0, "貸出可");
statusMap.put(1, "貸出中");
statusMap.put(2, "利用停止");
// 表示用 本の状態マップ
Map<Integer, String> conditionMap = new HashMap<>();
conditionMap.put(1, "新品同様 : ほぼ未使用");
conditionMap.put(2, "良好 : 目立つ傷や汚れ無し");
conditionMap.put(3, "使用感あり : 多少の折れ、擦れあり");
conditionMap.put(4, "傷みあり : 目立つ傷、汚れ、書き込みあり");
// 表示用名称の取得
String displayCategory = categoryMap.getOrDefault(book.getCategoryName(), book.getCategoryName());
String displaySubCategory = subCategoryMap.getOrDefault(book.getSubcategoryName(), book.getSubcategoryName());
String displayLocation = locationMap.getOrDefault(book.getLocationName(), book.getLocationName());
String displayStatus = statusMap.getOrDefault(book.getBookStatus(), String.valueOf(book.getBookStatus()));
String displayCondition = conditionMap.getOrDefault(book.getCondition(), String.valueOf(book.getCondition()));
%>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>【図書】更新内容確認</title>
<style>
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
min-height: 100%;
font-family: "Noto Sans JP", "Yu Gothic", "YuGothic", "Meiryo", Arial,
sans-serif;
color: #333;
background: #fff;
font-size: 13px;
}
.page {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Header */
.header {
height: 56px;
border-bottom: 1px solid #ddd;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 14px 0 17px;
background: #fff;
}
.logo {
display: flex;
align-items: center;
gap: 8px;
font-size: 15px;
font-weight: 700;
color: #444;
}
.logo-icon {
width: 20px;
height: 20px;
border: 2px solid #294b85;
border-radius: 2px;
position: relative;
}
.logo-icon::before {
content: "";
position: absolute;
left: 8px;
top: -2px;
height: 20px;
border-left: 1px solid #294b85;
}
.header-right {
display: flex;
align-items: center;
gap: 17px;
}
.user-name {
font-size: 11px;
color: #555;
white-space: nowrap;
padding: 6px 8px;
border-radius: 3px;
cursor: default;
}
.logout {
height: 28px;
padding: 0 10px;
border: 1px solid #bbb;
border-radius: 3px;
background: #fff;
color: #444;
font-size: 11px;
cursor: pointer;
}
/* Main layout */
.main {
flex: 1;
display: flex;
min-height: calc(100vh - 56px);
}
/* Sidebar */
.sidebar {
width: 116px;
flex: 0 0 150px;
background: #002d5b;
color: #fff;
padding-top: 17px;
}
.side-title {
padding: 0 12px 10px;
font-size: 8px;
color: #d9e4f0;
}
.menu-item {
height: 40px;
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
color: #fff;
font-size: 10px;
font-weight: 600;
cursor: pointer;
}
.menu-item.active {
background: #1264b4;
}
.menu-icon {
width: 16px;
text-align: center;
font-size: 14px;
}
/* Content */
.content {
flex: 1;
min-width: 0;
padding: 17px 14px 20px;
background: #fff;
}
.breadcrumb {
font-size: 8px;
color: #6f8094;
margin-bottom: 9px;
}
.breadcrumb span {
margin: 0 5px;
color: #9aa4ae;
}
.page-title {
margin: 0;
font-size: 18px;
font-weight: 700;
color: #333;
line-height: 1.4;
}
.description {
margin: 2px 0 13px;
font-size: 9px;
color: #777;
}
/* Form card */
.form-card {
border: 1px solid #e0e0e0;
border-radius: 3px;
padding: 13px 11px 15px;
box-shadow: 0 0 2px rgba(0, 0, 0, .02);
}
.section-title {
margin: 0 0 10px;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
font-size: 11px;
font-weight: 700;
color: #333;
}
.system-info-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
column-gap: 34px;
margin-bottom: 12px;
}
.input-fields {
display: flex;
flex-direction: column;
gap: 10px;
}
.optional-fields {
margin-top: 14px;
padding-top: 14px;
border-top: 1px solid #eee;
}
.field {
display: grid;
grid-template-columns: 76px minmax(0, 1fr);
align-items: center;
column-gap: 8px;
min-width: 0;
}
.label {
font-size: 9px;
font-weight: 600;
color: #333;
white-space: nowrap;
}
.required {
color: #e53935;
font-size: 8px;
margin-left: 2px;
font-weight: 500;
}
.optional {
color: #333;
font-size: 8px;
margin-left: 2px;
font-weight: 500;
}
.control {
width: 100%;
min-height: 28px;
padding: 6px 9px;
border: 1px solid #ddd;
border-radius: 3px;
background: #f3f5f8;
color: #555;
font-size: 9px;
line-height: 1.5;
display: flex;
align-items: center;
}
.with-note {
display: flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.with-note .control {
flex: 1;
min-width: 0;
}
.note {
flex: 0 0 auto;
color: #777;
font-size: 8px;
white-space: nowrap;
}
/* Memo */
.memo-section {
margin-top: 16px;
border: 1px solid #e0e0e0;
border-radius: 3px;
padding: 12px 11px 14px;
}
.memo-row {
display: grid;
grid-template-columns: 76px minmax(0, 1fr) 82px;
gap: 8px;
align-items: start;
}
.memo-value {
min-height: 60px;
padding: 8px 9px;
border: 1px solid #ddd;
border-radius: 3px;
background: #f3f5f8;
color: #555;
font-size: 9px;
line-height: 1.5;
white-space: pre-wrap;
}
.memo-note {
color: #777;
font-size: 8px;
padding-top: 7px;
white-space: nowrap;
}
/* Bottom area */
.bottom {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 12px;
}
.actions {
display: flex;
gap: 10px;
}
.back-button {
min-width: 82px;
height: 30px;
border: 1px solid #bbb;
border-radius: 3px;
background: #fff;
color: #444;
font-size: 9px;
font-weight: 600;
cursor: pointer;
}
.register-button {
height: 30px;
min-width: 86px;
border: 1px solid #005bb5;
border-radius: 3px;
background: #0967c3;
color: #fff;
font-size: 9px;
font-weight: 600;
cursor: pointer;
}
/* Modal Popup Styles */
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal-content {
background: #fff;
border-radius: 4px;
width: 500px;
max-width: 90%;
max-height: 85vh;
display: flex;
flex-direction: column;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
overflow: hidden;
}
.modal-header {
padding: 12px 16px;
background: #f8f9fa;
border-bottom: 1px solid #e0e0e0;
font-size: 13px;
font-weight: 700;
color: #333;
}
.modal-body {
padding: 16px;
overflow-y: auto;
font-size: 11px;
}
.modal-body-title {
margin-bottom: 12px;
color: #555;
font-size: 11px;
}
.modal-list {
display: flex;
flex-direction: column;
gap: 8px;
border: 1px solid #eee;
padding: 10px;
border-radius: 3px;
background: #fafafa;
}
.modal-item {
display: grid;
grid-template-columns: 100px 1fr;
align-items: center;
gap: 8px;
}
.modal-label {
font-weight: 600;
color: #666;
}
.modal-val {
color: #333;
word-break: break-all;
}
.modal-footer {
padding: 12px 16px;
border-top: 1px solid #e0e0e0;
display: flex;
justify-content: flex-end;
gap: 10px;
background: #f8f9fa;
}
.modal-cancel-btn {
height: 30px;
min-width: 80px;
border: 1px solid #bbb;
border-radius: 3px;
background: #fff;
color: #444;
font-size: 10px;
font-weight: 600;
cursor: pointer;
}
.modal-confirm-btn {
height: 30px;
min-width: 80px;
border: 1px solid #005bb5;
border-radius: 3px;
background: #0967c3;
color: #fff;
font-size: 10px;
font-weight: 600;
cursor: pointer;
}
</style>
</head>
<body>
<div class="page">
<header class="header">
<div class="logo">
<span class="logo-icon"></span><span>📖 ShareBooks</span>
</div>
<div class="header-right">
<div class="user-name">ログイン中</div>
<button type="button" class="logout">
ログアウト
</button>
</div>
</header>
<div class="main">
<aside class="sidebar">
<div class="side-title">管理者画面</div>
<div class="menu-item">
<span class="menu-icon">🏠</span><span>トップメニュー</span>
</div>
<div class="menu-item active">
<span class="menu-icon">📖</span><span>社内図書一覧</span>
</div>
</aside>
<main class="content">
<div class="breadcrumb">
トップメニュー <span>›</span> 社内図書一覧 <span>›</span> 図書情報更新入力 <span>›</span>
図書情報更新内容確認
</div>
<h1 class="page-title">図書情報更新内容確認</h1>
<p class="description">入力した内容をご確認ください。内容に問題がなければ「登録する」ボタンを押してください。</p>
<form id="executeUpdateForm"
action="${pageContext.request.contextPath}/book/updateExecute"
method="post">
<!-- DB更新用 hidden パラメータ -->
<input type="hidden" name="bookManagementId"
value="<%=book.getBookManageId() != null ? book.getBookManageId() : ""%>">
<input type="hidden" name="isbn"
value="<%=book.getIsbn() != null ? book.getIsbn() : ""%>">
<input type="hidden" name="title"
value="<%=book.getTitle() != null ? book.getTitle() : ""%>">
<input type="hidden" name="author"
value="<%=book.getAuthor() != null ? book.getAuthor() : ""%>">
<input type="hidden" name="category"
value="<%=book.getCategoryName() != null ? book.getCategoryName() : ""%>">
<input type="hidden" name="subCategory"
value="<%=book.getSubcategoryName() != null ? book.getSubcategoryName() : ""%>">
<input type="hidden" name="location"
value="<%=book.getLocationName() != null ? book.getLocationName() : ""%>">
<input type="hidden" name="status"
value="<%=book.getBookStatus()%>"> <input type="hidden"
name="bookCondition" value="<%=book.getCondition()%>"> <input
type="hidden" name="publisher"
value="<%=book.getPublisher() != null ? book.getPublisher() : ""%>">
<input type="hidden" name="publicationDate"
value="<%=book.getPublicationDate() != null ? book.getPublicationDate() : ""%>">
<input type="hidden" name="donor"
value="<%=book.getDonorName() != null ? book.getDonorName() : ""%>">
<input type="hidden" name="url" value=""> <input
type="hidden" name="memo"
value="<%=book.getDescription() != null ? book.getDescription() : ""%>">
<section class="form-card">
<h2 class="section-title">図書基本情報</h2>
<div class="system-info-row">
<div class="field">
<label class="label">図書管理ID</label>
<div class="with-note">
<div class="control"><%=book.getBookManageId() != null ? book.getBookManageId() : ""%></div>
<span class="note">※変更できません</span>
</div>
</div>
</div>
<div class="input-fields">
<div class="field">
<label class="label">ISBN<span class="required">(必須)</span></label>
<div class="control"><%=book.getIsbn() != null ? book.getIsbn() : ""%></div>
</div>
<div class="field">
<label class="label">タイトル<span class="required">(必須)</span></label>
<div class="control"><%=book.getTitle() != null ? book.getTitle() : ""%></div>
</div>
<div class="field">
<label class="label">著者名<span class="required">(必須)</span></label>
<div class="control"><%=book.getAuthor() != null ? book.getAuthor() : ""%></div>
</div>
<div class="field">
<label class="label">カテゴリ<span class="required">(必須)</span></label>
<div class="control"><%=displayCategory%></div>
</div>
<div class="field">
<label class="label">サブカテゴリ<span class="required">(必須)</span></label>
<div class="control"><%=displaySubCategory%></div>
</div>
<div class="field">
<label class="label">保管場所<span class="required">(必須)</span></label>
<div class="control"><%=displayLocation%></div>
</div>
<div class="field">
<label class="label">貸出状態<span class="required">(必須)</span></label>
<div class="control"><%=displayStatus%></div>
</div>
<div class="field">
<label class="label">本の状態<span class="required">(必須)</span></label>
<div class="control"><%=displayCondition%></div>
</div>
</div>
<div class="input-fields optional-fields">
<div class="field">
<label class="label">出版社<span class="optional">(任意)</span></label>
<div class="control"><%=book.getPublisher() != null ? book.getPublisher() : ""%></div>
</div>
<div class="field">
<label class="label">出版日<span class="optional">(任意)</span></label>
<div class="control"><%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%></div>
</div>
<div class="field">
<label class="label">寄贈者ID<span class="optional">(任意)</span></label>
<div class="control"><%=book.getDonorName() != null ? book.getDonorName() : ""%></div>
</div>
</div>
</section>
<section class="memo-section">
<div class="memo-row">
<label class="label">備考<span class="optional">(任意)</span></label>
<div class="memo-value"><%=book.getDescription() != null ? book.getDescription() : ""%></div>
<span class="memo-note">※任意の場合は空欄でも可</span>
</div>
</section>
<div class="bottom">
<button type="button" class="back-button"
onclick="history.back();">入力画面へ戻る</button>
<div class="actions">
<button type="button" class="register-button"
onclick="openModal()">登録する</button>
</div>
</div>
</form>
</main>
</div>
</div>
<!-- 更新確認ポップアップ(モーダル) -->
<div id="confirmModal" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">更新内容の最終確認</div>
<div class="modal-body">
<p class="modal-body-title">以下の内容で情報を更新します。よろしいですか?</p>
<div class="modal-list">
<div class="modal-item">
<span class="modal-label">図書管理ID:</span> <span class="modal-val"><%=book.getBookManageId() != null ? book.getBookManageId() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">ISBN:</span> <span class="modal-val"><%=book.getIsbn() != null ? book.getIsbn() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">タイトル:</span> <span class="modal-val"><%=book.getTitle() != null ? book.getTitle() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">著者名:</span> <span class="modal-val"><%=book.getAuthor() != null ? book.getAuthor() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">カテゴリ:</span> <span class="modal-val"><%=displayCategory%></span>
</div>
<div class="modal-item">
<span class="modal-label">サブカテゴリ:</span> <span class="modal-val"><%=displaySubCategory%></span>
</div>
<div class="modal-item">
<span class="modal-label">保管場所:</span> <span class="modal-val"><%=displayLocation%></span>
</div>
<div class="modal-item">
<span class="modal-label">貸出状態:</span> <span class="modal-val"><%=displayStatus%></span>
</div>
<div class="modal-item">
<span class="modal-label">本の状態:</span> <span class="modal-val"><%=displayCondition%></span>
</div>
<div class="modal-item">
<span class="modal-label">出版社:</span> <span class="modal-val"><%=book.getPublisher() != null ? book.getPublisher() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">出版日:</span> <span class="modal-val"><%=book.getPublicationDate() != null ? sdfDate.format(book.getPublicationDate()) : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">寄贈者ID:</span> <span class="modal-val"><%=book.getDonorName() != null ? book.getDonorName() : ""%></span>
</div>
<div class="modal-item">
<span class="modal-label">備考:</span> <span class="modal-val"><%=book.getDescription() != null ? book.getDescription() : ""%></span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="modal-cancel-btn"
onclick="closeModal()">キャンセル</button>
<button type="button" class="modal-confirm-btn"
onclick="submitForm()">更新</button>
</div>
</div>
</div>
<script>
function openModal() {
document.getElementById("confirmModal").style.display = "flex";
}
function closeModal() {
document.getElementById("confirmModal").style.display = "none";
}
function submitForm() {
document.getElementById("executeUpdateForm").submit();
}
</script>
</body>
</html>