LoginSignup
0
0

More than 1 year has passed since last update.

datepickerで選択した月以前のデータを、非同期で表示させる

Posted at

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の要素を探す。あったら、その中の部分テンプレートを更新させる。

おわり

 すこしややこしい話になったが、この流れで実装させることができた。

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