LoginSignup
6
7

More than 5 years have passed since last update.

Railsでカレンダー自作途中(ClndrのCSSを利用)

Last updated at Posted at 2015-12-28

簡素なカレンダーのライブラリが欲しくて、clndr-railsを試したがひと月毎にデータ取得するにはjsonでやり取りしないといけなかったり、Eventの種類わけてCSS当てたい等いろいろ弄くって拡張難しそうだったのでベースのCSSだけ残して後は自作した方が良い気がしたのでそのメモ

Clndr

gem 'clndr-rails'
application.css
*= require clndr-rails

Model

calendar.rb
class Calendar
  attr_accessor :current_month_days, :prev_month_days, :next_month_days, :start_day

  def initialize(date, start_day: :sunday)
    self.current_month_days = date.all_month
    self.prev_month_days    = date.prev_month.all_month
    self.next_month_days    = date.next_month.all_month
    self.start_day = start_day
  end

  def to_partial_path
    'calendar/calendar'
  end


  def headers
    %w(Sun Mon Tue Wed Thu Fri Sat)
  end

  def title
    "#{current_month_days.first.month} #{current_month_days.first.year}"
  end


  def days
    days = current_month_days.to_a
    days.concat(prev_month_days_in_first_week)
    days.concat(next_month_days_in_last_week)

    days.sort.map{|date| add_singleton_methods(date) }
  end


  def prev_month_path
    switch_month_path(:prev)
  end

  def next_month_path
    switch_month_path(:next)
  end


private

  def prev_month_days_in_first_week
    (current_month_days.first.beginning_of_week(start_day)...current_month_days.first).reject{|date|
      date.in?(current_month_days)
    }
  end


  def next_month_days_in_last_week
    (current_month_days.last..current_month_days.last.end_of_week(start_day)).reject {|date|
      date.in?(current_month_days)
    }
  end


  def add_singleton_methods(date)
    is_prev_month, is_next_month = prev_month_days.include?(date), next_month_days.include?(date)

    date.define_singleton_method(:prev_month?){ is_prev_month }
    date.define_singleton_method(:next_month?){ is_next_month }

    date
  end


  def switch_month_path(type)
    target_date =
      case type
      when :prev then prev_month_days.first
      when :next then next_month_days.first
      end

    Rails.application.routes.url_helpers.calendar_path(
      month: target_date.month,
      year:  target_date.year
    )
  end
end

to_partial_pathを定義することでrendar @calendarで描画できる

Controller

calendar_controller.rb
def index
  @calendar = Calendar.new(current_date)
end

View

calndar/index.html.erb
<%= render @calendar %>
clandar/_calendar.html.erb
<div id="my-clndr" class="clearfix full-clndr-template">
  <div class="clndr">
    <div class="clndr-controls">
      <%= link_to calendar.prev_month_path do %>
        <div class="clndr-previous-button">&lt;</div>
      <% end %>
      <%= link_to calendar.next_month_path do %>
        <div class="clndr-next-button">&gt;</div>
      <% end %>
    <div class="current-month"><%= calendar.title %></div>
  </div>
  </div>
  <div class="clndr-grid full">
    <div class="days-of-the-week clearfix">
      <% calendar.headers.each do |day_of_week| %>
        <div class="header-day"><%= day_of_week %></div>
      <% end %>
    </div>
    <div class="days">
      <% calendar.days.each do |date| %>
        <%= content_tag :div,
        class: "day #{'past' if date.past?} \
          #{'prev-month adjacent-month' if date.prev_month?} \
          #{'next-month adjacent-month' if date.next_month?} \
          calendar-dow-#{date.wday}".squish! do %>
          <span class="day-number"><%= date.day %></span>
        <% end %>
      <% end %>
    </div>
  </div>
</div>

とりあえず基本的なとこだけ出来た
スクリーンショット 2015-12-29 1.54.50.png

あとはここから見た目弄くったりeventsをつっこんだり。

6
7
4

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