Create a dynamic calendar with PHP & jQuery

So I’m working on a project where I have to put together a calendar feature that will eventually hold various tasks. So after a looking around the Internet, I found this Simple PHP Calendar to help me get the ball rolling. For the record, I don’t love the code provided here, but it was really easy to follow and there were some areas where I could improve the code. So yes, I’m going to show you some of the code that I lifted (and edited slightly) from mentioned blog post, plus I’ll show you the jQuery/JavaScript code I wrote to switch between months. I’ll try and explain as best I can from start to finish. And please, if you have any further improvements to my code, let me know in the comments. I’m not going to cover any ajax stuff in this post, but I’m thinking maybe I will follow up with it in a part 2 eventually.

The Back-End: PHP

So basically we are going to create a function called getCalendar(), which of course will look something like this…

function getCalendar() {
	//our code will go here
}

Now that we got how to write a function out of the way, let’s move on to the guts of the code that will replace my little //our code will go here comment within the function. So first, let’s take a look at the variables we need.

function getCalendar() {
	$day = date('d');
	$month = date('m');
	$year = date('Y');
	$first_day = mktime(0,0,0,$month, 1, $year);
	$title = date('M', $first_day);
	$day_of_week = date('D', $first_day);

Ok, so obviously we’ll be using the handy date() function. And by passing different arguments like d for day, m for month, and Y for year, we can grab all that we need to start building a calendar that reflects the current date. That last variable, $day_of_week will be used in the next section of code to figure out which day the first of the month falls on. We’ll be using a switch statement to start figuring that out.

	switch($day_of_week) {
		case "Sun": $blank = 0; break;
		case "Mon": $blank = 1; break;
		case "Tue": $blank = 2; break;
		case "Wed": $blank = 3; break;
		case "Thu": $blank = 4; break;
		case "Fri": $blank = 5; break;
		case "Sat": $blank = 6; break;
	}
	$days_in_month = cal_days_in_month(0, $month, $year);

The next bit of markup you might want to edit. Some parts of this table can be done better with CSS. Please take note of the id’s and classes I use here. I added them in from the original code in order to write the jQuery functions. I also added in the $row_count variable so I will always have enough rows to fill in all the dates for every month. Anyway, here is the last bit of code you need to add to the calendar.

	echo "<table id='calendar' border='1' cellspacing='0' width='280'>";
	echo "<tr><th id='prev'><</th><th colspan='5'> <span id='month'>$title</span>, <span id='year'>$year</span></th><th id='next'>></th></tr>";
	echo "<tr><td width='42'>S</td><td width='42'>M</td><td width='42'>T</td><td width='42'>W</td><td width='42'>T</td><td width='42'>F</td><td width='42'>S</td></tr>";
	$day_count = 1;
	echo "<tr>";
	while ( $blank > 0 ) {
	echo "<td class='day'></td>";
		$blank = $blank-1;
		$day_count++;
	}
	$day_num = 1;
	$row_count = 1;
	while ( $day_num <= $days_in_month ) {
		echo "<td class='day'> $day_num </td>";
		$day_num++;
		$day_count++;
		if ($day_count > 7) {
			echo "</tr><tr>";
			$day_count = 1;
			$row_count++;
		}
	}
	while ($row_count <=6 ) {
		echo "<td class='day'></td>";
		$day_count++;
		if ($day_count > 7) {
			$day_count = 1;
			$row_count++;
			$row_count <=6 ? print('</tr><tr>') : print('');
		}
	}
	echo "</tr></table>";
}

Now all you have to do is call the function on a page.

echo getCalendar();

Now let’s move onto the really fun jQuery part.

The Front-End: jQuery

As you probably know, jQuery is an incredibly popular and powerful JavaScript library that lets you do some incredible things using very little code. For the calendar, I wrote 2 functions that use the #next and #prev id’s in the HTML of my calendar to go forward and backward. Anyway, before we get into the big functions, here’s a quick styling function I wrote to grey out the unused boxes in the calendar. Also remember to place all this code in document ready, which looks like this:

$(function() {
	//jQuery code goes here
});

Okay, so for my grey boxes, place this code in document ready.

$('.day').each(function() {
	$(this).text() == '' ? $(this).css('background', '#ccc') : $(this).css('background', '#fff');
});

Now lets create the JavaScript arrays for months and days. We also need a variable to grab today’s date.

 var months = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
 var days = new Array('S', 'M', 'T', 'W', 'T', 'F', 'S');
 var date = new Date();

Here’s the last bit of code you need: 2 jQuery click functions to take you forward and backward. This is all done in JavaScript/jQuery, so the page never needs to reload. If you do reload the page, it will take you back to the current month. If you want it to hold onto the month/year you were looking at, I suggest creating/updating a cookie. Maybe I’ll cover how to do that too in part 2.

$('#next').click(function() {
	//gets current year from page
	var curMon = $('#month').text();
	for(var i in months) {
		if(months[i] == curMon) {
			//if not dec, increment i
			if(i != 11) {
				i++;
			} else {
			//else, back to jan and increment year
				i = 0;
				var curYear = $('#year').text();
				curYear = parseInt(curYear) + 1;
				curYear = curYear.toString();
				$('#year').text(curYear);
			}
			$('#month').html(months[i]);
			var yy = parseInt( $('#year').text() );
			var days = daysInMonth(i, yy);
			//clear all the dates
			$('.day').each(function() {
				$(this).text('');
			});
			var firstDay = new Date(months[i]+', 1 ' + yy);
			firstDay = firstDay.getDay();
			var j = 1;
			while(j <= days) {
				//fills in dates starting in the correct spot
				$('.day').eq(firstDay).text(j);
				firstDay++;
				j++;
			}
		}
	}
	//grey out unused boxes again
	$('.day').each(function() {
		$(this).text() == '' ? $(this).css('background', '#ccc') : $(this).css('background', '#fff');
	});
});
$('#prev').click(function() {
	var curMon = $('#month').text();
	for(var i in months) {
		if(months[i] == curMon) {
			if(i != 0) {
				i--;
			} else {
				i = 11;
				var curYear = $('#year').text();
				curYear = parseInt(curYear) - 1;
				curYear = curYear.toString();
				$('#year').text(curYear);
			}
			$('#month').html(months[i]);
			var yy = parseInt( $('#year').text() );
			var days = daysInMonth(i, yy);
			$('.day').each(function() {
				$(this).text('');
			});
			var firstDay = new Date(months[i]+', 1 ' + yy);
			firstDay = firstDay.getDay();
			var j = 1;
			while(j <= days) {
				$('.day').eq(firstDay).text(j);
				firstDay++;
				j++;
			}
		}
	}
	$('.day').each(function() {
		$(this).text() == '' ? $(this).css('background', '#ccc') : $(this).css('background', '#fff');
	});
});
//this little function returns how many days or in each month
function daysInMonth(m, y) {
return new Date(y, m+1, 0).getDate();
}

So that’s it. I added some comments in the first function so you can follow along. I’ve also included a link to a working model of the calendar. Just view source to see all the jQuery and (minimal) CSS.

Comments

  1. Arif Majid says:

    code plz … zip it

  2. geo news says:

    Hi, please provide a demo link to see the results :) Thanks

Speak Your Mind

*


*

* Copy this password:

* Type or paste password here:

415 Spam Comments Blocked so far by Spam Free Wordpress