SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    mouse monkey
    Join Date
    Dec 1999
    Location
    UK
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [rails] Group By Date (Outlook Style)

    I currently use the following code (have removed formatting) in my view to group results by dates.

    Code:
    <% current_date = nil -%>
    <% for item in @items -%>
    	
    	<% item_published_formatted = item.published.strftime('%d %B %Y') %>
    
    
    	<% if item_published_formatted != current_date  -%>
    		<%= item_published_formatted  %>
    	<% end -%>	
    
    
    	<%= item.title -%>
    	 
    	<% current_date = item_published_formatted -%>
    <% end -%>
    This outputs something like:

    04 April 2006
    Lorium ipsum
    An item title
    And another

    03 April 2006
    Item from yesterday
    Title



    I would like to group the items by date, similarly how Outlook 2003 works. So would look something like:

    Today
    ~items~
    Yesterday
    ~items~
    Sunday
    ~items~
    Last Week
    ~items~
    Two Weeks Ago
    Three Weeks Ago
    Last Month
    Two Months Ago



    Any ideas on the best way to achieve this?

    Thanks,
    Last edited by Fletch; Apr 4, 2006 at 10:37. Reason: Spelling mistake

  2. #2
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,235
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    There might be a better way to achieve this, but this is what I got working:
    Code:
    temp_date = nil 
    headline = nil
    temp_headline = nil
     for item in @items 
     	temp_date = item.published
    
    		if (temp_date > 1.day.ago)
    			temp_headline = 'Today'
    		elsif (temp_date <= 1.day.ago && temp_date > 2.days.ago)
    			temp_headline = 'Yesterday'
    		elsif (temp_date <= 2.days.ago && temp_date > 1.week.ago)
    			temp_headline = Date::DAYNAMES[item.published.wday]
    		elsif (temp_date <= 1.week.ago && temp_date > 2.weeks.ago)
    			temp_headline = 'Last Week'
    		elsif (temp_date <= 2.weeks.ago && temp_date > 3.weeks.ago)
    			temp_headline = '2 Weeks Ago'
    		elsif (temp_date <= 3.weeks.ago && temp_date > 4.weeks.ago)
    			temp_headline = '3 Weeks Ago'
    		elsif (temp_date <= 1.month.ago && temp_date > 2.months.ago)
    			temp_headline = 'Last Month'
    		else
    			temp_headline = 'Older'
    		end
    	
    		if temp_headline != headline
    			headline = temp_headline
                             #print out headline here
                   end
    #print out records/object attributes here
     end

  3. #3
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not tested, but looks a little bit nicer:

    Code:
    headlined = Hash.new([])
    
    for item in list
        headlined[case item.published
                  when 0.days.ago..1.day.ago
                    "Today"
                  when 1.day.ago..2.days.ago
                    "Yesterday"
                  when 2.days.ago..1.week.ago
                    Date.DAYNAMES[item.published.wday]
                  when 1.week.ago..2.weeks.ago
                    "Last week"
                  when 2.weeks.ago..3.weeks.ago
                    "2 weeks ago"
                  when 3.weeks.ago..4.weeks.ago
                    "3 weeks ago"
                  when 1.month.ago..2.months.ago
                    "Last month"
                  else
                    "Older"
                  end] += [item]
    end
    headlined SHOULD be a hash containing the headline as the key and an array of objects as value. Note that if you do headlined["some nonexisting key"] you'll get an empty array ([]).

  4. #4
    mouse monkey
    Join Date
    Dec 1999
    Location
    UK
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you both for your help, really good starting point!

    I've made a slight change; because "last week" is not strictly 7 days ago. For example today is Wednesday, so I would class the previous Saturday as "last week" even though it is only 4 days ago.

    So I've declared
    Code:
    current_wday = Time.now.wday
    and changed the 3rd criteria in the if statement to:
    Code:
    temp_date <= 2.days.ago && temp_date > current_wday.days.ago

  5. #5
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,235
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Nice cleanup job Fenrir2

    I was trying to get a case statement going initially when I was trying to use Date objects but it wasn't working for me. Your approach looks great though.

  6. #6
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ruby 1.9 has a neat Enumerable#group_by:

    Code:
    headlined = list.group_by{|item|
              case item.published
                  when 0.days.ago..1.day.ago
                    "Today"
                  when 1.day.ago..2.days.ago
                    "Yesterday"
                  when 2.days.ago..1.week.ago
                    Date.DAYNAMES[item.published.wday]
                  when 1.week.ago..2.weeks.ago
                    "Last week"
                  when 2.weeks.ago..3.weeks.ago
                    "2 weeks ago"
                  when 3.weeks.ago..4.weeks.ago
                    "3 weeks ago"
                  when 1.month.ago..2.months.ago
                    "Last month"
                  else
                    "Older"
                  end
    }


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •