Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

Exclusive offer: get 80% off this eBook here
jQuery 1.3 with PHP

jQuery 1.3 with PHP — Save 80%

Enhance your PHP applications by increasing their responsiveness through jQuery and its plugins.

₨587.06    ₨117.41
by Kae Verens | October 2009 | MySQL Content Management Open Source PHP Web Development

In this article by Kae Verens, we will discuss the following topics:

  • Displaying a calendar for a week
  • Creating and saving an event in that calendar
  • Moving, editing, and deleting events
  • Creating recurring events
  • Editing and removing recurring events

We will use the jquery-week-calendar plugin to create and edit normal and recurring events.

There are many reasons why you would want to display a calendar. You can use it to display upcoming events, to keep a diary, or to show a timetable. Recently, for example, I combined a calendar with an online store for a client to book meetings and receive payments more intuitively.

Google calendar is probably what springs to mind when people think of calendars online. There is a very good plugin called jquery-week-calendar that shows a week with events in a fashion similar to Google's calendar.

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

Its homepage is at http://www.redredred.com.au/projects/jquery-week-calendar/.

To get the latest copy of the plugin, go to http://code.google.com/p/jquery-week-calendar/downloads/list and get the highest-numbered file. The examples in this article are done with version 1.2.0.

Download the library and extract it so that there is a directory named jquery-weekcalendar-1.2.0 in the root of your demo directory.

Displaying the calendar

As usual, the HTML for the simplest configuration is very simple. Save this as calendar.html:

<html>
<head>
<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="../jquery.min.js"></script>
<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="../jquery-ui.min.js"></script>
<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="../jquery-weekcalendar-1.2.0/jquery.weekcalendar.js">
</script>
<script src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="calendar.js"></script>
<link rel="stylesheet" type="text/css"
href="../jquery-ui.css" />
<link rel="stylesheet" type="text/css"
href="../jquery-weekcalendar-1.2.0/jquery.weekcalendar.css"/>
</head>
<body>
<div id="calendar_wrapper" style="height:500px"></div>
</body>
</html>

We will keep all of our JavaScript in an external file called calendar.js, which will initially contain just this:

$(document).ready(function() { 
$('#calendar_wrapper').weekCalendar({
'height':function($calendar){
return $('#calendar_wrapper')[0].offsetHeight;
}
});
});

This is fairly straightforward. The script will apply the widget to the #calendar_wrapper element, and the widget's height will be set to that of the wrapper element.

Even with this tiny bit of code, we already have a good-looking calendar, and when you drag your mouse cursor around it, you'll see that events are created as you lift the mouse up:

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

It looks good, but it doesn't do anything yet. The events are temporary, and will vanish as soon as you change the week or reload the page. In order to make them permanent, we need to send details of the events to the server and save them there.

Creating an event

What we need to do is to have the client save the event on the server when it is created.

In this article, we'll use PHP sessions to save the data for the sake of simplicity.

Sessions are chunks of data, which are kept on the server side and are related to the cookie or PHPSESSID parameter that the client uses to access that session. We will use sessions in these examples because they do not need as much setup as databases.

For your own projects, you should adapt the PHP side in order to connect to a database instead.

If you are using this article to create a full application, you will obviously want to use something more permanent than sessions, in which case the PHP code should be adapted such that all references to sessions are replaced with database references instead. This is beyond the scope of this book, but as you are a PHP developer, you probably do this everyday anyway!

When the event has been created, we want a modal dialog to appear and ask for more details. In this test case, we'll add a text area for further details, which allows for more data than would appear in the small visible area in the calendar itself.

A modal dialog is a "pop up" that appears and blocks all other actions on the page until it has been taken care of. It's useful in cases where the answer to a question must be known before a script can carry on with its work.

Now, let's create an event and add it to our calendar.

Client-side code

In the calendar.js file, add an eventNew event to the weekCalendar call:

$(document).ready(function() { 
$('#calendar_wrapper').weekCalendar({
'height':function($calendar){
return $('#calendar_wrapper')[0].offsetHeight;
},
'eventNew':function(calEvent, $event) {
calendar_new_entry(calEvent,$event);
}
});
});

When an event is created, the calendar_new_entry function will be called with details of the new event in the calEvent parameter.

Now, add the function calendar_new_entry:

function calendar_new_entry(calEvent,$event){ 
var ds=calEvent.start, df=calEvent.end;
$('<div id="calendar_new_entry_form" title="New Calendar Entry">
event name<br />
<input value="new event" id="calendar_new_entry_form_title" />
<br />
body text<br />
<textarea style="width:400px;height:200px"
id="calendar_new_entry_form_body">event description
</textarea>
</div>').appendTo($('body'));
$("#calendar_new_entry_form").dialog({
bgiframe: true,
autoOpen: false,
height: 440,
width: 450,
modal: true,
buttons: {
'Save': function() {
var $this=$(this);
$.getJSON('./calendar.php?action=save&id=0&start='
+ds.getTime()/1000+'&end='+df.getTime()/1000,
{
'body':$('#calendar_new_entry_form_body').val(),
'title':$('#calendar_new_entry_form_title').val()
},
function(ret){
$this.dialog('close');
$('#calendar_wrapper').weekCalendar('refresh');
$("#calendar_new_entry_form").remove();
}
);
},
Cancel: function() {
$event.remove();
$(this).dialog('close');
$("#calendar_new_entry_form").remove();
}
},
close: function() {
$('#calendar').weekCalendar('removeUnsavedEvents');
$("#calendar_new_entry_form").remove();
}
});
$("#calendar_new_entry_form").dialog('open');
}

What's happening here is that a form is created and added to the body (the second line of the function), then the third line of the function creates a modal window from that form and adds some buttons to it.

Our modal dialog should look like this:

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

The Save button, when pressed, calls the server-side file calendar.php with the parameters needed to save the event, including the start and end, and the title and body.

When the result returns, the calendar is refreshed with the new event's data included.

When any of the buttons are clicked, we close the dialog and remove it from the page completely.

Note how we are sending time information to the server (shown highlighted in the code we just saw). JavaScript time functions usually measure in milliseconds, but we want to send it to PHP, which generally measures time in seconds. So, we convert the value on the client so that the PHP can use the received data as it is, without needing to do anything to it. Every little helps!

Server-side code

On the server side, we want to take the new event and save it. Remember that we're doing it in sessions in this example, but you should feel free to adapt this to any other model that you wish.

Create a file called calendar.php and save it with this source in it:

<?php 
session_start();
if(!isset($_SESSION['calendar'])){
$_SESSION['calendar']=array(
'ids'=>0,
);
}
if(isset($_REQUEST['action'])){
switch($_REQUEST['action']){
case 'save': // {
$start_date=(int)$_REQUEST['start'];
$data=array(
'title'=>(isset($_REQUEST['title'])?$_REQUEST['title']:''),
'body' =>(isset($_REQUEST['body'])?$_REQUEST['body']:''),
'start'=>date('c',$start_date),
'end' =>date('c',(int)$_REQUEST['end'])
);
$id=(int)$_REQUEST['id'];
if($id && isset($_SESSION['calendar'][$id])){
$_SESSION['calendar'][$id]=$data;
}
else{
$id= ++$_SESSION['calendar']['ids'];
$_SESSION['calendar'][$id]=$data;
}
echo 1;
exit;
// }
}
}
?>

In the server-side code of this project, all the requested actions are handled by a switch statement. This is done for demonstration purposes—whenever we add a new action, we simply add a new switch case. If you are using this for your own purposes, you may wish to rewrite it using functions instead of large switch cases.

The date function is used to convert the start and end parameters into ISO 8601 date format. That's the format jquery-week-calendar prefers, so we'll try to keep everything in that format.

Visually, nothing appears to happen, but the data is actually being saved.

To see what's being saved, create a new file named test.php, and use the var_dump function in it to examine the session data (view it in your browser):

<?php 
session_start();
var_dump($_SESSION);
?>

Here's an example from my test machine:

jQuery 1.3 with PHP Enhance your PHP applications by increasing their responsiveness through jQuery and its plugins.
Published: October 2009
eBook Price: ₨587.06
Book Price: ₨300.00
See more
Select your format and quantity:

Loading events from the server

The next step is to load events from the server, so you can see the details of the event you've created in your browser.

Client-side code

In the JavaScript, all you need to do is to add another parameter to the startup script. Add this highlighted line to the weekCalendar call, as shown:

$('#calendar_wrapper').weekCalendar({
'data':'./calendar.php?action=get_events',
'height':function($calendar){

This parameter is used to tell the plugin where to check for event data.

When loaded up, the plugin will call that file (./calendar.php?action=get_events), with the extra HTML parameters start and end, both of which are measured in seconds—being the first and last second of the week respectively.

The result is expected to be a JSON string, which describes the week's events.

Server-side code

On the server side, all we need to do is to add a new case to the switch block:

case 'get_events': // { 
$arr=array();
$start=date('c',$_REQUEST['start']);
$end=date('c',$_REQUEST['end']);
for($i=1;$i<$_SESSION['calendar']['ids']+1;$i++){
if(!isset($_SESSION['calendar'][$i]))continue;
if(strcmp($_SESSION['calendar'][$i]['start'],$end)<1
&& strcmp($_SESSION['calendar'][$i]['end'],$start)>-1){
$d=$_SESSION['calendar'][$i];
$arr[]=array(
'id' =>$i,
'title'=>$d['title'],
'start'=>$d['start'],
'end' =>$d['end']
);
}
}
echo '{"events":'.json_encode($arr).'}';
exit;
// }

Note that we convert the seconds into ISO 8601 strings, and then compare all entries in the session array to see if any of them are contained in the requested time slot.

The reason we rebuild the array and don't just use it as-is is that we want to include the id of each event, and we don't want to include any fields that the plugin doesn't use.

jquery-week-calendar is only interested in the id, title, start, and end parameters. So, it would be a waste of bandwidth to send anything more than that.

Now we can create events and read them back.

Moving and resizing events

From the data point of view, resizing and moving are actually the same thing. When it is being recorded, the data fields that are changed are the start and end times, and nothing else. This is good, as it means we have very little extra to write.

In the widget, you resize an event by dragging its bottom border down or up, as shown:

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

And you move the events by dragging the top label, as shown:

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

Client-side code

In the calendar.js file, add the following new events to the weekCalendar call in the start-up section:

'eventDrop':function(calEvent, $event) { 
$.getJSON('./calendar.php?action=move',{
'id':calEvent.id,
'start':calEvent.start.getTime()/1000,
'end':calEvent.end.getTime()/1000
},null);
},
'eventResize':function(calEvent, $event) {
$.getJSON('./calendar.php?action=move',{
'id':calEvent.id,
'start':calEvent.start.getTime()/1000,
'end':calEvent.end.getTime()/1000
},null);
},

Both the events are exactly the same as you would expect, because in both the cases, we are only changing the start and end times of the events.

Server-side code

In calendar.php, add the following to the action switch:

case 'move': // { 
$id=(int)$_REQUEST['id'];
if(!isset($_SESSION['calendar'][$id]))exit;
$_SESSION['calendar'][$id]['start']
=date('c',(int)$_REQUEST['start']);
$_SESSION['calendar'][$id]['end']
=date('c',(int)$_REQUEST['end']);
exit;
// }

Incredibly simple. Just a matter of saving the new times.

Editing events

Editing an event is slightly more complex than creating an event. We need to populate the edit form with the values of the event. However, because jquery-week-calendar only records the id, start and end times, and title, the event data does not have any of the extra fields, such as the body field, which are required to fill in the form.

To get around this, we wrap the form generator in an inline function, which is called after the server has been requested to supply all of the event's data.

To expand further on that, when we are asked to show the event editing form, what we need to do is to retrieve the data from the server, and send it to a callback function, which will generate the form and display it.

We will use an inline function in this case, as the code is mostly unique and is only used in this case. So, it makes sense to not create a public function out of it.

As a reminder, an inline function is a function that does not have a name, and is defined as a parameter to a function. In our case, we define it as the callback function for $.getJSON as shown next.

Client-side code

Add the following event to our previous weekCalendar call in calendar.js:

'eventClick':function(calEvent, $event) { 
calendar_edit_entry(calEvent,$event);
},

And now we create the edit form:

function calendar_edit_entry(calEvent,$event){ 
if(!calEvent.id) return;
var ds=calEvent.start, df=calEvent.end;
$.getJSON('./calendar.php?action=get_event&id='
+calEvent.id,
function(eventdata){
$('<div id="calendar_edit_entry_form" '
+'title="Edit Calendar Entry">event name<br />'
+'<input id="calendar_edit_entry_form_title" value="'
+eventdata.title+'" /><br />body text<br />'
+'<textarea style="width:400px;height:200px"'
+'id="calendar_edit_entry_form_body">'
+eventdata.body+'</textarea></div>'
).appendTo($('body'));
$("#calendar_edit_entry_form").dialog({
bgiframe: true,
autoOpen: false,
height: 440,
width: 450,
modal: true,
buttons: {
'Save': function() {
var $this=$(this),start=ds.getTime()/1000,end=df.getTime()/1000;
var body=$('#calendar_edit_entry_form_body').val();
var title=$('#calendar_edit_entry_form_title').val();
$.getJSON('./calendar.php?action=save&id='
+eventdata.id+'&start='+start+'&end='+end,
{'body':body,'title':title},
function(ret){
$this.dialog('close');
$('#calendar_wrapper').weekCalendar('refresh');
$('#calendar_edit_entry_form').remove();
}
);
},
Cancel: function() {
$(this).dialog('close');
$("#calendar_edit_entry_form").remove();
}
},
close: function() {
$("#calendar_edit_entry_form").remove();
}
});
$("#calendar_edit_entry_form").dialog('open');
});
}

The highlighted line indicates the beginning of the inline callback function. This looks similar to the function we wrote to create a new form, but there are enough differences between creating an event and deleting an event to warrant separate functions and forms, instead of using abstraction to combine the two.

The differences will become more obvious later in the article as we expand on it.

There is no visual difference between the two event forms at this point.

Note that the form creation is delayed by first using $.getJSON to ask the server for details about the selected event, which are then used by the form to fill itself with the resulting values.

Apart from the pre-filling of data, there are no large differences between the editing and saving of the data.

Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 1

Server-side code

In the Creating an event section, we wrote PHP that already handles the saving of data that has an id, so there's nothing further to do there.

However, in the example in the previous section, we requested the server to provide information about a specified event. That can be handled by adding another case to the action switch:

case 'get_event': // { 
$id=(int)$_REQUEST['id'];
if(!isset($_SESSION['calendar'][$id]))exit;
$t=$_SESSION['calendar'][$id];
$t['id']=$id;
echo json_encode($t);
exit;
// }

And that completes the editing of the event.

jQuery 1.3 with PHP Enhance your PHP applications by increasing their responsiveness through jQuery and its plugins.
Published: October 2009
eBook Price: ₨587.06
Book Price: ₨300.00
See more
Select your format and quantity:

>> Continue Reading Calendars in jQuery 1.3 with PHP using jQuery Week Calendar Plugin: Part 2

[ 1 | 2 ]

About the Author :


Kae Verens

Kae Verens is an owner manager of the web-development company Webworks.ie and is currently secretary of the Irish PHP Users Group. He has been writing in JavaScript since the mid 90s, and in PHP since the late 90s. Kae is the creator of the file management system KFM, the CMS WebME (used by Webworks.ie for over 200 separate clients), and the author of the Packt book jQuery 1.3 with PHP.

 

Books From Packt

Joomla! with Flash
Joomla! with Flash

Joomla! 1.5 SEO
Joomla! 1.5 SEO

Symfony 1.3 Web Application Development
Symfony 1.3 Web Application Development

Plone 3 for Education
Plone 3 for Education

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

PHP Team Development
PHP Team Development

JBoss RichFaces 3.3
JBoss RichFaces 3.3

jQuery UI 1.6: The User Interface Library for jQuery
jQuery UI 1.6: The User Interface Library for jQuery

 

 

 

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software