Hi; I'm fooling around trying to make a very simple date picker for a form and would like to make it look like a one-month calendar page with buttons in each cell to show and on clicking, select the date. Essentially I want the set of buttons to work like radio buttons, but look like little square buttons with the date of the month on the button faces.

Here is what I have so far.

<html>
<head>
<title>Joe's handy dandy calendar control</title>
<STYLE TYPE="text/css"> 
.puny_yellow {
width: 20px;
height: 20px;
background-color:yellow;
border-color:efefef;
color: blue;
font-weight: bold;
font-family: arial, verdana, ms sans serif;
font-size: 8pt;}

.puny_red {
width: 20px;
height: 20px;
background-color:red;
border-color:efefef;
color: white;
font-weight: bold;
font-family: arial, verdana, ms sans serif;
font-size: 8pt;}

.puny_blue {
width: 20px;
height: 20px;
background-color:blue;
border-color:efefef;
color: white;
font-weight: bold;
font-family: arial, verdana, ms sans serif;
font-size: 8pt;}

table {border-collapse: collapse;} 
TH {color: white; background-color: navy; font-family: Arial; font-size: 8pt; padding: 0px;} 
TD {font-family: Arial; font-size: 8pt; padding: 0px;}

</STYLE>
</head>
<body  style="font-family: Arial; font-size: 8pt">

<?
// POSTED VALUES
foreach($_POST as $postkey=>$postval) {$$postkey="$postval";}
//echo "$$postkey:$postval<br>";} //DEBUG
// END POSTED VALUES

// Convert posted date string into time string
if(isset($raw_date) and $raw_date!="") {
	$raw_time=strtotime($raw_date);
	$datename="Selected date";
	} else {
	$raw_time=strtotime(date('Y-n-j'));
	$datename="Default date (today)";}
// END Convert posted date string into time string

//calendar form based on picked date
// Date formatted/parsed for various purposes
$firstday=date('n/1/Y',$raw_time);
$picked_date=date('Y-n-j',$raw_time);
$picked_comppart=date('Y-n-',$raw_time); // used for comparison and creating select date string buttons
$picked_mo_yr=date('Y-n', $raw_time);  
$picked_topbar=date('F Y', $raw_time); $picked_month_length=date('t', $raw_time); $picked_month=date('n', $raw_time); //month without leading zero $picked_year=date('Y', $raw_time); $raw_time_firstday=strtotime($firstday); $picked_month_startday=date('N', $raw_time_firstday); //numeric value of the day of week 0=sunday 6=saturday $current_compstring=date('Y-n-j'); // used for comparison if it is TODAY $spacecounter=(1-$picked_month_startday); //starting point for the calendar date cells echo "$datename: $picked_date<br>"; // show the default date or the date that was picked // figure out previous month and next month if($picked_month=="1") { $prev_yr=$picked_year-1; $prev_month="$prev_yr-12-1"; } else { $prev_mo=$picked_month-1; $prev_month="$picked_year-$prev_mo-1";} if($picked_month=="12") { $next_yr=$picked_year+1; $next_month="$next_yr-1-1"; } else { $next_mo=$picked_month+1; $next_month="$picked_year-$next_mo-1";} echo "<br>"; // end figure out previous month and next month //a one month calendar control echo "<table>"; echo "<tr><th><form method=\"POST\" action=\"xcal6.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$prev_month\"> <input type=\"submit\" value=\"<<\" class=\"puny_red\"> </th></form><th colspan=5>$picked_topbar</th><th><form method=\"POST\" action=\"xcal6.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$next_month\"> <input type=\"submit\" value=\">>\" class=\"puny_red\"> </th></form></tr>"; echo "<form method=\"POST\" action=\"xcal6.php\" target=\"_self\">"; echo "<tr><th>Su</th><th>Mo</th><th>Tu</th><th>We</th><th>Th</th><th>Fr</th><th>Sa</th></tr>"; $weeks=ceil($picked_month_length/7); //rounds upwards $week=0; $wkday=0; //start the first week for($week; $week <= $weeks; $week++) {echo "<tr>"; for($wkday; $wkday<=6; $wkday++) { $compstring="$picked_comppart$spacecounter"; if ($spacecounter < 1 ) {echo "<td align=center></td>";} elseif ($spacecounter > $picked_month_length) {echo "<td align=center></td>";} elseif ($compstring==$current_compstring) {echo "<td align=right> <input type=\"hidden\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\"> <input type=\"button\" value=\"$spacecounter\" class=\"puny_red\"> </td>";} elseif ($compstring==$picked_date) {echo "<td align=right> <input type=\"hidden\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\"> <input type=\"button\" value=\"$spacecounter\" class=\"puny_blue\"> </td>";} else {echo "<td> <input type=\"hidden\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\"> <input type=\"button\" value=\"$spacecounter\" class=\"puny_yellow\"> </td>";} // WEEKDAY SPACES $spacecounter++; } echo "</tr>"; $wkday=0; //resets the row counter } echo "</table>"; //END calendar form based on picked date echo "<input type=\"submit\" value=\"Save the date I clicked.\"></form>"; ?> </body></html>

As you see, when you hit the "Save the date" button, it only submits the very last value that would have been created in the process of creating the calendar page.

    That's really a client thing, not a PHP thing. There's a ton of free Javascript date choosers out on the web. I've sorted through quite a few, and the simplest one I've found is Matt Kruse's Calendar Popup.

    There's one small javascript file to download, customize, and include in your page. Then to implement the script, you'd include the following:

    <head>
    <script language="javascript" src="includes/CalendarPopup.js"></script>
    <SCRIPT LANGUAGE="JavaScript">
      var cal = new CalendarPopup();
    </SCRIPT>
    </head>
    
    <body>
    From <input type="text" name="fromdate" size="10" maxlength="10">
    <input type="button" onClick="cal.select(document.forms['advsch'].fromdate,'anchor1','MM/dd/yyyy'); return false;" value="..." NAME="anchor1" ID="anchor1">

    </body>

    I also add a Javascript function to validate the date format, in case the user decides to change it or type it in themselves. Here is that script:

    // Limit field to dates only
    // Usage: <INPUT NAME="date" onKeyPress="return datesonly(this, event)">
    function datesonly(myfield, e, dec)
      {
      var key;
     var keychar;
    
      if (window.event)
        key = window.event.keyCode;
      else if (e)
        key = e.which;
      else
        return true;
      keychar = String.fromCharCode(key);
    
      // control keys
      if ((key==null) || (key==0) || (key==8) || (key==9) || (key==13) || (key==27) )
        return true;
    
      // numbers & slashes
      else if ((("0123456789/").indexOf(keychar) > -1))
        return true;
    
      // decimal point jump
      else if (dec && (keychar == "."))
        {
        myfield.form.elements[dec].focus();
        return false;
        }
      else
        return false;
      }
    

    I've attached a picture of the resulting popup calendar.

      Thank you very much for your suggestion. I've downloaded the file and saved your code and am trying it out, but have never worked with javascript before and can't seem to make it work yet. I'll keep trying.

      Still, it does seem to be a lot fussier/more code (but maybe it does a bunch of stuff that mine won't be able to do)

      I've gotten closer to what I want with only 6K of basic php. But it requires radio buttons...I'd like them to just be tiny square buttons with the dates on each.

      Save/call it as "xcal9r.php" if you want it to see it work.

      <html> 
      <head> 
      <title>Joe's handy dandy calendar control</title> 
      <STYLE TYPE="text/css"> 
      .puny_yellow { 
      width: 20px; 
      height: 20px; 
      background-color:yellow; 
      border-color:efefef; 
      color: blue; 
      font-weight: bold; 
      font-family: arial, verdana, ms sans serif; 
      font-size: 8pt;} 
      
      .puny_red { 
      width: 20px; 
      height: 20px; 
      background-color:red; 
      border-color:efefef; 
      color: white; 
      font-weight: bold; 
      font-family: arial, verdana, ms sans serif; 
      font-size: 8pt;} 
      
      .puny_blue { 
      width: 20px; 
      height: 20px; 
      background-color:blue; 
      border-color:efefef; 
      color: white; 
      font-weight: bold; 
      font-family: arial, verdana, ms sans serif; 
      font-size: 8pt;} 
      </STYLE> 
      </head> 
      <body  style="font-family: Arial; font-size: 8pt"> 
      
      <? 
      // POSTED VALUES 
      foreach($_POST as $postkey=>$postval) {$$postkey=$postval;
      } 
      //echo "$$postkey:$postval<br>";} //DEBUG 
      // END POSTED VALUES 
      
      // Convert posted date string into time string 
      if(isset($raw_date) and $raw_date!="") { 
          $raw_time=strtotime($raw_date); 
          $datename="Selected date"; 
          } else { 
          $raw_time=strtotime(date('Y-m-d')); 
          $datename="Default date (today)";} 
      // END Convert posted date string into time string 
      
      //calendar form based on picked date 
      // Date formatted/parsed for various purposes 
      $firstday=date('m/1/Y',$raw_time); 
      $picked_date=date('Y-m-d',$raw_time); 
      $picked_comppart=date('Y-m-',$raw_time); // used for comparison and creating select date string buttons 
      $picked_mo_yr=date('Y-m', $raw_time);   
      $picked_topbar=date('F Y', $raw_time); $picked_month_length=date('t', $raw_time); $picked_month=date('m', $raw_time); //month without leading zero $picked_year=date('Y', $raw_time); $raw_time_firstday=strtotime($firstday); $picked_month_startday=date('m', $raw_time_firstday); //numeric value of the day of week 0=sunday 6=saturday $current_compstring=date('Y-m-d'); // used for comparison if it is TODAY $spacecounter=(1-$picked_month_startday); //starting point for the calendar date cells echo "Red cell shows current date<br>"; echo "Blue/clicked cell shows selected date<br>"; echo "$datename: $picked_date<br>"; // show the default date or the date that was picked echo "current compstring: $current_compstring<br>"; // show the default date or the date that was picked // figure out previous month and next month if($picked_month=="1") { $prev_yr=$picked_year-01; $prev_month="$prev_yr-12-01"; } else { $prev_mo=$picked_month-01; $prev_month="$picked_year-$prev_mo-01";} if($picked_month=="12") { $next_yr=$picked_year+1; $next_month="$next_yr-01-01"; } else { $next_mo=$picked_month+1; $next_month="$picked_year-$next_mo-01";}
      echo "<br>";
      // end figure out previous month and next month //a one month calendar control echo "<table>"; echo "<tr><th><form method=\"POST\" action=\"xcal9r.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$prev_month\"> <input type=\"submit\" value=\"<<\" class=\"puny_red\"> </th></form><th colspan=5>$picked_topbar</th><th><form method=\"POST\" action=\"xcal9r.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$next_month\"> <input type=\"submit\" value=\">>\" class=\"puny_red\"> </th></form></tr>"; echo "<form method=\"POST\" action=\"xcal9r.php\" target=\"_self\">"; echo "<tr><th>Su</th><th>Mo</th><th>Tu</th><th>We</th><th>Th</th><th>Fr</th><th>Sa</th></tr>"; $weeks=ceil($picked_month_length/7); //rounds upwards $week=0; $wkday=0; //start the first week for($week; $week <= $weeks; $week++) {echo "<tr>"; for($wkday; $wkday<=6; $wkday++) { if($spacecounter<10) { $compstring="$picked_comppart".'0'."$spacecounter"; } else { $compstring="$picked_comppart$spacecounter";} //echo "$compstring : $current_compstring<br>"; //DEBUG // this version is for PAST DATE selection...no dates beyond today can be picked. (line 119) if ($spacecounter < 1 ) {echo "<td align=center></td>";} //elseif ($compstring < $current_compstring) {echo "<td align=center>n/a</td>"; echo "FUTURE DATES ONLY<BR>";} //future dates //elseif ($compstring > $current_compstring) {echo "<td align=center>-</td>"; $week=$weeks;} //stops the cycle...no more rows needed // past dates only elseif (($compstring==$current_compstring) AND ($compstring==$picked_date)) {echo "<td align=right bgcolor=red><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_red\" checked> </td>";} elseif ($compstring==$current_compstring) {echo "<td align=right bgcolor=red><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_red\"> </td>";} elseif ($compstring==$picked_date) {echo "<td align=right bgcolor=blue><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_blue\" checked> </td>";} elseif ($spacecounter > $picked_month_length) {echo "<td align=center></td>";} else {echo "<td align=right bgcolor=yellow>$spacecounter <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_yellow\"> </td>";} // WEEKDAY SPACES $spacecounter++; } echo "</tr>"; $wkday=0; //resets the row counter } echo "</table>"; //END calendar form based on picked date echo "<input type=\"submit\" value=\"Save the date I clicked.\"></form>"; ?> </body></html>

      Dang! I just noticed this version is not starting at the correct at the correct day when you click to go to different months....thought I had that part licked.
      Back to the drawing board.

        Okay...this earlier version works properly "xcal8r.php"

        <html> 
        <head> 
        <title>Joe's handy dandy calendar control</title> 
        <STYLE TYPE="text/css"> 
        .puny_yellow { 
        width: 20px; 
        height: 20px; 
        background-color:yellow; 
        border-color:efefef; 
        color: blue; 
        font-weight: bold; 
        font-family: arial, verdana, ms sans serif; 
        font-size: 8pt;} 
        
        .puny_red { 
        width: 20px; 
        height: 20px; 
        background-color:red; 
        border-color:efefef; 
        color: white; 
        font-weight: bold; 
        font-family: arial, verdana, ms sans serif; 
        font-size: 8pt;} 
        
        .puny_blue { 
        width: 20px; 
        height: 20px; 
        background-color:blue; 
        border-color:efefef; 
        color: white; 
        font-weight: bold; 
        font-family: arial, verdana, ms sans serif; 
        font-size: 8pt;} 
        
        table {border-collapse: collapse;} 
        TH {color: white; background-color: navy; font-family: Arial; font-size: 8pt; padding: 0px;} 
        TD {font-family: Arial; font-size: 8pt; padding: 0px;} 
        
        </STYLE> 
        </head> 
        <body  style="font-family: Arial; font-size: 8pt"> 
        
        <? 
        // POSTED VALUES 
        foreach($_POST as $postkey=>$postval) {$$postkey=$postval;
        } 
        //echo "$$postkey:$postval<br>";} //DEBUG 
        // END POSTED VALUES 
        
        // Convert posted date string into time string 
        if(isset($raw_date) and $raw_date!="") { 
            $raw_time=strtotime($raw_date); 
            $datename="Selected date"; 
            } else { 
            $raw_time=strtotime(date('Y-n-j')); 
            $datename="Default date (today)";} 
        // END Convert posted date string into time string 
        
        //calendar form based on picked date 
        // Date formatted/parsed for various purposes 
        $firstday=date('n/1/Y',$raw_time); 
        $picked_date=date('Y-n-j',$raw_time); 
        $picked_comppart=date('Y-n-',$raw_time); // used for comparison and creating select date string buttons 
        $picked_mo_yr=date('Y-n', $raw_time);   
        $picked_topbar=date('F Y', $raw_time); $picked_month_length=date('t', $raw_time); $picked_month=date('n', $raw_time); //month without leading zero $picked_year=date('Y', $raw_time); $raw_time_firstday=strtotime($firstday); $picked_month_startday=date('N', $raw_time_firstday); //numeric value of the day of week 0=sunday 6=saturday $current_compstring=date('Y-n-j'); // used for comparison if it is TODAY $spacecounter=(1-$picked_month_startday); //starting point for the calendar date cells echo "Red cell shows current date<br>"; echo "Blue/clicked cell shows selected date<br>"; echo "$datename: $picked_date<br>"; // show the default date or the date that was picked echo "current compstring: $current_compstring<br>"; // show the default date or the date that was picked // figure out previous month and next month if($picked_month=="1") { $prev_yr=$picked_year-1; $prev_month="$prev_yr-12-1"; } else { $prev_mo=$picked_month-1; $prev_month="$picked_year-$prev_mo-1";} if($picked_month=="12") { $next_yr=$picked_year+1; $next_month="$next_yr-1-1"; } else { $next_mo=$picked_month+1; $next_month="$picked_year-$next_mo-1";}
        echo "<br>";
        // end figure out previous month and next month //a one month calendar control echo "<table>"; echo "<tr><th align=left><form method=\"POST\" action=\"xcal8r.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$prev_month\"> <input type=\"submit\" value=\"<<\" class=\"puny_red\"> </th></form><th colspan=5>$picked_topbar</th><th align=right><form method=\"POST\" action=\"xcal8r.php\" target=\"_self\"> <input type=\"hidden\" name=\"raw_date\" value=\"$next_month\"> <input type=\"submit\" value=\">>\" class=\"puny_red\"> </th></form></tr>"; echo "<form method=\"POST\" action=\"xcal8r.php\" target=\"_self\">"; echo "<tr><th>Su</th><th>Mo</th><th>Tu</th><th>We</th><th>Th</th><th>Fr</th><th>Sa</th></tr>"; $weeks=ceil($picked_month_length/7); //rounds upwards $week=0; $wkday=0; //start the first week for($week; $week <= $weeks; $week++) {echo "<tr>"; for($wkday; $wkday<=6; $wkday++) { $compstring="$picked_comppart$spacecounter"; //echo "$compstring : $current_compstring<br>"; //DEBUG if ($spacecounter < 1 ) {echo "<td align=center></td>";} //UN-COMMENT one of the following lines if you want to allow only past or future date selection //elseif ($compstring < $current_compstring) {echo "<td align=center>n/a</td>";} //no past dates //elseif ($compstring > $current_compstring) {echo "<td align=center>n/a</td>";} //no future dates elseif (($compstring==$current_compstring) AND ($compstring==$picked_date)) {echo "<td align=right bgcolor=red><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_red\" checked> </td>";} elseif ($compstring==$current_compstring) {echo "<td align=right bgcolor=red><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_red\"> </td>";} elseif ($compstring==$picked_date) {echo "<td align=right bgcolor=blue><font color=white>$spacecounter</font> <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_blue\" checked> </td>";} elseif ($spacecounter > $picked_month_length) {echo "<td align=center></td>";} else {echo "<td align=right bgcolor=yellow>$spacecounter <input type=\"radio\" name=\"raw_date\" value=\"$picked_comppart$spacecounter\" class=\"puny_yellow\"> </td>";} // WEEKDAY SPACES $spacecounter++; } echo "</tr>"; $wkday=0; //resets the row counter } echo "</table>"; //END calendar form based on picked date echo "<input type=\"submit\" value=\"Save the date I clicked.\"></form>"; ?> </body></html>

        ...but still, the steeenking radio buttons!

          I concede that that there's a slight learning curve, but your users will thank you when the page doesn't have to reload every time they choose a different date. What if a user picks the wrong date by accident? Then they may be stuck reloading the page multiple times. God forbid that your server actually becomes busy...that will really annoy people.

          I resisted Javascript too when I started building websites. But the bottom line is that you need to use some kind of CLIENT technology (as opposed to PHP, which is a SERVER techology) in order to do cool things on the client's browser. It isn't just expected, it's very nearly a requirement.

          That said, you CAN replace Javascript with other client technologies in certain instances. For example, CSS can do quite a bit on the client that it didn't do previously. In fact, a search of the web may turn up a more CSS-oriented calendar, but there is still going to be a little Javascript involved to make things happen on the client (i.e.- to make the CSS calendar appear, you will need to "unhide" it using Javascript, and to actually put the date in a text box).

            Thanks for that input. Not actually being a programmer, I have been getting by with php for my applications, and have been annoying my users with date-dropdowns all these years. Just before trying to figure out how to make this sort of control I was wondering if there was a way to do it without having to reload the page in order for the user to get to farther-back or farther-forward sets of dates. I did't know that that was the sort of thing that one could do with javascript. This does appear to be worth the effort. It would be better than my solutions because the pages where my users would encounter these calendar controls are already pretty server-intensive.

            Thanks for kicking me up the conceptual ladder!

              I am marking the thread resolved not because I got the answer I originally sought, but because ixalmida shifted my frame of reference. Trying to build this control with client-side coding like javascript will proably be a better approach.

              Thanks.

                Write a Reply...