[TYPO3-mvc] [INFO] How-to do AJAX with Extbase

Xavier Perseguers typo3 at perseguers.ch
Fri Jul 31 20:36:22 CEST 2009


Hi,

In an attempt to find best way to code with Extbase, we found today a 
solution to the AJAX problem when using Extbase.

In our mvc_extjs_samples extension, we started having some actions that 
returned JSON. But in order for us to only get this JSON and not the 
rest of the page, we had to end the action with an exit() statement. Not 
really pretty! But wait! Pagetypes are our friend! Why do we need to 
reinvent the wheel?

As such I rewrote part of the SimpleForm controller, namely the 
genresAction that output a list of movie genres as a JSON list:

/**
  * Returns a list of movie genres as JSON.
  *
  * @return void
  */
public function genresAction() {
	$genreRepository = 
t3lib_div::makeInstance('Tx_MvcExtjsSamples_Domain_Model_GenreRepository');
	/* @var $genreRepository Tx_MvcExtjsSamples_Domain_Model_GenreRepository */

		// Retrieve all genres from repository
	$genres = $genreRepository->findAll();

		// Convert Tx_MvcExtjsSamples_Domain_Model_Genre objects to an array
	$arr = Tx_MvcExtjsSamples_ExtJS_Utility::encodeArrayForJSON($genres);

		// Send the JSON response
	return Tx_MvcExtjsSamples_ExtJS_Utility::getJSON($arr);
}

This is thus pure Extbase without any hack.

Now we have to declare this action as non-cachable. After all, this is 
the purpose of an AJAX call not to be cached. This is easily done from 
ext_localconf.php:

Tx_Extbase_Utility_Plugin::configureDispatcher(
	'MvcExtjsSamples',
	'SimpleForm',
	array('SimpleForm' => 'index,genres'),
	array('SimpleForm' => 'genres')			// Action 'genres' is used for AJAX 
and thus should not be cached
);

Again, pure Extbase!

Now the trick is to get this AJAX call rendered with another PageType:

In ext_typoscript_setup.txt I put:

<INCLUDE_TYPOSCRIPT: 
source="FILE:EXT:mvc_extjs_samples/Configuration/TypoScript/ajax.txt">

And file ajax.txt is:

# Get your own typeNum with
# php -r 'echo time();'

ajax = PAGE
ajax {
		# You don't need to change this typeNum
	typeNum = 1249058000
	config {
		disableAllHeaderCode = 1
		additionalHeaders = Content-type:application/json
		xhtml_cleaning = 0
		admPanel = 0
	}
}

mvcextjssamples_simpleform < ajax
mvcextjssamples_simpleform {
	typeNum = 1249058991
	10 < tt_content.list.20.mvcextjssamples_simpleform
}

Pure TYPO3!

Now, I only should get an AJAX link that points to my "genres" action 
using PageType 1249058991 (I found this time() typeNum great as it has 
the same idea as for exception when coding, we are pretty sure an 
extension won't override another extension's AJAX definition).

Simply call the well-known URIBuilder from Extbase to get it:

$ajaxUrl = $this->URIBuilder->URIFor(NULL, 'genres', array(), NULL, 
NULL, NULL, 1249058971);

That's it! I can now output my Ext.data.Store and use that url as the 
Ext.data.HttpProxy url or any other AJAX action I need.

-- 
Xavier Perseguers
http://xavier.perseguers.ch/en

One contribution a day keeps the fork away


More information about the TYPO3-project-typo3v4mvc mailing list