LoginSignup
36
48

More than 1 year has passed since last update.

[Rails]FullCalenderでカレンダー機能の実装

Last updated at Posted at 2020-02-18

実装すること

①マイページで予定管理ができるようにする
②日付をクリックで予定の作成・編集をできるようにする
※Userモデル等は作成した前提で進めていきます。

FullCalenderとは

オープンソースのカスタマイズ可能なjqueryのカレンダーライブラリです。
上手く活用することで、カレンダーのスクラッチ開発をせずにリッチなカレンダーを表示できます。

ER図

calenderER図.png

モデルの作成

$ rails g model Event title:string body:text disp_flg:boolean start:datetime end:datetime allDay:string

アソシエーションの確認

app/models/user.rb
class User < ApplicationRecord

    has_many :events

end
app/models/event.rb
class Event < ApplicationRecord

    belongs_to :user

end

ダウンロード

FullCalenderの公式ドキュメントからダウンロードし、zipを解凍します。
https://fullcalendar.io/

Gemの追加

Gemfile.
gem 'jquery-rails', '4.3.3'
gem 'fullcalendar-rails'
gem 'momentjs-rails'
$ bundle inatall

読み込み

application.htmlのhead内で読み込みます。

app/views/layouts/application.html
<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>
app/assets/javascripts/application.js
//= require jquery
//= require moment
//= require fullcalendar

表示する(マイページ)

カレンダー.png カレンダー登録.png

コントローラー

app/contorollers/users_contoroller.rb
  def show
    @user = User.find(params[:id])
    @events = Event.where(user_id: @user.id)
    @event = Event.new
  end
app/controllers/events_controller.rb
    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>でカレンダーを表示しています。
・予定を編集するときのモーダル内容はパーシャルにします。

app/views/users/show.html

<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>

app/views/events/create.js
//フォームを空にする
$('input[type="text"]').val('');
//モーダルを消す
$('#inputScheduleForm').modal('hide');
//作成した予定を差し替える
$('#inputEditForm').html('<%= escape_javascript(render("events/edit", events: @events )) %>');
// フルカレンダー を一度消しもう一度表示
$('#calendar').fullCalendar('refetchEvents')

予定を編集する

app/views/events/_edit.html
<% 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 %>
app/views/events/update.js
//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

36
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
48