実装すること
①マイページで予定管理ができるようにする
②日付をクリックで予定の作成・編集をできるようにする
※Userモデル等は作成した前提で進めていきます。
FullCalenderとは
オープンソースのカスタマイズ可能なjqueryのカレンダーライブラリです。
上手く活用することで、カレンダーのスクラッチ開発をせずにリッチなカレンダーを表示できます。
ER図
![calenderER図.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F539971%2Fed96da21-982d-82b6-6e1e-27ddf084e82c.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=33af7d26db972e74ea33bd6ed9fd9f22)
モデルの作成
$ rails g model Event title:string body:text disp_flg:boolean start:datetime end:datetime allDay:string
アソシエーションの確認
class User < ApplicationRecord
has_many :events
end
class Event < ApplicationRecord
belongs_to :user
end
ダウンロード
FullCalenderの公式ドキュメントからダウンロードし、zipを解凍します。
https://fullcalendar.io/
Gemの追加
gem 'jquery-rails', '4.3.3'
gem 'fullcalendar-rails'
gem 'momentjs-rails'
$ bundle inatall
読み込み
application.htmlのhead内で読み込みます。
<head>
~
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/core/main.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/daygrid/main.min.css">
~
</head>
//= require jquery
//= require moment
//= require fullcalendar
表示する(マイページ)
![カレンダー.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F539971%2F3a623adc-d50e-72d9-e3f5-bca7f7bfa9b8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a2b57ffec6f517f132781129d0268630)
![カレンダー登録.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F539971%2Fac91a317-1001-ee58-03c5-53385de92a2b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=f679cb7cc1ff3b68f497ff0b8efd796b)
コントローラー
def show
@user = User.find(params[:id])
@events = Event.where(user_id: @user.id)
@event = Event.new
end
def create
event = Event.new(event_params)
event.save!
@events = Event.where(user_id: current_user.id)
end
def update
event = Event.find(params[:id])
@events = Event.where(user_id: current_user.id)
event.update(event_params)
end
def destroy
@user = User.find(params[:id])
event = Event.find(params[:id])
event.destroy
redirect_to user_path(@user)
end
private
def event_params
params.require(:event).permit(:title, :start, :end, :user_id, :body)
end
ビュー
予定を表示する・作成する
・<div id="calendar"></div>
でカレンダーを表示しています。
・予定を編集するときのモーダル内容はパーシャルにします。
<h3 class="text-center">カレンダー</h3>
<!-- カレンダーの表示 -->
<div id="calendar"></div>
<!-- もしユーザーがログインしていたら -->
<% if user_signed_in? %>
<!-- ページのparams.idがログインユーザー.idと同じなら -->
<% if @user.id == current_user.id %>
<div id="inputScheduleForm" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-nm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">スケジュール登録</h4>
</div>
<div class="modal-body">
<%= form_with model: @event, url: events_path do |f| %>
<div class="col">
<p>
<span>タイトル</span>
<span><%= f.text_field :title, class: "form-control", placeholder: "タイトルを入力してください" %></span>
</p>
<span>開始日時</span>
<span><%= f.datetime_field :start, placeholder: "XXXX-XX-XX", class:"field" %> ~ </span><br>
<span>終了日時</span>
<span><%= f.datetime_field :end, placeholder: "XXXX-XX-XX", class:"field" %></span><br>
<span>詳細
<%= f.text_field :body, class: "form-control", placeholder: "タイトルの詳細を記入してください" %></span>
</div>
<div class="modal-footer">
<%= f.submit "登録する", class: "btn btn-primary" %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
</div>
<% end %>
</div>
</div>
</div>
</div>
<!-- 編集 ------------------------------------------------------------------>
<div id="inputEditForm">
<%= render 'events/edit', events: @events %>
</div>
<% end %>
<% end %>
<script>
// CRUDを行う際にCSRF対策のtokenを発行
$(document).ready(function() {
var prepare = function(options, originalOptions, jqXHR) {
var token;
if (!options.crossDomain) {
token = $('meta[name="csrf-token"]').attr('content');
if (token) {
return jqXHR.setRequestHeader('X-CSRF-Token', token);
}
}
};
}
)
// カレンダー表示
$('#calendar').fullCalendar ({
header: {
left: 'prev,next today',
center: 'month,agendaWeek,agendaDay',
right: 'title'
},
buttonText: {
prev: "<",
next: ">"
},
timezone: 'UTC',
events: '/users/events.json',
navLinks: true,
selectable: true,
selectHelper: true,
// 日付クリック
dayClick : function ( date , jsEvent , view ) {
$('#inputScheduleForm').modal('show');
},
// event クリックで編集、削除
eventClick : function(event, jsEvent , view) {
jsEvent.preventDefault();
$(`#inputScheduleEditForm${event.id}`).modal('show');
},
eventMouseover : function(event, jsEvent , view) {
jsEvent.preventDefault();
}
})
</script>
//フォームを空にする
$('input[type="text"]').val('');
//モーダルを消す
$('#inputScheduleForm').modal('hide');
//作成した予定を差し替える
$('#inputEditForm').html('<%= escape_javascript(render("events/edit", events: @events )) %>');
// フルカレンダー を一度消しもう一度表示
$('#calendar').fullCalendar('refetchEvents')
予定を編集する
<% events.each do |event| %>
<div id='inputScheduleEditForm<%= event.id %>' class="modal fade" tabindex="-1">
<div class="modal-dialog modal-nm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">スケジュール編集</h4>
</div>
<div class="modal-body">
<div class="col">
<%= form_with(model: event, url: users_event_path(event), method: :put) do |f| %>
<p>
<span>タイトル</span>
<span id="inputTitle" value=""><%= f.text_field :title, class: "form-control", placeholder: "タイトルを入力してください" %></span>
</p>
<span>開始日時</span>
<span><%= f.datetime_field :start, placeholder: "XXXX-XX-XX", class:"field" %> ~ </span><br>
<span>終了日時</span>
<span><%= f.datetime_field :end, placeholder: "XXXX-XX-XX", class:"field" %></span>
<span><br>
詳細
<%= f.text_field :body, class: "form-control", placeholder: "タイトルの詳細を記入してください" %>
</span>
<div class="modal-footer">
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.submit "編集する", class: "btn btn-primary" %>
<button type="button" class="btn btn-default" data-dismiss="modal">閉じる</button>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
<% end %>
//updateした内容を差し替え
$('#inputEditForm').html('<%= escape_javascript(render("events/edit", events: @events)) %>');
//モーダル背景画面を消す
$('.modal-backdrop').remove();
// フルカレンダー を一度消しもう一度表示
$('#calendar').fullCalendar('refetchEvents')
最後に
最後までご覧いただきありがとうございます。
初学者ですので間違っていたり、分かりづらい部分もあるかと思います。
何かお気付きの点がございましたら、お気軽にコメントいただけると幸いです。
参考
公式ドキュメント
https://fullcalendar.io/
[Rails]FullcalendarのイベントをDBに保存・編集
https://qiita.com/ShoutaWATANABE/items/3d0cddafadb4f275991e