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

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

### Clndr
+ [Clndr](https://github.com/kylestetz/CLNDR)
+ [clndr-rails](https://github.com/sedx/clndr-rails)

```Gemfile
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](https://qiita-image-store.s3.amazonaws.com/0/3914/cd33d2d8-2e54-ae9e-aba9-a4df306e9a93.png)

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