In this tutorial we are going to create sleek calendar using php with a good looking UI and a navigation. Let’s get started !!
First of all create the project folder on your server and inside it create a php file.
We will start off by creating a rather basic skeleton of our calendar in html. Our structure will consists of a header for displaying month and navigation , table for displaying the month dates. All of this will be wrapped inside a div with ‘calendar’ class which will be our reference for styling it later on.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" type="text/css" href="style.css" /> <title>Calendar</title> </head> <body> <div class="calendar"> <div class="calendar-header">Month </div> <div class="calendar-content"> <table> <thead> <tr><th>Sun</th><th>Mon</th><th>Tues</th><th>Wed</th><th>Thurs</th> <th>Fri</th><th>Sat</th></tr> <!-- Week Format --> </thead> <tbody> <!-- Table Dates here --> </tbody> </table> </div> </div> </div> </body> </html>
Note: We could have used the table directly instead of wrapping it inside of div with ‘calendar-content’ class, but it’s a good practice to wrap the content inside a widget div, so if you need add some data like notification inside the calendar, you don’t have to restructure the plugin again.
Now since we have created a basic structure, let’s move on to actually start adding the logic to it. First we will initialize day, month and year variables that we will use later in the generation logic.
<?php
$year = date('Y');
$day = date('j');
$month = date('n');
?>
Now we will work on the header of the calendar which has the current month name displayed along with the navigation for next or previous month. For navigation we will send the navigation details using GET method to our php file.
<div class="calendar-header">
<a href="index.php?nav=prev&m=<?php echo $month; ?>"> « </a>
<?php echo date("F",mktime(0,0,0,$month,1,$year)); ?>
<a href="index.php?nav=next&m=<?php echo $month; ?>"> » </a>
</div>
We will use anchor tags with link to the php file itself ( I am using index.php ) along with the navigation type that is next or previous and current selected month. In between the navigation we will echo the current month.
Now since we have added the navigation controls, we need to alter the month variable. That is if the Get variables are set, we need to alter the calendar in respect to that values. So the earlier php code now looks like -
<?php
$year = date('Y');
$day = date('j');
if(isset($_GET["nav"]))
{
if($_GET["nav"]=="next")
{
$m = $_GET["m"];
if($m==12)
$m =0;
$month = $m+1;
}
else
{
$m = $_GET["m"];
if($m==0)
$m =12;
$month = $m-1;
}
}
else
$month = date('n');
?>
First we will check if the value of the get variables are set using the isset() function, if they are we will check the type of navigation and increment or decrement the month variable accordingly. If get variables are not set it will display the current month. Also we have little validation to check that if the values are always within 1 -12 range for months.
Now are going to create a php code block inside the table’s tbody tag. Where we will add the calendar date blocks. So to start with we will initialize the variables that we will be needing to implement the logic.
<?php
$first_Day = date("w", mktime(0,0,0,$month,1,$year));
$totaldays = date("t",mktime(0,0,0,$month,1,$year));
$temp = $first_Day + $totaldays;
$weeksInMonth = ceil($temp/7);
$counter = 1;
$flag = true;
if($month!=date("n"))
$flag=false;
?>
$first_Day returns the index of the first day of the month, total days count the total days for our loop to run. temp is the variable we will have total days of the table grid plus first day index which is required for our nested loop that we will use later. Next we calculate weeks on the month and initialize a counter that will print the dates. Also we have created a variable to check that the calendar is generating the current month or not for highlighting today’s date.
Now we are going to implement the nested loops to create a grid of dates for our calendar table.
for($i=0;$i<$weeksInMonth;$i++)
{
echo "<tr>";
for($j=0;$j<7;$j++)
{
if(( $counter<=$temp) && ( ($counter + $totaldays) - $temp >0) )
{
echo "<td><p";
if(( $counter - $first_Day )==$day&&$flag==true)
echo " class='current-bg'";
echo ">".( $counter - $first_Day )."</p>";
}
else
echo "<td>";
echo "</td>";
$counter++;
}
echo "</tr>";
}
First we will loop through the total number of weeks, nested loop will run till 7. Here 1 week represents 1 row of the table, so we will echo the tr tag first and after the loop we will close it. Inside the loop since it runs of total days of all weeks so we will check the condition that counter variable is less than the total days of the month plus the starting date and also we will check that difference of counter plus totaldays variable and temp is greater than zero.
Then we will print out the table cell with conditional checking that if it is current month and current day then add the class current-bg which we will style later to highlight today’s date and then print the current date that difference between $counter and $first_Day, we have done this because counter variable runs from 0. Finally if the condition is not met print an empty table cell.
Though we have the functionality , but it is rather ugly looking and there is no way to tell what is today’s date. So we will style it up now.
Now create a syle.css file in the project directory and link it to our main file. We will use gradients as background images, for that I have already sliced them, they are available in the source code. Add the following code to it -
* { margin:0;padding:0; }
.calendar { background:#f2f2f2; width:601px; margin-left:auto; margin-right:auto; margin-top:20px; border:1px solid #CCC;}
.calendar .calendar-header { background:#333; color:#e2e2e2; font-family:Georgia, "Times New Roman", Times, serif; padding:10px; text-align:center; font-weight:bold; }
.calendar table { border-collapse:collapse; width:100%; }
.calendar .calendar-header a { text-decoration:none; color:#fff; }
.calendar .calendar-header a:hover { text-decoration:underline; }
.calendar table thead th { text-align:center; border-bottom:1px solid #999; padding:8px 4px; font-family: Arial,sans-serif; font-weight:100; text-shadow:#fff 1px 1px 0px; }
.calendar table tbody tr td p{ background:url(i/calender-default.png) repeat-x; border: 1px solid #fff; border-right:1px solid #d6d6d6; font-family: Arial,sans-serif; border-bottom:1px solid #d6d6d6; width:74px; height:70px; display:block; text-align:center;padding:5px; text-shadow:#fff 1px 1px 0px; -moz-border-radius: 7px; -webkit-border-radius: 7px; }
First we have added a mini reset, then style our parent div that has calendar class. First we will style the parent container, then the header and finally the table. Now our calendar looks like -
But still we don’t know the current date and need some effect on hover. So we will add the final touch to it -
.current-bg { background:url(i/current-bg.png) repeat-x!important; border:1px solid #0CF!important; }
.calendar table tbody tr td p:hover { background:url(i/hover-bg.png) repeat-x; border:1px solid #3F9; }
Add we are done, ready to used in projects, event widgets etc.
No related posts.
Thanks a lot for the nice explanation. ![]()
Yes! This is great tutorial!
January 12th, 2012 at 11:28 pm
good one. But how can i display year?
Twitter
Follow me on Twitter to keep up to date!
RSS Feed
Keep up with all of our updates by subscribing to our RSS feed!
FaceBook
Join our group on Facebook and become a fan of us!