datepickerの実装
これは先の記事に詳しく書いている。
viewファイルに部分プレート追加
app/views/reports/index.html.erb
<input type="hidden" id="reported_array" value="<%= @reports %>">
<input type="hidden" id="reported" value="<%= @reported_days %>">
<div id="datepicker-report"></div>
<div class="col-lg-7">
<div id="report_list">
<%= render partial: 'reportlist' %>
</div>
</div>
app/views/reports/_reportlist.html.erb
<% @reports.each.with_index(1) do |report, i| %>
<% report.report_items.each do |item| %>
<%= item.content %>
<% end %>
<%= report.content %>
<% end %>
<nav aria-label="Page navigation example">
<ul class="pagination">
<%= paginate @reports %>
</ul>
</nav>
細かいdivタグは排除している。レポートの中身を部分テンプレートに格納している。
JSファイルの書き換え
app/javascript/home.js
$(document).on("page:load turbolinks:load", function() {
// 略
let reportedDays_json = document.getElementById('reported').value;
if (reportedDays_json !== null) {
let reportedDays = JSON.parse(reportedDays_json);
$( "#datepicker-report" ).datepicker({
beforeShowDay: function(date) {
// 略
},
onChangeMonthYear: function(year, month, inst) {
$.ajax({
type: 'GET',
url: '/reports/filter_report',
data: { 'year' : year, 'month' : month },
dataType: 'script'
})
.done(function(data){
// なし
})
}
});
}
このようになる。jQuery UIのdatepickerのonChangeMonthYear
オプションを利用することで、カレンダーの月が変更したときの関数を定義している。
この関数ではyearとmonthの値を取得し、Ajaxを使用してサーバーにデータを送信している。
ルーティング設定
以下のように書き換える。
config/routes.rb
Rails.application.routes.draw do
# 略
resources :reports do
collection do
get 'filter_report'
end
end
# 略
end
collectionルーティングを使用し、idを伴わないパスを認識させる。これによってjsに書いた、url: '/reports/filter_report'
が生きてくる。
コントローラーの変更
以下のようにする。
app/controllers/reports_controller.rb
class ReportsController < ApplicationController
# 略
def filter_report
year = filter_params[:year].to_i
month = filter_params[:month].to_i
target_month = Date.new(year,month)
target_day = target_month.end_of_month
@reports = get_filterd_report.where('reported_on < ?', target_day)
respond_to do |format| # リクエスト形式によって処理を切り分ける
format.html { redirect_to :root } # html形式の場合
format.js
format.json { render json: @reports } # json形式の場合
end
end
# 略
end
@reports
に 選択した月とその月以前のレポートデータを入れる。ajax通信で呼ばれると、次にfilter_report.js.erb
ファイルを呼び出す。
JSファイルによるページの一部書き換え
app/views/reports/filter_report.js.erb
if (typeof reports === 'undefined'){
let reports = document.querySelector("#report_list");
reports.innerHTML = '<%= j render 'reportlist' %>';
} else {
reports = document.querySelector("#report_list");
reports.innerHTML = '<%= j render 'reportlist' %>';
}
viewファイルの中からid report_list
の要素を探す。あったら、その中の部分テンプレートを更新させる。
おわり
すこしややこしい話になったが、この流れで実装させることができた。