CodeCharge Studio
search Register Login  

Web Reporting

Visually create Web Reports in PHP, ASP, .NET, Java, Perl and ColdFusion.
CodeCharge.com

YesSoftware Forums -> CodeCharge Studio -> PHP

 Recurring Events in a Calendar Control Part II[TIP]

Print topic Send  topic

Author Message
mentecky

Posts: 321
Posted: 06/02/2008, 6:54 PM

This tip is a continuation of a solution I presented in another thread: http://forums.codecharge.com/posts.php?post_id=95561

I suggest reading that thread first because it defines the tables and strategy for making one single event record repeat. That method works fine if you are querying a single date, but how do you list events that occur between two dates? I recently added this function to my community web site at http://www.meetwny.com/chat_month_view.php?chat_roomsDate=2008-05

What you see there is the result of only 7 records. What we need to do is build a query that spans all dates displayed in the calendar.

OK, first create a page and add a Calendar using the builder. On the data source page open Query Builder. Select your table that holds the recurring events, in my case chat_rooms. In the top left change the type to SQL.

Now we have to build a SQL statement that will return a dataset in the format we want. What we are doing differently here is we won't be specifying any parameters. We will deal with those later in the code. My SQL statement looks like this:

SELECT chat_rooms.*, chat_types.chat_type AS chat_types_desc, e.chat_date as chat_date   
FROM chat_rooms INNER JOIN chat_types ON  
chat_rooms.chat_type = chat_types.chat_type_id,  
(SELECT chat_date FROM  
   (  
	 SELECT DATE('2008-01-01') as chat_date   
	 UNION  
                      SELECT DATE('2008-01-02') as chat_date   
	 UNION  
                      SELECT DATE('2008-01-03') as chat_date   
	 UNION  
                      SELECT DATE('2008-01-04') as chat_date   
  ) d  
) e  
  
WHERE chat_rooms.chat_start_date <= e.chat_date  
AND chat_rooms.chat_end_date >= e.chat_date  
AND ((( chat_types.chat_type_id = 11  
OR chat_types.chat_type_id = 10 ))  
OR ( chat_types.chat_type_id = 9  
AND ( 1 = DAYOFWEEK(e.chat_date)  
OR 7 = DAYOFWEEK(e.chat_date) ))  
OR ( chat_types.chat_type_id = 8  
AND 1 <> DAYOFWEEK(e.chat_date)  
AND 7 <> DAYOFWEEK(e.chat_date) )  
OR chat_types.chat_type_id = DAYOFWEEK(e.chat_date) )   
ORDER BY chat_date, chat_start  

If you got my first example running you will recognize the query with a few differences. The SELECT statements with the union returns a table, aliased as "e", of dates. Also, in the where clause anywhere we tested for a date the parameter has been replaced with e.chat_date. Everything else is the same as the previous project. So, you can use the query that works for your implementation as a basis. When you get this right you should be able to click the "Show Data" button on the tool bar and get a resulting table and no errors.

Save your query and finish the builder as you normally would. Remember, chat_date will be your date value for the builder and start_time will be the time. Also, select Time stored in separate field.

Now the FUN part! Click your Calendar Control and in events add code to Before Execute Select. The following is the code I added:

   // Retrieve the start and end dates for the calendar  
   $first_dt = $chat_rooms->StartDate;  
   $last_dt = $chat_rooms->EndDate;  
   $first_ts = $first_dt[ccsTimestamp];  
   $last_ts = $last_dt[ccsTimestamp];  
  
   // Convert to MySQL dates  
   $this_date = date("Y-m-d", $first_ts);  
   $last_date = date("Y-m-d", $last_ts);  
  
   // We're building a totally new SQL statement here  
   // NOTE: The extra spaces at the end of lines are important!  
    $SQL = "SELECT chat_rooms.*, chat_types.chat_type AS chat_types_desc, e.chat_date as chat_date ";  
    $SQL .= "FROM chat_rooms INNER JOIN chat_types ON ";  
    $SQL .= "chat_rooms.chat_type = chat_types.chat_type_id, ";  
    $SQL .= "(SELECT chat_date FROM ";  
    $SQL .= "   (";  
  
    // Start dayoffset at 0  
   $dayoffset = 0;  
  
   // Here's the creative part. We're building a bunch of SELECT statements  
   // that will return a list of dates for each day on our calendar.  
   // The resulting SQL will look like this:  
   //  
   // SELECT DATE('2008-01-01') as chat_date  
   // UNION  
   // SELECT DATE('2008-01-02') as chat_date  
   // UNION  
   // .  
   // .  
   // .  
   // SELECT DATE('2008-01-31') as chat_date  
   //  
   // The resulting table is aliased as "e" for use in the WHERE clause  
   while (strtotime($this_date) <= strtotime($last_date))  
   {  
      $SQL .= "	 SELECT DATE('$this_date') as chat_date ";  
      
      if (strtotime($this_date) < strtotime($last_date))  
      {  
         $SQL .= "	 UNION ";  
       }  
  
       // Increment the dayoffset  
      $dayoffset++;  
      $this_date = date("Y-m-d", mktime ($first_dt[ccsHour], $first_dt[ccsMinute], $first_dt[ccsSecond], $first_dt[ccsMonth], $first_dt[ccsDay] + $dayoffset, $first_dt[ccsYear]));  
   }  
	     
   $SQL .= "	 ) d) e ";  
  
   // Add the WHERE clause. This is similar to the previous Recurring Date code  
   // except we are using "e.chat_date" for all the date tests  
   $SQL .= "WHERE chat_rooms.chat_start_date <= e.chat_date ";  
   $SQL .= "AND chat_rooms.chat_end_date >= e.chat_date ";  
   $SQL .= "AND ((( chat_types.chat_type_id = 11 ";  
   $SQL .= "OR chat_types.chat_type_id = 10 )) ";  
   $SQL .= "OR ( chat_types.chat_type_id = 9 ";  
   $SQL .= "AND ( 1 = DAYOFWEEK(e.chat_date) ";  
   $SQL .= "OR 7 = DAYOFWEEK(e.chat_date) )) ";  
   $SQL .= "OR ( chat_types.chat_type_id = 8 ";  
   $SQL .= "AND 1 <> DAYOFWEEK(e.chat_date) ";  
   $SQL .= "AND 7 <> DAYOFWEEK(e.chat_date) ) ";  
   $SQL .= "OR chat_types.chat_type_id = DAYOFWEEK(e.chat_date) ) ";   
   $SQL .= "ORDER BY chat_date, chat_start";  
  
    // Set the new SQL statement  
   $chat_rooms->DataSource->SQL = $SQL;  
  
   // This probably isn't necessary but it makes sense. Clear our old ORDER BY  
   $chat_rooms->DataSource->Order = "";  

That code builds the exact same SQL statement that we put in the Calendar Builder except it builds the "e" table based on the begin and end dates of the Calendar Control.

That's about it, format your Calendar as needed. I did have to add formats to the date and time labels, but after that it works great.

I hope this helps!

Rick
_________________
http://www.ccselite.com
View profile  Send private message
mentecky

Posts: 321
Posted: 06/02/2008, 8:44 PM

OK Walter.... now it's your turn since I put the code up! ;-)

Rick
_________________
http://www.ccselite.com
View profile  Send private message

Add new topic Subscribe to topic   


These are Community Forums for users to exchange information.
If you would like to obtain technical product help please visit http://support.yessoftware.com.

MS Access to Web

Convert MS Access to Web.
Join thousands of Web developers who build Web applications with minimal coding.

CodeCharge.com

Home   |    Search   |    Members   |    Register   |    Login


Powered by UltraApps Forum created with CodeCharge Studio
Copyright © 2003-2004 by UltraApps.com  and YesSoftware, Inc.