excid3 / simple_calendar

A wonderfully simple calendar gem for Rails
http://excid3.github.io/simple_calendar
MIT License
1.56k stars 267 forks source link

Weekly calendar view #233

Closed stevesizer closed 3 years ago

stevesizer commented 4 years ago

Hi Chris,

I looking at using this gem for a project I am currently working on and all the events are week long events. What I wanted to do is render a calendar using weeks instead of days. Please see image attached. Is this possible?

Thanks in advance.

Screenshot 2020-04-23 at 13 43 52
excid3 commented 4 years ago

Yep. You'd want to build a custom Calendar object to do it, that way you can control the dates that are rendered and how many are in a row.

It's pretty simple: https://github.com/excid3/simple_calendar#custom-calendars

excid3 commented 4 years ago

Something like this would generate a calendar like your screenshot.

Take the date from the URL, use it as the starting week, then add 15 entries by adding 1 week each time.

class WeekCalendar < SimpleCalendar::Calendar
  private

    def date_range
      dates = [start_date.beginning_of_week]
      15.times do
         dates << (dates.last + 1.week)
      end
    end
end
stevesizer commented 4 years ago

Excellent i'll give it ago now and see how far I get. :)

stevesizer commented 4 years ago

Error undefined method `slice' for 1:Integer

so when I check date_range it only the value 1

View <%= SimpleCalendar::WeeklyCalendar.new(self, {}).render do |date| %> <%= date %> <% end %>

Class class SimpleCalendar::WeeklyCalendar < SimpleCalendar::Calendar private

def week_number
  format = (Date.beginning_of_week == :sunday) ? "%U" : "%V"
  start_date.beginning_of_week.strftime(format).to_i
end

def number_of_weeks
  options.fetch(:number_of_weeks, 1)
end

def end_week
  week_number + number_of_weeks - 1
end

def date_range
  dates = [start_date.beginning_of_week]
  number_of_weeks.times do
     dates << (dates.last + 1.week)
  end
end

end

Partial

<%= date_range %> <% date_range.slice(0, 7).each do |day| %> <% end %> <% date_range.each_slice(7) do |week| %> <% week.each do |day| %> <%= content_tag :td, class: calendar.td_classes_for(day) do %> <% if defined?(Haml) && respond_to?(:block_is_haml?) && block_is_haml?(block) %> <% capture_haml(day, sorted_events.fetch(day, []), &block) %> <% else %> <% block.call day, sorted_events.fetch(day, []) %> <% end %> <% end %> <% end %> <% end %>
<%= t('date.abbr_day_names')[day.wday] %>
excid3 commented 4 years ago

Return the array in your date_range method. Right now you're returning the value of the times loop. That should do the trick.

stevesizer commented 4 years ago

Have you ever had any weird things going on between environments? I just i had everything sorted and for some reason on my staging site its not working.

first image is local and displays 21 weeks in the calendar. The second screenshot is on the staging site.

Screenshot 2020-04-29 at 15 41 46 Screenshot 2020-04-29 at 15 41 20

_weekly_calendar.html.erb

<%= date_range %> <%= calendar.options %> <% date_range.each_slice(4) do |week| %> <% week.each do |day| %> <%= content_tag :td, class: calendar.td_classes_for(day) do %> <% if defined?(Haml) && respond_to?(:block_is_haml?) && block_is_haml?(block) %> <% capture_haml(day, sorted_events.fetch(day, []), &block) %> <% else %> <% block.call day, sorted_events.fetch(day, []) %> <% end %> <% end %> <% end %> <% end %>
DATE
Cycle
OPEX Pain
OPEX Sustain

weekly_calendar.rb class SimpleCalendar::WeeklyCalendar < SimpleCalendar::Calendar private

def week_number
  format = (Date.beginning_of_week == :sunday) ? "%U" : "%V"
  start_date.beginning_of_week.strftime(format).to_i
end

def number_of_weeks
  options.fetch(:number_of_weeks, 1)
end

def end_week
  week_number + number_of_weeks - 1
end

def date_range
  dates = [start_date.beginning_of_week]
  i = 1
  while i < number_of_weeks
     dates << (dates.last + 1.week)
     i = i + 1
  end

  return dates
end

end