To address this problem, you’ll need to adjust the date by the timezone offset using two built-in Date object methods: .setMinutes and .getTimezoneOffset.. Using .setMinutes, you can add
Trang 1"deserialize" : function(str){ },
"urldecode" : function(str) { }
};
Fixing Timezone Inconsistencies
You aren’t passing a time or timezone to the Date object, so that object will default to midnight
Greenwich Mean Time (00:00:00 GMT) This can cause your dates to behave unexpectedly for users in
different timezones To address this problem, you’ll need to adjust the date by the timezone offset using
two built-in Date object methods: setMinutes() and getTimezoneOffset()
The return value of getTimezoneOffset() is the difference in the number of minutes between GMT and the user’s timezone For instance, the return value of getTimezoneOffset() in Mountain Standard Time (-0700) is 420
Using setMinutes(), you can add the value of the timezone offset to the Date object, which will
return the date to midnight on the given day, no matter what timezone the user is in
You can make that adjustment using the following bold code:
fx = {
"initModal" : function() { },
"boxin" : function(data, modal) { },
"boxout" : function(event) { },
// Adds a new event to the markup after saving
"addevent" : function(data, formData){
// Converts the query string to an object
var entry = fx.deserialize(formData),
// Makes a date object for current month
cal = new Date(NaN),
// Makes a date object for the new event
event = new Date(NaN),
// Extracts the event day, month, and year
date = entry.event_start.split(' ')[0],
// Splits the event data into pieces
edata = date.split('-'),
// Extracts the calendar month from the H2 ID
cdata = $("h2").attr("id").split('-');
// Sets the date for the calendar date object
cal.setFullYear(cdata[1], cdata[2], 1);
// Sets the date for the event date object
event.setFullYear(edata[0], edata[1], edata[2]);
// Since the date object is created using
Trang 2// GMT, then adjusted for the local timezone,
// adjust the offset to ensure a proper date
event.setMinutes(event.getTimezoneOffset());
},
"deserialize" : function(str){ },
"urldecode" : function(str) { }
};
Ensuring the Event Occurs in the Current Month
Your next step is to set up a conditional statement that ensures that only events that belong on the calendar are appended If both the year and month match between the current calendar month and the
event date, you can extract the day of the month using the Date object’s getDay() method To work
properly with the next step, which adds leading zeroes to single-digit dates, you also need to convert this
value to a string, which is accomplished by passing the value to String()
The day of the month needs to have a leading zero to properly match the calendar For example, if the returned date is only one digit, you prepend a leading zero to the date
Do this by inserting the following bold code:
fx = {
"initModal" : function() { },
"boxin" : function(data, modal) { },
"boxout" : function(event) { },
// Adds a new event to the markup after saving
"addevent" : function(data, formData){
// Converts the query string to an object
var entry = fx.deserialize(formData),
// Makes a date object for current month
cal = new Date(NaN),
// Makes a date object for the new event
event = new Date(NaN),
// Extracts the event day, month, and year
date = entry.event_start.split(' ')[0],
// Splits the event data into pieces
edata = date.split('-'),
// Extracts the calendar month from the H2 ID
cdata = $("h2").attr("id").split('-');
// Sets the date for the calendar date object
cal.setFullYear(cdata[1], cdata[2], 1);
// Sets the date for the event date object
event.setFullYear(edata[0], edata[1], edata[2]);
Trang 3// Since the date object is created using
// GMT, then adjusted for the local timezone,
// adjust the offset to ensure a proper date
event.setMinutes(event.getTimezoneOffset());
// If the year and month match, start the process
// of adding the new event to the calendar
if ( cal.getFullYear()==event.getFullYear()
&& cal.getMonth()==event.getMonth() )
{
// Gets the day of the month for event
var day = String(event.getDate());
// Adds a leading zero to 1-digit days
day = day.length==1 ? "0"+day : day;
}
},
"deserialize" : function(str){ },
"urldecode" : function(str) { }
};
Appending the Event to the Calendar
You’re finally ready to append the new event to the calendar To do so, create a new anchor element,
hide it, set its href attribute, and use the title of the event as the link text
Next, set a one-second delay using delay(1000) and fade in the new event
You can implement this by adding the following code shown in bold:
fx = {
"initModal" : function() { },
"boxin" : function(data, modal) { },
"boxout" : function(event) { },
// Adds a new event to the markup after saving
"addevent" : function(data, formData){
// Converts the query string to an object
var entry = fx.deserialize(formData),
// Makes a date object for current month
cal = new Date(NaN),
// Makes a date object for the new event
event = new Date(NaN),
// Extracts the event day, month, and year
date = entry.event_start.split(' ')[0],
// Splits the event data into pieces
Trang 4edata = date.split('-'),
// Extracts the calendar month from the H2 ID
cdata = $("h2").attr("id").split('-');
// Sets the date for the calendar date object
cal.setFullYear(cdata[1], cdata[2], 1);
// Sets the date for the event date object
event.setFullYear(edata[0], edata[1], edata[2]);
// Since the date object is created using
// GMT, then adjusted for the local timezone,
// adjust the offset to ensure a proper date
event.setMinutes(event.getTimezoneOffset());
// If the year and month match, start the process
// of adding the new event to the calendar
if ( cal.getFullYear()==event.getFullYear()
&& cal.getMonth()==event.getMonth() )
{
// Gets the day of the month for event
var day = String(event.getDate());
// Adds a leading zero to 1-digit days
day = day.length==1 ? "0"+day : day;
// Adds the new date link
$("<a>")
hide()
attr("href", "view.php?event_id="+data)
text(entry.event_title)
insertAfter($("strong:contains("+day+")"))
delay(1000)
fadeIn("slow");
}
},
"deserialize" : function(str){ },
"urldecode" : function(str) { }
}
■ Note The data variable is undefined as of right now You’ll remedy this in the next section
Now, back in the click event handler for the Submit button, modify the success callback of the
$.ajax() function to execute fx.addevent() by using the following bold code:
Trang 5// Edits events without reloading
$(".edit-form input[type=submit]").live("click", function(event){
// Prevents the default form action from executing
event.preventDefault();
// Serializes the form data for use with $.ajax()
var formData = $(this).parents("form").serialize();
// Sends the data to the processing file
$.ajax({
type: "POST",
url: processFile,
data: formData,
success: function(data) {
// Fades out the modal window
fx.boxout();
// Adds the event to the calendar
fx.addevent(data, formData);
},
error: function(msg) {
alert(msg);
}
});
});
Save this file and reload http://localhost/ Bring up the event creation form and create a new event
with the following information:
• Event Title: Addition Test
• Event Start: 2010-01-09 12:00:00
• Event End: 2010-01-09 14:00:00
• Event Description: This is a test of the dynamic addition of new events to the
calendar
Submitting the form causes the modal window to fade out; a second later, the new event title will
fade in on the calendar in the proper place (see Figure 8-2)
Trang 6Figure 8-2 The calendar after the new event is created
Getting the New Event’s ID
Currently, a new event is not viewable without a page refresh after it is created Because the event ID is absent (nothing is returned from a successful event addition), clicking the generated link results in an empty modal window (see Figure 8-3)
Trang 7Figure 8-3 Here the event cannot be loaded because no event ID is available
Modifying the Event Creation Method to Return New Event IDs
To make the event immediately viewable, you only need to make one small adjustment in the Calendar class Open the file (/sys/class/class.calendar.inc.php) and locate the processForm() method
Inside this method, modify the return command to output the ID of the last inserted row using
PDO’s lastInsertId() method:
public function processForm()
{
/*
* Exit if the action isn't set properly
*/
if ( $_POST['action']!='event_edit' )
{
return "The method processForm was accessed incorrectly";
}
Trang 8/*
* Escape data from the form
*/
$title = htmlentities($_POST['event_title'], ENT_QUOTES); $desc = htmlentities($_POST['event_description'], ENT_QUOTES); $start = htmlentities($_POST['event_start'], ENT_QUOTES); $end = htmlentities($_POST['event_end'], ENT_QUOTES);
/*
* If no event ID passed, create a new event
*/
if ( empty($_POST['event_id']) )
{
$sql = "INSERT INTO `events`
(`event_title`, `event_desc`, `event_start`, `event_end`)
VALUES
(:title, :description, :start, :end)";
}
/*
* Update the event if it's being edited
*/
else
{
/*
* Cast the event ID as an integer for security
*/
$id = (int) $_POST['event_id'];
$sql = "UPDATE `events`
SET
`event_title`=:title,
`event_desc`=:description,
`event_start`=:start,
`event_end`=:end
WHERE `event_id`=$id";
}
/*
* Execute the create or edit query after binding the data */
try
{
$stmt = $this->db->prepare($sql);
$stmt->bindParam(":title", $title, PDO::PARAM_STR); $stmt->bindParam(":description", $desc, PDO::PARAM_STR); $stmt->bindParam(":start", $start, PDO::PARAM_STR); $stmt->bindParam(":end", $end, PDO::PARAM_STR);
$stmt->execute();
$stmt->closeCursor();
/*
Trang 9* Returns the ID of the event
*/
return $this->db->lastInsertId();
}
catch ( Exception $e )
{
return $e->getMessage();
}
}
After making the preceding change, save this file and reload http://localhost/ in your browser
Next, create a new event with the following information:
• Event Title: ID Test
• Event Start: 2010-01-06 12:00:00
• Event End: 2010-01-06 16:00:00
• Event Description: This event should be immediately viewable after creation
Now save the event, and the title will appear on the calendar Click the title, and the event will load
in a modal window (see Figure 8-4)
Trang 10Figure 8-4 An event loaded immediately after creation
Editing Events in a Modal Window
In its current state, your app is only a short ways away from allowing users to edit events from the modal
window, as well The existing click event handler for loading the event creation form will also work for
event editing with only a little modification
To start, expand the selector to include any element with a class admin; you can accomplish this by including the following bold code:
// Displays the edit form as a modal window
$(".admin-options form,.admin").live("click", function(event){
// Prevents the form from submitting
event.preventDefault();
// Loads the action for the processing file