前回までのあらすじ&今回の目標
前回は、データベースに登録されているデータを「FullCalendar」のカレンダーに表示できるように修正を行いました。
今後はそのデータベースに「データを登録する仕組み」を追加していく予定です。
そして今回はその第一歩として、FullCalendarの「Toolbar」を用いて登録ボタンを追加し、データ登録用のモーダル画面を表示させることを目標に進めていきます。
FullCalendarのボタン追加方法
FullCalendarではヘッダ/フッタのツールバーにボタンを追加することができます。
追加するには下記のように「customButtons」と「headerToolbar/footerToolbar」のプロパティを記載する必要があります。
ボタン押下後の処理はclickプロパティに記載するようなので、7行目部分にモーダルの表示処理を実装すれば実現できそうです。
let calendar = new FullCalendar.Calendar(calendarEl, {
// customButtonsプロパティから自作ボタンを定義
customButtons: {
mybutton: {
// textはボタンには表示する文字列、clickにはボタン押下時の処理を記載
text: "button",
click: function() {...}
}
},
headerToolbar: {
// 上記で定義したボタンを記載する
// ボタンは画面左、中央、右に出力可能でそれぞれleft(start)、center、right(end)で指定する
right: 'mybutton',
// ボタンは半角スペースで分けることで複数出力可能
// today、prev,nextのようにFullCalendarが既に用意しているボタンもある
center: 'today prev,next'
}
});
実装
モーダル画面の作成
モーダル画面は別のファイルに書き出しました。実際に使用する際にはThymeleafのフラグメント式を使用してコンテンツを挿入するようにします。(3~12行目、14~51行目)
またアイコンは「Material Symbols」を使用して出力しています。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="ja">
<head th:fragment="registration_head(links)">
<!--/* 当htmlのhead内容 */-->
<meta charset='utf-8'/>
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.14/index.global.min.js'></script>
<script th:src="@{/js/editcalendar.js}"></script>
<link rel="stylesheet" th:href="@{/css\registration.css}">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20,400,0,0" />
<!--/* 出力先のhead内容 */-->
<th:block th:replace="${links}" />
</head>
<body>
<div th:fragment="registration-modal" id="modal" class="modal">
<div class="modal-content">
<label id="closer" class="closer">×</label>
<div class="modal-content-title">
<h2 class="title">メニューの新規登録</h2>
</div>
<form th:action="@{registration}">
<div class="modal-content-row">
<span class="material-symbols-outlined material-symbols-big-font">edit_calendar</span>
<input id="eating-date" type="date">
</div>
<div class="modal-content-row">
<div class="modal-content-icon"><span class="material-symbols-outlined material-symbols-big-font">chat_info</span></div>
<div class="modal-content-input-area">
<input id="meal-type-1" type="radio" name="meal-types">
<label for="meal-type-1">朝食</label>
<input id="meal-type-2" type="radio" name="meal-types">
<label for="meal-type-2">昼食</label>
<input id="meal-type-3" type="radio" name="meal-types">
<label for="meal-type-3">夕食</label>
</div>
</div>
<div class="modal-content-row">
<div class="modal-content-icon"><span class="material-symbols-outlined material-symbols-big-font">restaurant</span></div>
<div class="modal-content-input-area">
<input type="text" placeholder="料理名を入力">
</div>
</div>
<div class="modal-content-row">
<span class="material-symbols-outlined material-symbols-big-font">description</span>
<input type="text" placeholder="メモを入力">
</div>
<div class="submit">
<input type="submit" value="上記内容で登録" class="submit-button">
</div>
</form>
</div>
</div>
</body>
</html>
モーダル用のcssファイルは下記の通りです。見た目とモーダルを非表示する内容を記載しています。
@charset "UTF-8";
.modal {
position : fixed;
top : 0;
left : 0;
display : none;
z-index : 1;
width : 100%;
height : 100%;
align-items : center;
justify-content : center;
background-color : rgb(0 0 0 / 70%);
}
.modal-content {
position : absolute;
width : 45%;
height : 60%;
background-color : #FEFEFE;
border-radius : 10px;
}
.modal-content .modal-content-title {
border-radius : 10px 10px 0 0;
width : 100%;
background-color : #607080;
}
.modal-content .modal-content-title .title{
width : 90%;
margin : 0;
padding : 10px;
color : #FEFEFE;
}
.material-symbols-outlined.material-symbols-big-font {
font-size : 36px;
}
.modal-content .modal-content-row {
display : flex;
align-items : center;
padding : 10px;
column-gap : 20px;
}
.closer {
position :absolute;
top : 10px;
right : 20px;
font-size : 24px;
color : #FEFEFE;
text-decoration : none;
cursor : pointer;
}
.submit {
text-align : center;
}
.submit-button {
display : inline-block;
border-radius : 10px;
font-size : 12pt;
text-align : center;
cursor : pointer;
padding : 10px 48px;
background : lightslategray;
color : #fefefe;
line-height : 1em;
border : 2px solid lightslategray;
}
.submit-button:hover {
color : #f0f0f0;
background : #607080;
border : 2px solid #607080;
}
上記でモーダルの用意ができたため、あとは既存のhtmlにThymeleafのreplace属性を追加して挿入するだけになります。(3~8行目、11行目)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="ja">
<head th:replace="~{registration::registration_head(~{::link})}">
<meta charset='utf-8' />
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.14/index.global.min.js'></script>
<script th:src="@{/js/editcalendar.js}"></script>
<link th:href="@{/css/foodapp.css}" rel="styleSheet" />
</head>
<body>
<div id='calendar'></div>
<div th:replace="~{registration::registration-modal}"></div>
<script type="text/javascript" th:inline="javascript">
document.addEventListener('DOMContentLoaded', initializeCalendar(/*[[${events}]]*/ null));
</script>
</body>
</html>
@charset "UTF-8";
body {
margin: 0;
}
JavaScriptの修正
修正点としては下記の通りです。今回の実装ではclickプロパティにモーダルを表示する処理を実装した関数を渡しています。
- ボタン追加用のプロパティ追記(4~12行目)
- カレンダー初期化時にモーダルの閉じるボタンの機能を追加(18~21行目)
- モーダルの表示/非表示処理を追加(24~29行目、31~36行目)
function initializeCalendar(events) {
let calendarEl = document.getElementById('calendar');
let calendar = new FullCalendar.Calendar(calendarEl, {
customButtons: {
new: {
text: "new",
click: showRegistrationModal
}
},
headerToolbar: {
right: 'new today prev,next'
},
contentHeight: "auto",
events
});
calendar.render();
let closer = document.getElementById('closer');
if (closer) {
closer.addEventListener('click', closeRegistrationModal);
}
}
function showRegistrationModal() {
let modal = document.getElementById("modal");
if (modal) {
modal.style.display = 'flex';
}
}
function closeRegistrationModal() {
let modal = document.getElementById('modal');
if (modal) {
modal.style.display = 'none';
}
}
動作確認
まず初期表示ですが、画面右上に今回追加したnewボタンが出力されていますね。
○出力結果 (初期表示)
次にnewボタンを押下してみます。
○出力結果 (newボタン押下時)
newボタンを押下すると今回作成したモーダルが無事表示されました。これであとはForm部分の修正とJava側に処理を追加すればメニューの登録ができるようになりそうですね!
今後の予定
今回はメニュー情報を入力するモーダル画面とその画面を表示させるボタンを「FullCalendar」を用いて実現しました。
次回はモーダルのForm部分の修正とJava側の実装を行って、データの登録処理を実装していきます。
今日の夕飯はチキン南蛮です。それではまた。。
コメント