PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Fri Sep 21, 2018 7:07 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: AJAX calendar
PostPosted: Wed May 17, 2006 11:33 am 
Offline
Briney Mod
User avatar

Joined: Mon Jan 19, 2004 7:11 pm
Posts: 6445
Location: 53.01N x 112.48W
Hi all,

I just finished making MY version of a date picker calendar. This one uses XMLHTTP (AJAX) to get PHP to generate the calendar. The visual part itself is thrown into the page, so there are no pop-ups. This uses DOM scripting and xmlhttp, so it's not backwards compatible with Netscape 2. Sorry.

Changing the appearance isn't ideally simple, but I didn't want to require modifications to a site's CSS file in order to change the appearance. So, everything's done with <style> tags and onMouseOver and onMouseOut. To change the appearance, just modify the $styles array at the top of the file.

$styles['current']['day'] defines the styles that are applied to the current month's weekdays,
$styles['current']['weekend'] defines the styles that are applied to the current month's weekend days
$styles['other']['day'] defines the styles that are applied to previous & last month's weekdays,
$styles['other']['weekend'] defines the styles that are applied to previous & last month's weekends days.
$styles['nav'] defines the styles applied to the 'next' and 'previous' links
$styles['date'] defines the styles applied to the date output in the header
$styles['th'] defines the styles applied to the whole header
$styles['td'] defines the styles applied to the calendar days
$styles['a'] defines the styles applied to the links in each day

'js' defines the string javascript will use to change this property
'css' defines the string that will be used in the <style> tags
'value' defines the initial and onMouseOut value of this property
'mouseovervalue' defines the value of this property defined onmouseover


Library
Syntax: [ Download ] [ Hide ]
<?PHP

//Released under the GPL license





//--------------------

// CONFIG



//set the styles of the calendar

$styles['current']['day'] = array(array('js'=>'backgroundColor',

                                        'css'=>'background-color',

                                        'mouseovervalue'=>'#FFFFFF',

                                        'value'=>'#d7e9ff'));

$styles['current']['weekend'] = array(array('js'=>'backgroundColor',

                                            'css'=>'background-color',

                                            'mouseovervalue'=>'#FFFFFF',

                                            'value'=>'#a7cbf5'));

$styles['other']['day'] = array(array('js'=>'backgroundColor',

                                      'css'=>'background-color',

                                      'mouseovervalue'=>'#FFFFFF',

                                      'value'=>'#afc3d9'));

$styles['other']['weekend'] = array(array('js'=>'backgroundColor',

                                          'css'=>'background-color',

                                          'mouseovervalue'=>'#FFFFFF',

                                          'value'=>'#d9e0e7'));

$styles['nav'] = array(array('js'=>'backgroundColor',

                             'css'=>'background-color',

                             'mouseovervalue'=>'#FFFFFF',

                             'value'=>'#5995de'),

                       array('js'=>'color',

                             'css'=>'color',

                             'mouseovervalue'=>'#333333',

                             'value'=>'#FFFFFF'),

                       array('js'=>'display',

                             'css'=>'display',

                             'mouseovervalue'=>'block',

                             'value'=>'block'),

                       array('js'=>'textDecoration',

                             'css'=>'text-decoration',

                             'mouseovervalue'=>'none',

                             'value'=>'none'));

$styles['th'] = 'background-color:#5995de;color:#fff;font-weight:bold;';

$styles['date'] = 'text-align:center;';

$styles['td'] = 'text-align:center;';

$styles['a'] = 'display:block;height:100%;text-decoration:none;padding:3px;';





//set the date format to return - use PHP's date() syntax

$date_format = 'd/m/Y';







// /CONFIG

// You shouldn't need to go beyond this point

//--------------------





if($_POST['mode'] == 'PHP')

{

  actAsPHP($styles,$date_format);

}

else

{

  actAsJavascript();

}







function actAsPHP($styles,$date_format)

{

  $id = $_POST['id'];





  if(isset($_POST['curr_stamp']))

  {

    $direction = ($_POST['direction'] == 'subtract') ? '-' : '+';

    $now = strtotime($direction.'1 month',$_POST['curr_stamp']);

  }

  else

  {

    $now = time();

  }



  $first_of_month = mktime(0,0,0,date('m',$now),1,date('y',$now));



 //-------------------

 //build the day array



 //get the Monday of the week that has the 1st of the month

 $first_day_stamp = $first_of_month;

 while(date('w',$first_day_stamp) > 0)

 {

   $first_day_stamp = strtotime('-1 day',$first_day_stamp);

 }



 //insert all days from last month

 $curr_stamp = $first_day_stamp;

 while($curr_stamp < $first_of_month)

 {

   $days[1][] = $curr_stamp;

   $curr_stamp = strtotime('+1 day',$curr_stamp);

 }



 //insert all days from this month

 $week = 1;

 while(date('n',$curr_stamp) == date('n',$first_of_month))

 {

   $days[$week][] = $curr_stamp;

   $week = (date('w',$curr_stamp)) == 6 ? $week + 1 : $week;

   $curr_stamp = strtotime('+1 day',$curr_stamp);

 }



 //insert all the days from next month

 while(date('w',$curr_stamp) > 0)

 {

   $days[$week][] = $curr_stamp;

   $curr_stamp = strtotime('+1 day',$curr_stamp);

 }



 //-----------------

 //display the table



 //open the table & display the navigation



 foreach($styles['nav'] as $property)

 {

   $style .= $property['css'].':'.$property['value'].';';

   $mouseOver .= 'this.style.'.$property['js']."='".$property['mouseovervalue']."';";

   $mouseOut .= 'this.style.'.$property['js']."='".$property['value']."';";

 }



 $monthyear = date('M \'y',$first_of_month);

 echo <<<TABLE

        <table cellspacing = '1' style = '$styles[table]'>

          <tr>

            <th style = '$styles[th]' colspan = '2'>

              <a href = "javascript&#058;void(0);" style = "$style" onmouseover = "$mouseOver" onmouseout = "$mouseOut" onClick = "loadDate('$id','$first_of_month','subtract');">

                &laquo;

              </a>

            </th>

            <th colspan = '3' style = '$styles[th] $styles[date]'>

              $monthyear

            </th>

            <th style = '$styles[th]' colspan = '2'>

              <a href = "javascript&#058;void(0);" style = "$style" onmouseover = "$mouseOver" onmouseout = "$mouseOut" onClick = "loadDate('$id','$first_of_month','add');">

                &raquo;

              </a>

            </th>

          </tr>

TABLE
;

 





 foreach($days as $week)

 {

   echo '<tr>';

   foreach($week as $day)

   {

     //setup how the day should look

     if(date('n',$day) != date('n',$first_of_month))

       if(date('w',$day) == 0 || date('w',$day) == 6)

         $style_properties = $styles['other']['weekend'];

       else

         $style_properties = $styles['other']['day'];

     else

       if(date('w',$day) == 0 || date('w',$day) == 6)

         $style_properties = $styles['current']['weekend'];

       else

         $style_properties = $styles['current']['day'];



     unset($style);

     unset($mouseOver);

     unset($mouseOut);



     foreach($style_properties as $property)

     {

       $style .= $property['css'].':'.$property['value'].';';

       $mouseOver .= 'this.style.'.$property['js']." = '".$property['mouseovervalue']."';";

       $mouseOut .= 'this.style.'.$property['js']." = '".$property['value']."';";

     }



     $day_of_month = date('j',$day);

     $click_val = date($date_format,$day);

     echo <<<CELL

            <td style = '$styles[td]'>

              <a href = "javascript&#058;void(0);"

                 style = '$styles[a] $style'

                 onMouseOver = "$mouseOver"

                 onMouseOut = "$mouseOut"

                 onClick = "document.getElementById('$id').value = '$click_val';document.getElementById('$id').style.display = 'block';document.getElementById('$id').focus();divNode = document.getElementById('calendar');divNode.parentNode.removeChild(divNode);">$day_of_month

</a>

            </td>

CELL
;

   }

   echo '</tr>';

 }

 echo '</table>';

}//function: actAsPHP()



function actAsJavascript()

{

  $uri = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];

  header('Content-type: text/javascript;');

 

  echo <<<JAVASCRIPT

    function loadDate(pFieldID)

    {

      try

      {

        if(window.XMLHttpRequest)

        {

          reqsend = new XMLHttpRequest();

        }

        else

        {

          reqsend = new ActiveXObject("Microsoft.XMLHTTP");

        }

      }

      catch(e)

      {

        alert('Your browser does not support XMLHTTP.');

      }



      try

      {

        reqsend.open("POST",'$uri');

        reqsend.setRequestHeader("Content-Type","application/x-www-form-urlencoded");



        post = "mode=PHP&id=" + pFieldID;



        //'arguments' is a JS construct that represents

        //all the arguments sent to a function

        if(arguments[1])

        {

          post = post + '&curr_stamp=' + arguments[1] + '&direction=' + arguments[2];

        }

        reqsend.setRequestHeader("Content-Length",post.length);

        reqsend.send(post);

        reqsend.onreadystatechange = function()

        {

          if(reqsend.readyState == 4 && reqsend.status == 200)

          {

            var responseText = reqsend.responseText;



            //create the new div

            //it's not inserted into the document yet

            calendarDiv = document.createElement('div');

            calendarDiv.setAttribute('id','calendar');



            //remove the div if it exists

            //this avoids duplication of the calendar in the document

            if(document.getElementById('calendar'))

            {

              calendarDiv = document.getElementById('calendar');

              calendarDiv.parentNode.removeChild(calendarDiv);

            }

 

            //insert the new div into the document

            pField = document.getElementById(pFieldID);

            pField.parentNode.appendChild(calendarDiv);



            //hide the text field it's replacing

            document.getElementById(pFieldID).style.display = 'none';



            //fill the new div

            document.getElementById('calendar').innerHTML = responseText;

          }

        };

      }

      catch(e)

      {

        alert(e);

      }

    }

JAVASCRIPT
;

}

?>

 



Example usage
Syntax: [ Download ] [ Hide ]
<html>

  <head>

    <script src = "calendar.php"></script>

  </head>

  <body>

    <input type = "text" id = "test2" onclick = "loadDate('test2');" value = 'Click me!'>

  </body>

</html>

 


You can see this in use here: http://www.nderson.ca/misc/calendar/test.php

_________________
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.


Last edited by pickle on Thu May 18, 2006 12:46 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 1:38 am 
Offline
Forum Regular

Joined: Tue Jul 05, 2005 3:54 am
Posts: 945
Location: Sofia, Bulgaria
I cant seem to get this working. Trying the url you provided.
When I click it returns.
Using Firefox 1.5.0.1


[Exception... "'Permission denied to set property XULElement.selectedIndex' when calling method: [nsIAutoCompletePopup::selectedIndex]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "JS frame :: http://www.nderson.ca/misc/calendar/test.php :: anonymous :: line 0" data: no]test.php (line 0)
[Exception... "'Permission denied to set property XULElement.selectedIndex' when calling method: [nsIAutoCompletePopup::selectedIndex]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "JS frame :: http://www.nderson.ca/misc/calendar/test.php :: anonymous :: line 0" data: no]


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 7:02 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
jmut wrote:
I cant seem to get this working. Trying the url you provided.
When I click it returns.
Using Firefox 1.5.0.1


[Exception... "'Permission denied to set property XULElement.selectedIndex' when calling method: [nsIAutoCompletePopup::selectedIndex]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "JS frame :: http://www.nderson.ca/misc/calendar/test.php :: anonymous :: line 0" data: no]test.php (line 0)
[Exception... "'Permission denied to set property XULElement.selectedIndex' when calling method: [nsIAutoCompletePopup::selectedIndex]" nsresult: "0x8057001e (NS_ERROR_XPC_JS_THREW_STRING)" location: "JS frame :: http://www.nderson.ca/misc/calendar/test.php :: anonymous :: line 0" data: no]


Using FF 1.5.0.3 (Linux) Works nicely for me :)


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 7:16 am 
Offline
DevNet Master
User avatar

Joined: Tue Nov 02, 2004 6:43 am
Posts: 2704
Location: Ireland
Firefox 1.5.0.3 for Windows likewise works.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 8:15 am 
Offline
Forum Regular

Joined: Tue Jul 05, 2005 3:54 am
Posts: 945
Location: Sofia, Bulgaria
:)
guess it is time for an upgrade.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 10:05 am 
Offline
Briney Mod
User avatar

Joined: Mon Jan 19, 2004 7:11 pm
Posts: 6445
Location: 53.01N x 112.48W
I'm not doubting you get that error, but nonetheless it makes no sense. That error seems like it should pop up when there's a problem with a drop-down list - dunno why it's popping up here.

_________________
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:05 pm 
Offline
Forum Commoner
User avatar

Joined: Thu Jan 26, 2006 4:38 am
Posts: 46
Location: Bath, UK
works on Firefox 1.0.7, Opera 8.52, Safari 2.0.3 on the mac but (not surprisingly!) Internet Explorer 5.2 doesn't support XMLHTTP (gotta love microsoft and their half hearted attempt to created a less than half decent browser for the mac).

good stuff! keep up the good work


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:18 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
tasteslikepurple wrote:
works on Firefox 1.0.7, Opera 8.52, Safari 2.0.3 on the mac but (not surprisingly!) Internet Explorer 5.2 doesn't support XMLHTTP (gotta love microsoft and their half hearted attempt to created a less than half decent browser for the mac).

good stuff! keep up the good work


IE does support XMLHTTP they just decided to dilly-dally around using XMLHttpRequest and invent their own. Now I have to make a point here though in Microsoft's favour. Microsoft invented XMLHTTP.

In IE you use an ActiveX control called XMLHTTP. It's pretty easy to roll your own function to return an XMLHttpRequest object or an activeX object depending upon what's avilable ;)

EDIT | I'm terribly sorry I totally mis-read the whole thing about the Mac and version 5.2 of IE :oops:


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:27 pm 
Offline
Spockulator
User avatar

Joined: Wed Feb 04, 2004 9:15 pm
Posts: 4713
Location: Eden, Utah
nice work pickle.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:36 pm 
Offline
Briney Mod
User avatar

Joined: Mon Jan 19, 2004 7:11 pm
Posts: 6445
Location: 53.01N x 112.48W
Thanks everyone!

_________________
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:39 pm 
Offline
Tutorials Group

Joined: Sun Jan 04, 2004 11:30 pm
Posts: 2692
What license? BSDL? Free-to-use? GPL?


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:45 pm 
Offline
Briney Mod
User avatar

Joined: Mon Jan 19, 2004 7:11 pm
Posts: 6445
Location: 53.01N x 112.48W
Yep.

Um... GPL I guess
(updated the code to say as much)

_________________
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 12:50 pm 
Offline
Forum Commoner
User avatar

Joined: Thu Jan 26, 2006 4:38 am
Posts: 46
Location: Bath, UK
d11wtq wrote:
tasteslikepurple wrote:
works on Firefox 1.0.7, Opera 8.52, Safari 2.0.3 on the mac but (not surprisingly!) Internet Explorer 5.2 doesn't support XMLHTTP (gotta love microsoft and their half hearted attempt to created a less than half decent browser for the mac).

good stuff! keep up the good work


IE does support XMLHTTP they just decided to dilly-dally around using XMLHttpRequest and invent their own. Now I have to make a point here though in Microsoft's favour. Microsoft invented XMLHTTP.

In IE you use an ActiveX control called XMLHTTP. It's pretty easy to roll your own function to return an XMLHttpRequest object or an activeX object depending upon what's avilable ;)

EDIT | I'm terribly sorry I totally mis-read the whole thing about the Mac and version 5.2 of IE :oops:


easily done :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 6:22 am 
Offline
Forum Newbie

Joined: Tue Sep 26, 2006 5:18 am
Posts: 1
Location: Paris, France
Nice code but I made 2 modifications :

- The calendar doesn't work before 1970. To correct this, change :
Syntax: [ Download ] [ Hide ]
$first_of_month = mktime(0,0,0,date('m',$now),1,date('y',$now));

into
Syntax: [ Download ] [ Hide ]
$first_of_month = mktime(0,0,0,date('m',$now),1,date('Y',$now));

Yeah, a simple case change for just one can change everything :)

- It would be great to show the calendar with another month than the current one. To do this, I changed the beginning of the actAsPHP function :
Syntax: [ Download ] [ Hide ]
function actAsPHP($styles,$date_format)

{

  $id = $_POST['id'];



  if(isset($_POST['curr_stamp']))

  {

        if (isset($_POST['direction'])) {

            $direction = ($_POST['direction'] == 'subtract') ? '-' : '+';

        $now = strtotime($direction.'1 month',$_POST['curr_stamp']);

        } else {

                $now = $_POST['curr_stamp'];

        }

  }

  else

  {

    $now = time();

  }

[...]

and the Javascript part :
Syntax: [ Download ] [ Hide ]
[...]

        //'arguments' is a JS construct that represents

        //all the arguments sent to a function

        if(arguments[1])

        {

          post = post + '&curr_stamp=' + arguments[1];

                 

                  if (arguments[2]) {

                        post = post + '&direction=' + arguments[2];

                  }

        }

[...]

Now you can call loadDate with the wanted timestamp as a second argument.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 9:48 am 
Offline
Briney Mod
User avatar

Joined: Mon Jan 19, 2004 7:11 pm
Posts: 6445
Location: 53.01N x 112.48W
Nice additions. I'll add them to the code.

_________________
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group