Tải bản đầy đủ (.pdf) (10 trang)

Tương tác giữa PHP và jQuery - part 29 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (874.17 KB, 10 trang )

CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

281

"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
CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

282
// 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]);
CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

283

// 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
CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

284
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
// 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:

CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

285
// 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).


CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

286

Figure 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).

CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

287

Figure 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";

}

CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

288
/*
* 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();

/*
CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

289

* 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).
CHAPTER 8 ■ EDITING THE CALENDAR WITH AJAX AND JQUERY

290

Figure 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

×