Using requestAction & custom layouts to add XHR functionality

2 : Determine the XHR Elements

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.

The calendar will show information about a single month, and will provide navigation forward one month, and back one month. For regular viewers this will all be in one page. However I want to split this so my default view can load each element via XHR into specified areas of the page. So I split the requirements across more functions:

In the Controller controllers/calendar_controller.php I add:

Controller Class:

<?php 
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 
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);             
   }      
}
?>

the action calendarnavigation will provide links forward one month and back one month, based on the date specified. By default it chooses the current month and year. the action singlecalendar will show the calendar for the month and year specified. It too chooses the current month and year by default.

Custom Layouts for XHR

Each of these functions specifies it's own layout:



$this->layout = 'calendardynamic'; 
and

$this->layout = 'calendarnavigationdynamic'; 

These two layouts are for the dynamic XHR responses. But first we need to add another function so that the non-XHR viewers can see the calendar and navigation.

in controllers/calendar_controller.php

Controller Class:

<?php 
function generatecalendar($chooseYear=null,$chooseMonth=null) {
    
$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')));    
 } 
?>

Notice this latest action makes use of requestAction to call the other two actions needed to complete our page. requestAction and the custom layouts, are the glue for the whole method.

Without XHR, /calendar/generatecalendar can be called, which in turn calls the two components. Using requestAction calls the method internally so ignores the layouts views/layouts/singlecalendardynamic.thtml and views/layouts/calendarnavigationdynamic.thtml.

With XHR, the methods can be called directly, using their own layouts, producing the minimal code we need to update our areas of our page.

As it's just for test purposes, our singlecalendar method simply states it's month and year, but could be developed to show a tabled view of each day of the month.

Page 3: Views and layouts