<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>@Lathi.net: More Calendar Fun</title>
    <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>On Life, Fatherhood, Christianity, and Computers</description>
    <item>
      <title>More Calendar Fun</title>
      <description>&lt;p&gt;So I had what I thought was a pretty workable &lt;a href="http://blog.lathi.net/articles/2005/09/09/dynamic-calendar-and-appointments"&gt;calendar component&lt;/a&gt; ready for my client.  Once she had a look at it, she didn&amp;#8217;t like it.  Turns out she&amp;#8217;s a more &amp;#8220;visual&amp;#8221; person.  That means she wants to see the calendar events on the day they occur inside the calendar.  What I had given her was pretty much just a daily view using &lt;a href="http://www.dynarch.com/projects/calendar/"&gt;jscalendar&lt;/a&gt; as the main navigation to change days.&lt;/p&gt;


	&lt;p&gt;Before I go on, I&amp;#8217;d like to thank &lt;a href="http://onestepback.org/"&gt;Jim Weirich&lt;/a&gt; for pointing out &lt;a href="http://runt.rubyforge.org"&gt;Runt&lt;/a&gt;, which is a temporal expression library.  It&amp;#8217;s basically exactly what I was working towards with my &lt;code&gt;TimeX&lt;/code&gt; class.  I haven&amp;#8217;t switched to using runt just because what I have works so far.  I may still switch in the future.  I &lt;em&gt;know&lt;/em&gt; I have other stuff that can use that logic.  I&amp;#8217;m just not sure about rewriting what I already have at this point.&lt;/p&gt;


	&lt;p&gt;As it turns out though, building my own monthy calendar grid was fairly simple.  So simple, I&amp;#8217;ll go ahead and include the code for it here:&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
  def calendar_grid(year, month)
    # We're going to build a 5x7 grid of calendar dates
    first_day = Date.new(year.to_i, month.to_i, 1)
    # finding the last day of the month is a little clumsy
    last_day = (month == 12) ? Date.new(year + 1, 1,1) - 1 : 
       Date.new(year,month + 1, 1) - 1
    grid = Array.new
    week = 0
    # start on the beginning of the week of the first of the month
    current_day = first_day - first_day.wday
    while current_day &amp;lt;= last_day
      grid[week] = Array.new
      0.upto(6) do |wday| 
        grid[week] &amp;lt;&amp;lt; current_day
        current_day = current_day + 1
      end
      week = week + 1
    end
    return grid
  end
&lt;/pre&gt;

	&lt;p&gt;&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Just displaying the grid is also only about 10 lines of &lt;acronym title="Embedded Ruby Hyper Text Markup Language"&gt;RHTML&lt;/acronym&gt;.  I then went on to include the events on each day and add links for managing those events.  Boy did the page get heavy fast!&lt;/p&gt;


	&lt;p&gt;I was happy with the quick-post logic for adding new categories in &lt;a href="http://typo.leetsoft.com/"&gt;typo&lt;/a&gt;.  I wanted to use that for adding an appointment for each day.  I already had that logic for my previous daily view, and only had to do minor changes to put the &lt;code&gt;Effect.BlindUp&lt;/code&gt; form on every day in the calendar.&lt;/p&gt;


	&lt;p&gt;The new event form is a little large.  It&amp;#8217;s got two select boxes with all the time increments from 7am to 10pm in 15 minute steps.  Adding a &amp;#8220;new event&amp;#8221; link to every day in the 5&amp;#215;7 grid put a lot of weight on the page.  Don&amp;#8217;t forget that for every day in the grid I have a pretty crude &lt;code&gt;find_by_date&lt;/code&gt; method to scan the &lt;code&gt;TimeExpression&lt;/code&gt; table filtering out any that don&amp;#8217;t occur on the day in question.&lt;/p&gt;


	&lt;p&gt;The page isn&amp;#8217;t too bad.  Even running on webrick in development mode, it loads in a few seconds.  Hmm, here&amp;#8217;s all these events listed.  I need to edit them.  OK, I&amp;#8217;ll just adapt the quick-post forms for adding a new event to edit the listed event.  For an even that repeats three times a week, that&amp;#8217;s 15 more somewhat large forms that are embedded and hidden on the page.  Plus, more logic to evaluate the event object to build the form.&lt;/p&gt;


	&lt;p&gt;So, with just a few events I&amp;#8217;ve got like 50 copies of essentially the same form.  That&amp;#8217;s a lot of duplication!  The page can easily come in at over 200K.  That&amp;#8217;s a lot to download and a lot to generate with &lt;acronym title="Embedded Ruby"&gt;ERB&lt;/acronym&gt;.  I&amp;#8217;m not sure what to do about it though short of not embedding all those forms.  If I had to reload a new page for each of those &amp;#8220;edit&amp;#8221; and &amp;#8220;add&amp;#8221; links rather than embed the form, the whole app may actually be faster.  I&amp;#8217;d lose a little cool factor of using the &lt;code&gt;Effect.BlindUp&lt;/code&gt;; but I&amp;#8217;m not so sure my client cares about that.&lt;/p&gt;


	&lt;p&gt;While I&amp;#8217;m at it, I still haven&amp;#8217;t gotten the sophisticated &amp;#8220;delete&amp;#8221; operation done.  I can delete a whole event; but I can&amp;#8217;t do nice things like &amp;#8220;delete only this one occurance of the event&amp;#8221; or &amp;#8220;delete all future events&amp;#8221;.  The controller logic is simple. The model already supports it.  To keep the UI consistent with what I&amp;#8217;m doing now though I&amp;#8217;d have to embed another form for every event with the radio buttons for the choices.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll get this worked out today.  I&amp;#8217;ve got another demo tonight with the client.&lt;/p&gt;</description>
      <pubDate>Tue, 13 Sep 2005 12:15:22 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d49eda59c18c24dddbfdb31ddb5e99cc</guid>
      <author>Doug</author>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun</link>
      <category>Programming</category>
      <category>Ruby on Rails</category>
      <category>Rails</category>
      <category>Calendars</category>
    </item>
    <item>
      <title>"More Calendar Fun" by Doug</title>
      <description>&lt;p&gt;Thanks for your ideas, Pat.  As it turns out I&amp;#8217;ve mostly addressed this.  I have an exception list of dates the TimeExpression doesn&amp;#8217;t occur on.&lt;/p&gt;


	&lt;p&gt;However, I like your idea of using negative TimeExpressions.  My client wants the ability to block out whole days or weeks.  That could be done pretty easily with a &amp;#8220;negative&amp;#8221; TimeExpression.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Dec 2005 08:36:30 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:c4f682d5-d6f1-4459-8f19-a679d65d2c66</guid>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun#comment-112</link>
    </item>
    <item>
      <title>"More Calendar Fun" by Pat</title>
      <description>&lt;p&gt;Actually I think a better structure for this would be to have an Event class (perhaps Appointment in your case) that has properties like a description, a place, some details about the person you&amp;#8217;re meeting.  Then it also has a bunch of TimeXes, which can be either positive or negative.  A positive TimeX just means that the event occurs on that time, and a negative TimeX means that..it doesn&amp;#8217;t :)  Essentially the same as a mask.  So if an Event has a positive TimeX matching MWF and a negative TimeX that matches Wednesdays in January, the Event would occur every MWF of the year except for Wednesdays in January.  Whether it&amp;#8217;s positive or negative is would be a simple boolean flag.  Then you implement Event#occursOn? to look if it matches any negative TimeXes, and if it matches none check to see if it matches any of the positive TimeXes.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Dec 2005 06:36:06 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:da7eb34a-b461-433b-879e-c644c8dfeb0e</guid>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun#comment-111</link>
    </item>
    <item>
      <title>"More Calendar Fun" by Pat</title>
      <description>&lt;p&gt;Not sure if you&amp;#8217;re still working on this or not, but I had an idea for how to delete an occurrence of an event.  You could use masks.&lt;/p&gt;


	&lt;p&gt;Any mask would just be another TimeX, and where they intersect is an instance of the event that&amp;#8217;s deleted.  Let&amp;#8217;s say I create a TimeX that matches MWF to represent the days I go out biking.  Every three weeks I take the Friday off.  Create another TimeX to represent each third Friday and assign that as a mask to the main TimeX object.  Change your TimeX matching method to exclude the times that fall within a mask, so when you do something like timex.match(time.now), if time.now falls within one of the masks then match returns false.&lt;/p&gt;


	&lt;p&gt;Assigning a mask to another object is pretty simple.  OfficeHours has_many :masks class =&amp;gt; &amp;#8220;OfficeHour&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Hopefully I&amp;#8217;ve made some sense here.  I&amp;#8217;ll check back in a few days to see if you like the suggestion or have any questions about it.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Dec 2005 06:22:55 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:9e922592-f352-4e6d-b001-1cec0efebb45</guid>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun#comment-110</link>
    </item>
    <item>
      <title>"More Calendar Fun" by Doug</title>
      <description>&lt;p&gt;That&amp;#8217;s be sweet if I had the JS chops to pull it off.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Sep 2005 09:39:33 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1676a1fa-b7da-470b-844c-3fc7bf062332</guid>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun#comment-37</link>
    </item>
    <item>
      <title>"More Calendar Fun" by John Wilger</title>
      <description>&lt;p&gt;What if, instead of duplicating the same form multiple times, you just put one instance of the form in the code and then used CSS/Javascript to position it close to the &amp;#8220;edit&amp;#8221; or &amp;#8220;new&amp;#8221; links? Then you only have one &amp;#8220;new event&amp;#8221; form plus one &amp;#8220;edit event&amp;#8221; form for each unique event.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Sep 2005 08:56:33 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:07b2628e-fccd-4285-b577-7926c11422fa</guid>
      <link>http://blog.lathi.net/articles/2005/09/13/more-calendar-fun#comment-36</link>
    </item>
  </channel>
</rss>

