Rails8.0でFullCalenderを導入しようとした際に、fullcalendar-rails
をgemで
インストールして実装するやり方を試みたところうまくいかず、別の方法で解決したので備忘録として残します。
原因
rails8.0では、Javascriptの扱いが以前のバージョンと異なるようです。
Hotwireというライブラリを標準で使用しており、さらに言うとHotwireの"Stimulu"で
ページのjavascriptを管理しているようです。これに準じた方法でライブラリを使用する必要があるようでした。
ライブラリの使い方
まず、configディレクトリの中にある"importmap.rb"に使いたいライブラリを追記します。
pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
#追加
pin "@fullcalendar/core", to: "https://cdn.skypack.dev/@fullcalendar/core@6.1.19"
#追加
pin "@fullcalendar/daygrid", to: "https://cdn.skypack.dev/@fullcalendar/daygrid@6.1.19"
pin_all_from "app/javascript/controllers", under: "controllers"
続いて、app>assets>javascript>controllersの中に****_controller.jsという命名規則で
javascriptファイルを配置します。今回はschedule_controller.jsという名前にしました。
このファイルを以下のように編集します。
import { Controller } from "@hotwired/stimulus"
import { Calendar } from "@fullcalendar/core";
import dayGridPlugin from "@fullcalendar/daygrid";
export default class extends Controller {
static targets = ["calendar"]
connect() {
this.calendar = new Calendar(this.calendarTarget, {
plugins: [dayGridPlugin],
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
}
})
window.addEventListener("load", () => {
this.calendar.render();
});
}
}
ポイントとして、static targets = ["calendar"]
の部分に注目してください。
ここは、html.erb上でタグに付与したdata属性のキーを指定します。複数指定することも可能です。
また、このキーに対して何らかの操作をする際は、(キー名)Target
がDOM要素となります。
今回は、calendarTarget
の部分がそれに該当します。
schedule_controller.jsを反映させるhtml.erbは以下のように書きます。
<div data-controller="schedule">
<div data-schedule-target="calendar"></div>
</div>
親要素となるタグに、data-controllerという属性が付与されています。
ここは、使用したい****_controller.jsを指定します。
_controller.jsのの部分を値として書きます。今回はschedule_controller.jsを使いたいので、指定する値は"schedule"になります。
子要素でDOM操作をしたいタグにdata--target属性を付与します。
の部分は、_controller.jsのと同じ名前にする必要があります。
今回はschedule_controller.jsというファイル名なので、data-schedule-targetとなります。
値には、static targets = []
で定義したキーを指定します。
今回は、calendarを定義したので値を"calendar"とします。
data-schedule-target="calendar"に対して、schedule_controller.jsのconnect()メソッドに書かれたDOM操作が行われる仕組みとなります。
これで実装は完了です。