2/01/2010

Easy PHP Date Picker

There are many fancy javascript calendars for selecting dates - for example the one that comes as a jQuery plugin is really cool. There are however some disadvantages to using such calendars:


  • If you only need a date picker, it's not worth to include all these Javascript libraries and overload.

  • These javascript calendars are hard to use from people who don't see well or can't use a mouse

  • In admin screens etc., where you may need to manage many dates in rows of records, clicking on the calendars can be much slower than picking dates from dropdown.



In cases like these and maybe more, it's better to create a simple dropdown date picker that will allow the user to select year, month and day (in fact this will be 3 dropdowns).

Let's build such a function:

First we'll build an array of months:

$months=array('','January','February','March','April','May','June','July','August',
'September','October','November','December');


Note that I inserted the first element of the array as empty because I want the month numbers to start from 1 (for January).

Then we'll construct the three dropdowns:

$html="<select name=\"".$name."month\">";
for($i=1;$i<=12;$i++)
{
$html.="<option value='$i'>$months[$i]</option>";
}
$html.="</select> ";


This was the months dropdown. Did you notice the "name" variable? We will pass it as argument to the function so we can control the name of the dropdowns and have many of them in a page. In very similar way you can create the days dropdown - from 1st to 31st.


$html.="<select name=\"".$name."day\">";
for($i=1;$i<=31;$i++)
{
$html.="<option value='$i'>$i</option>";
}
$html.="</select> ";


The years dropdown is just as simple. The only question in it is in what year to start and when to end. Your function can accept this as arguments or you can dynamically create start and end year accordingly to the current date. For example:


$startyear = date("Y")-100;
$endyear= date("Y")+50;

$html.="<select name=\"".$name."year\">";
for($i=$startyear;$i<=$endyear;$i++)
{
$chooser.="<option value='$i'>$i</option>";
}
$html.="</select> ";


You can add some javascript to increase/reduce the number of days accordingly to the month, but this can be needlessly complicated. It's easier to solve this problem by javascript validation at the time when the form is submitted.

So Here Is The Full Code (For Those Who Don't Get It):



Then put all this code into a function which accepts the argument $name:


function date_picker($name, $startyear=NULL, $endyear=NULL)
{
if($startyear==NULL) $startyear = date("Y")-100;
if($endyear==NULL) $endyear=date("Y")+50;

$months=array('','January','February','March','April','May',
'June','July','August', 'September','October','November','December');

// Month dropdown
$html="<select name=\"".$name."month\">";

for($i=1;$i<=12;$i++)
{
$html.="<option value='$i'>$months[$i]</option>";
}
$html.="</select> ";

// Day dropdown
$html.="<select name=\"".$name."day\">";
for($i=1;$i<=31;$i++)
{
$html.="<option $selected value='$i'>$i</option>";
}
$html.="</select> ";

// Year dropdown
$html.="<select name=\"".$name."year\">";

for($i=$startyear;$i<=$endyear;$i++)
{
$html.="<option value='$i'>$i</option>";
}
$html.="</select> ";

return $html;
}


And use the function as echo date_picker("registration") (for example - "registration" is just a name you choose). The result that will come in $_POST after submitting such form will be in 3 variables:
$_POST['registrationmonth'], $_POST['registrationday'] and $_POST['registrationyear'].

You can easily construct a MySQL date from these variables.

Now think how you can make this dropdown read stored data and pre-select its values accordingly to it (for "Edit record" forms).

1/16/2010

Building a Simple Monthly Calendar

In this tutorial we are going to learn how to build a simple calendar in PHP. You have seen many of those calendar date pickers mostly in Javascript. This PHP based one has a slightly different purpose - instead of populating an input field, it outputs links for the different dates and can be used for example as a monthly archive in a dynamic DB-driven site.



We will build this calendar following good coding practices and keeping the login in one PHP file and the presentation in one HTML file.



Let's start:



First we need to define the current date OR a date coming by POST after the calendar form is submitted:



$today=getdate();
$year=$_POST['year']?$_POST['year']:$today['year'];
$month=$_POST['month']?$_POST['month']:$today['month'];
$day=$_POST['day']?$_POST['day']:$event['day'];


PHP getdate() function returns an array of year, month and day. We assign this to $today variable and use it to define the calendar day, year and month - if they are coming from POST, the POST values have priority - otherwise we use $today values.



Then we need to define the number of days in the given month. We use function cal_days_in_month() for that:



$numdays=cal_days_in_month(CAL_GREGORIAN, $month, $year);


Now there's one specific. We don't want the calendar rows to be different number in different month. For that we'll make sure the calendar looks like the printed calendars and like this event calendar software by defining the week start day:



// calculate 'extra' days - these which need to come on the first
// line - like 30-31- -- - -- - -- - -- - 1
$estart=(7-$wday)+28;
$extra=$numdays-$estart;


That's it, now we only need to include the design template:



require_once("mc_template.html");


The rest is easy - display year and month dropdows:



<select name="year" onchange="this.form.submit();">
<php
for($i=$start_year;$i<=2050;$i++)
{
if($i==$year) $selected='selected';
else $selected='';
echo "<option $selected value=$i>$i</option>";
}
?>
</select>
 
<select name="month" onchange="this.form.submit();">
<php
for($i=1;$i<=12;$i++)
{
if($i==$month) $selected='selected';
else $selected='';
echo "<option $selected value=$i>".$lmonths[$months[$i]]."</option>";
}
// end PHP
</select>


And the calendar itself in a HTML table:




<p;?php
if($extra<0) $extra=0;
for($i=$estart;$i<$numdays;$i++)
{
// ...
// the full code can be downloaded at the bottom
}
?>


And your calendar is ready! You can download the free Microcal script that uses this same code here

Welcome... and first few tips!

Welcome to my new blog featuring some of my PHP tutorials. Here I'll try to share simple and elegant hacks that will help you not only solve varios problems but solve them in easier, quicker and more elegant way.

Being a great PHP developer doesn't mean to know each and every function and feature of the language. It means to solve the real world problems in efficient way. This is what the blog is going to help you for.

Let's start with a few random smart tips




  • Using the alternate PHP syntax in the HTML code will make it much cleaner and easier to follow.

  • Make your own database object or download a class online instead of using the PHP built-in functions like mysql_query etc. It's not that you are going to change the DB engines (it's unlikely) - it's about using far more comfortable functions that return directly arrays of objects of the results you are selecting.

  • Don't forget about the HEREDOC syntax.

  • When passing IDs in the URL check them with is_numeric() function. In many cases this is all you need to avoid attacks.

  • Use good PHP editor such as CodeLobster.

  • Put a small comment at the beginning of all your PHP files. This is extremely useful when you return to old code.

  • Use variable names that make sense. For example when selecting users from the DB call the result array $users instead of $rows. This will help you when the variable appears 10 lines later.



These tips are very basic, but I promise that's just the start. There are a lot more useful things coming in place here. Stay tuned!