先日投稿した記事と被っている箇所がありますがあしからず。
【技術スタック】
- Laravel 6.0
- AdminLTE 3 (ComposerでLaravelにインストール)
- jQuery 3.3.1+ (AdminLTEにデフォルトで入っている)
- FullCalendar 5.3.2 (AdminLTEでデフォルトで入ってるのは古いので別途新しいバージョンをCDNで導入)
FullCalendar概要
オープンソースのカスタマイズ可能なjQueryのカレンダーライブラリ。
公式ドキュメント:https://fullcalendar.io/docs
※FullCalenderのバージョンによってFullCalendarのコードの書き方がかなり変わるようなので、注意が必要です。
ver.3まではjQueryの記述方法でカレンダーを描画していましたが、ver.4以降は生のjavascriptでの記述方法に変わりました。
- DOMの取得方法がネイティブのgetElementByIdになった
- カレンダーの生成方法が new FullCalendar.Calendar() になった
JavaScript カレンダープラグイン FullCalendar ~その1 スケジュール表を作成する~ | 打ち聞かせ 様より引用
全体の大まかな流れ
- モデル、テーブル作成しておく(FullCalendarのイベントに対応するカラム名にする)
- フォームに情報を入力してボタンをクリックすると、jQuery側でクリックを検知&フォームの情報を取得
- Ajaxを使い、2で取得した情報をPOSTでコントローラー側に送信
- コントローラー側で送信された情報をsave
基本の書き方が下記。
var calendar = new Calendar(calendarEl, {
timeZone: 'UTC',
events: [
{
id: 'a',
title: 'testEvent',
start: '2020-11-01'
}
]
})
https://fullcalendar.io/docs/event-parsing に記載のイベントオブジェクト一覧で、全てのイベントに関連するプロパティを見ることができます。
下記一部抜粋です。
プロパティ名 | 概要 |
---|---|
id | 文字列または整数。イベントを一意に識別します。getEventByIdに便利です。 |
start |
イベントの開始時刻。イベントが明示的に allDay である場合、時、分、秒、ミリ秒は無視されます。 |
title |
イベントに表示されるテキスト。 |
color |
backgroundColorとborderColorを同時に指定するためのエイリアス。 |
上記の記述方法だと、 「testEventというイベント名が2020/11/1の日付に表示」されます。
今回は、 events の中身を、DBの値に置き換えていきたいと思います。
1. モデル、テーブル作成しておく(FullCalendarのeventプロパティに対応するカラム名にする)
$ php artisan make:model Event -m
で、モデル作成&マイグレーションファイルを作成します。
マイグレーションファイルを下記のように編集
// create_events_table.php
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->date('start');
$table->date('end')->nullable();
$table->string('title');
$table->string('color')->nullable();
});
}
$ php artisan migrate
でマイグレーションをかけてeventsテーブルを作成します。
2. フォームに情報を入力してボタンをクリックすると、jQuery側でクリックを検知&フォームの情報を取得
// test.blade.php
<div style="margin-top:30px; border:1px solid gray;">
<form id="form" action="">
<p><input type="text" name="title" placeholder="タイトル入力"></p>
<p><input type="date" name="start" placeholder="日付入力"></p>
<p><input type="color" name="color" ></p>
</form>
<button id="bt2">
Ajax->DBにPostテスト
</button>
CSSはガン無視です(笑)
inputタグのname属性に、送信したい値のキーを書いてあげるのがポイントです。
// scriptタグの中
$("#bt2").click(function () { // bt2のidの要素をクリックしたときに発動
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
var formData = $("#form").serialize();
// ajax部分は後に記述 //
});
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
はおまじないです。これを設定することによって、セキュアなAjax通信を行うことができます。
var formData = $("#form").serialize();
では、フォーム要素を取得して、name属性とvalue属性をキーとvalueの形式に変換します。
※ jQuery serializeでキーバリューにするサンプル | ITSakura 様を参照
3. Ajaxを使い、2で取得した情報をPOSTでコントローラー側に送信
$("#bt2").click(function () {
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
var formData = $("#form").serialize();
console.log(formData);
$.ajax({
//POST通信
type: "post", //HTTP通信のメソッドをPOSTで指定
//ここでデータの送信先URLを指定します。
url: "/postevent", //通信先のURL
dataType: "json", // データタイプをjsonで指定
data: formData, // serializeしたデータを指定
})
//通信が成功したとき
.then((res) => {
console.log(res);
// カレンダーの再描画
var calendarEl = document.getElementById("calendar");
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: "prev,next today",
center: "title",
right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
},
locale: "ja",
editable: true,
googleCalendarApiKey: "GoogleのAPIKEY",
eventSources: [
{
googleCalendarId: "japanese__ja@holiday.calendar.google.com", //祝日の予定を取得
rendering: "background",
color: "#FF6666",
},
],
events: "/getevents",
selectable: true,
});
calendar.render(); //カレンダーを再描画
})
//通信が失敗したとき
.fail((error) => {
console.log(error.statusText);
});
});
4. コントローラー側で送信された情報をsave
//web.php
Route::post('/postevent', '****Controller@postEvent'); //任意のコントローラー名を記述
// コントローラー側
public function postEvent(Request $request)
{
$event = new Event();
$event->start = $request->start;
$event->title = $request->title;
$event->color = $request->color;
$event->save();
return $event;
}