【食事内容管理Webアプリ】FullCalendarのイベントドラッグ&ドロップ

前回までのあらすじ&今回の目標

前回は、「FullCalendar」のextendedPropsプロパティを利用して登録したメモの内容を画面に表示できるようにしました。

そして今後は「FullCalendar」の機能をさらに利用して、メニューの登録を簡易的にできるようにしていきたいと思います。

ということで、今回は「FullCalendar」のExternal Event Dragging機能を用いてイベントのドラッグ&ドロップができるようになることを目標に進めていきます。

External Event Dragging機能

「FullCalendar」のExternal Event Dragging機能は、カレンダー外にあるイベントをカレンダー内にドラッグ&ドロップして追加できる機能です。

追加するイベントの作り方

追加するイベントはDraggableコンストラクタを使用して生成します。コンストラクタは二種類用意されており、下記のように使用します。

  1. new Draggable(コンテナ要素, {
     itemSelector: ‘CSSセレクタ’,
     eventData: function(イベント要素) {return {…};}
    });
  2. new Draggable(イベント要素, {eventData: {…}});

一つ目は、ドラッグ&ドロップしたいイベント要素を子孫要素とするコンテナ要素を第一引数、ドラッグ&ドロップしたいイベントのCSSセレクタや関数を記述したJavaScriptオブジェクトを第二引数とするコンストラクタです。

二つ目は、ドラッグ&ドロップしたいイベント要素を第一引数、そのイベントの各プロパティを記述したJavaScriptオブジェクトを第二引数とするコンストラクタです。

どちらを使用してもイベントのドラッグ&ドロップが可能ですが、特に理由がなければ一つ目のコンストラクタを使用すればOKです。

二つのコンストラクタはどちらとも第一引数に要素を指定しますが、指定する要素が異なる点に注意しましょう。

実装

今回は簡単な処理を追加してドラッグ&ドロップ機能の動作を確認していきたいと思います。

JavaScriptの修正

まずJavaScriptについてですが、下記の手順で修正を行います。

  1. ドラッグ&ドロップできるイベント(以降、外部イベント)を子孫要素とするコンテナ要素を取得 (3行目)
  2. 第一引数にコンテナ要素、第二引数にJavaScriptオブジェクトを指定したDraggableコンストラクタを追加 (5行目)
  3. itemSelectorプロパティには外部イベントの要素のclassに設定するfc-eventを指定 (6行目)
  4. eventDataプロパティにはカレンダーにドロップされた際に各プロパティを渡す関数を設定 (7~10行目)

関数の引数には外部イベントが渡されるので、今回はテキストをtitleプロパティに設定して返す処理とします。

editcalendar.js (修正部分抜粋)
function initializeCalendar(events) {
	
	let containerEl = document.getElementById('external-events');

	new FullCalendar.Draggable(containerEl, {
		itemSelector: '.fc-event',
		eventData: function(eventEl) {
			return {
				title: eventEl.innerText
			};
		},
	});
	
	let calendarEl = document.getElementById('calendar');
	...
}

html、cssの修正

次にhtmlですが、下記の手順で修正を行います。

  1. 外部イベントを保持するコンテナ要素(id=’external-events’)を追加 (11行目)
  2. コンテナ要素の子要素にclass=’fc-event’とメニュー名をテキストにもつ要素を追加 (15~20行目)

また装飾として下記の修正も追加しています

  • コンテナ要素とカレンダーを横並びにするために親要素(id=”foodapp-content”)を追加 (10行目)
  • コンテナ要素の上部に”Menu”と表示するように要素を追加 (12~14行目)
  • 外部イベントには「FullCalendar」で用意されているclass=”fc-h-event fc-daygrid-event”を追加して見た目を変更
calendar.html
<!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 class="foodapp-content">
      <div id="external-events">
  		  <p>
  		    <strong>Menu</strong>
  		  </p>
  		  <div class="fc-event fc-h-event fc-daygrid-event">
  		    <div class="fc-event-main">うどん</div>
  		  </div>
  		  <div class="fc-event fc-h-event fc-daygrid-event">
  		    <div class="fc-event-main">ラーメン</div>
  		  </div>
  		</div>
    	<div id="calendar"></div>
    </div>
  	<div th:replace="~{registration::registration-modal}"></div>
  	<script type="text/javascript" th:inline="javascript">
  		document.addEventListener("DOMContentLoaded", initializeCalendar(/*[[${events}]]*/ null));
  	</script>
  </body>
</html>
foodapp.css (修正箇所抜粋)
.foodapp-content {
	display: flex;
}

#external-events {
	width: 200px;
	text-align: center;
	padding: 5px 10px;
	background-color: #e5e5e5;
}

#calendar {
	flex: 1;
	padding: 5px 10px;
}

動作確認

○ドラッグ&ドロップ
ドラッグ&ドロップ

無事に外部イベントをカレンダーにドラッグ&ドロップすることができました!

今後の予定

今回はFullCalendarが提供しているドラッグ&ドロップ機能の簡単な処理をカレンダーに追加しました。

次回は外部イベントをデータベースから取得した内容に変更してカレンダーに登録できるようにしていきたいと思います!

今夜は鮭のフライでした。それではまた。。

コメント

タイトルとURLをコピーしました