Using requestAction & custom layouts to add XHR functionality

5 : Full, final code listing

By A.Doherty (am_d)
This tutorial outlines a method for creating or modifying Cake apps that work swiftly for XHR(XmlHTTPRequest)-enabled clients and degrade well to non-XHR/AJAX (even javascript disabled) clients. The guidance provided here will be most suitable to newly converted Bakers. It simply outlines some of Cake's many flexible features and shows how using them in combination can bring rapid returns.
models/calendar.php

Model Class:

<?php class Calendar extends AppModel {
   var 
$name 't1';   
}
?>




controllers/calendar_controller.php

Controller Class:

<?php class CalendarController extends AppController {
 function 
index() {
    }
 function 
calendarnavigation($chooseYear=null,$chooseMonth=null) {
    
$this->layout 'calendarnavigationdynamic'
    
$y = ($chooseYear)?(int)$chooseYear:date("Y",mktime());
    
$m = ($chooseMonth)?(int)$chooseMonth:date("n",mktime());
    
$this->set('calYearInt'$y); 
    
$this->set('calMonthInt'$m);    
 }
 function 
generatecalendar($chooseYear=null,$chooseMonth=null) {
    
// Create defaults for Year and Month
    
$y = ($chooseYear)?(int)$chooseYear:date("Y",mktime());
    
$m = ($chooseMonth)?(int)$chooseMonth:date("n",mktime());
    
    
$this->set('calYearInt'$y); 
    
$this->set('calMonthInt'$m); 
    
    
$this->set('calendar'$this->requestAction('/Calendar/singlecalendar/'.$y.'/'.$m, array('return'))); 
    
$this->set('calendarnavigation'$this->requestAction('/Calendar/calendarnavigation/'.$y.'/'.$m , array('return')));    
 }   
 function 
singlecalendar($chooseYear=null,$chooseMonth=null ) {
   
    
$this->layout 'calendardynamic'
    
    
$y = ($chooseYear)?(int)$chooseYear:date("Y",mktime());
    
$m = ($chooseMonth)?(int)$chooseMonth:date("n",mktime());
    
$this->set('calYearInt'$y); 
    
$this->set('calMonthInt'$m);             
   }      
}
?>


Views


views/calendar/index.thtml

View Template:

<h1>Calendar Index</h1><br />
 <p>non-XHR, non javascript: <a href="/calendar/generatecalendar">Click this link to go to the Calendar Page</a></p>
 <br />
<p>XHR/AJAX,javascript: <a href="#" id="calendarGen">Click this link to load The XHR Calendar</a></p>
<br />
<p>Download: <a href="/addingXHR.rar">Right-click->save this link to download the example files</a></p>
<br />
<br />
<div style="font-weight:bold;font-size:120%;padding3px;">This is the Calendar Nav Div ↓ </div>
<div id="calendarNavDiv" style="border:1px solid black;margin-top:.1em;">

The Calendar Navigation will load here

</div>
<br /><br />
<div style="font-weight:bold;font-size:120%;padding3px;">This is the Calendar Div ↓ </div>
<div id="calendarDiv" style="border:1px solid black;margin-top:.1em;">

The Calendar will load here
</div>
<script type="text/javascript">
 
$('calendarGen').addEvent('click', function(e) {
    e = new Event(e).stop();
     var url = "/calendar/singlecalendar";
     new Ajax(url, {
        method: 'get',
        onRequest:  function(){
                 $('calendarDiv').setStyle('border','12px solid red');
            },
        onSuccess:  function(){
                 $('calendarDiv').setStyle('border','1px dotted blue');
            }, 
        update: $('calendarDiv')
    }).request();
});
$('calendarGen').addEvent('click', function(e) {
    e = new Event(e).stop();
     var url = "/calendar/calendarnavigation";
     /**
     * The simple way for an Ajax request, use onRequest/onComplete/onFailure
     * to do add your own Ajax depended code.
     */
    new Ajax(url, {
        method: 'get',
        evalScripts: true,
        onRequest:  function(){
                 $('calendarNavDiv').setStyle('border','12px solid red');
            }, 
        onSuccess:  function(){
                 $('calendarNavDiv').setStyle('border','1px dotted blue');
            }, 
        update: $('calendarNavDiv')
    }).request();
});
</script>



views/calendar/calendarnavigation.thtml

View Template:

<?php
$calMonthInt 
= (strlen($calMonthInt) ==1)?"0".$calMonthInt :$calMonthInt ;
$YYYYMM  $calYearInt.'-'.$calMonthInt.'';
$firstDayOfMonthUnixTimestamp strtotime($YYYYMM);
$viewingMonth date("F",$firstDayOfMonthUnixTimestamp);
$viewingYear date("Y",$firstDayOfMonthUnixTimestamp);
 
//next month
$nextMonthText date('F Y',strtotime("+1 months",$firstDayOfMonthUnixTimestamp)).">>";
// previous month
$previousMonthText "<<".date('F Y',strtotime("-1 months",$firstDayOfMonthUnixTimestamp));
 
//next month link
 
$nextMonthLink "/calendar/generatecalendar/".date('Y\/m',strtotime("+1 months",$firstDayOfMonthUnixTimestamp));
 
// previous month link
 
$previousMonthLink "/calendar/generatecalendar/".date('Y\/m',strtotime("-1 months",$firstDayOfMonthUnixTimestamp));
?>
<div id="calendar_navigation" style="text-align:center;">
<?php echo $html->link($previousMonthText,$previousMonthLink); ?>         
<?php echo $viewingMonth ?> <?php echo $viewingYear ?>           
<?php  echo $html->link($nextMonthText,$nextMonthLink); ?> 
</div>


views/calendar/singlecalendar.thtml

View Template:

<?php
$calMonthInt 
= (strlen($calMonthInt) ==1)?"0".$calMonthInt :$calMonthInt ;
$YYYYMM  $calYearInt.'-'.$calMonthInt.'';
$firstDayOfMonthUnixTimestamp strtotime($YYYYMM);
$viewingMonth date("F",$firstDayOfMonthUnixTimestamp);
$viewingYear date("Y",$firstDayOfMonthUnixTimestamp);
echo 
"this is the Calendar for <h2>".$viewingMonth"</h2><h3>"$viewingYear."</h3><br />";
 
?>


views/calendar/generatecalendar.thtml

View Template:

<h1>Calendar Non-XHR</h1><br />
<p><a href="/calendar/">Return to Calendar home</a></p><br />
<div style="padding:1em;border:2px solid green;">
<?php echo $calendarnavigation?>
</div>
<br />
<div style="padding:1em;border:2px solid green;">
<?php echo $calendar?>
</div>


Layouts



views/layouts/default.thtml

View Template:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title><?php echo $title_for_layout ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="/js/mootools.v1.1.js"></script>
</head>
<body>
<div id="outermost">
<div id="outermostInner">
    <div id="content">
        <div id="contentPad">
            <?php echo $content_for_layout ?>
        </div>
    </div>
    <div style="margin-top:20px;font-size:80%;color:#fff;">
    <?php
        
echo  " ".date("M d Y H:i",mktime()) .", timezone: ".date(" \G\M\T O",mktime()) ."";   
    
?>  
    </div>     
</div>
</div>    
</body></html>


views/calendar/calendardynamic.thtml

View Template:

<div style="background-color:#fff;padding:2em;">
<?php echo $content_for_layout ?>
</div>


views/calendar/calendarnavigationdynamic.thtml

View Template:

<div id="calendar_navigation" style="background-color:#e0e0e0;padding:2em;">
<?php echo $content_for_layout ?>
</div>
<script type="text/javascript">
 
 $$('#calendar_navigation a').each(function(el){
 var url =  el.getProperty('href');
 url = url.replace(/generatecalendar/,'singlecalendar');
 
 
 el.addEvent('click', function(e) {
 e = new Event(e).stop();
 e.preventDefault();
 
    new Ajax(url, {
        method: 'get',
        onRequest:  function(){
              $('calendarDiv').setStyle('border','12px solid red');
            },
        onSuccess:  function(){
                 $('calendarDiv').setStyle('border','1px dotted blue');
                 UpdateNav(url);
            }, 
        update: $('calendarDiv')
    }).request();
    
    
    //
    function UpdateNav(url) {
    url = url.replace(/singlecalendar/,'calendarnavigation');
 
    new Ajax(url, {
        method: 'get',
        evalScripts: true,
        onRequest:  function(){
                 $('calendarNavDiv').setStyle('border','12px solid red');
            },
        onSuccess:  function(){
                 $('calendarNavDiv').setStyle('border','1px dotted blue');
            }, 
        update: $('calendarNavDiv')
    }).request();
    
    }
});

 
 
});
 
</script>