Follow Sebastiaan de Jonge on Twitter
Sebastiaan de Jonge

Blog

21Sep

Bringing AJAX to your frontend plugins

Posted on September 21, 2010 in Extension Development,jQuery by Sebastiaan de Jonge

When designing and creating cool and fast web applications, a technique called AJAX is commonly used to provide the user with a nice and smooth workflow. It allows the user to get new information from the server-side, without having to deal with page reloads. TYPO3 has some cool features that allow you to easily combine AJAX with TYPO3, to make awesome web applications.

In my example I will combine TYPO3 and the jQuery framework to show how easy it is to implement AJAX into your TYPO3 web app. Of course, you are not bound to using jQuery. Any library, framework or even a small self-written AJAX script will do. However in this example we'll use jQuery.

Let's get started

For starters we are going to create a TYPO3 extension. I assume you have mastered this process, so I'm going to skip the absolute basics. Simply create an extension with one frontend plugin in the kickstarter or by hand if you prefer.

I want my extension to do something simple, but something only the server can do. So in this example the extension will generate a sha1 hash of the string that can be entered by the user. Without reloading the page of course. I will start with some simple HTML, to make it easier I will not use any templating. The main() function of my plugin contains the following code.

class.tx_sdjfeajax_pi1.php 
  1. $content='
  2.         <h1>SHA1 it!</h5>
  3.         <form action="'.$this->pi_getPageLink($GLOBALS['TSFE']->id).'" method="POST">
  4.                 <input type="text" id="'.$this->prefixId.'_in" name="'.$this->prefixId.'[in]" value="'.htmlspecialchars($this->piVars['in']).'">
  5.                 <input type="submit" id="'.$this->prefixId.'_submit" name="'.$this->prefixId.'[submit_button]" value="SHA1 IT!">
  6.         </form>
  7. ';
  8.  
  9. $content .= '<p id="the-result">';
  10. if(!empty($this->piVars['in'])) {
  11.         $content .= 'SHA1: '.sha1($this->piVars['in']);
  12. }
  13. $content .= '</p>';
  14.  
  15. return $content;
$content='
	<h1>SHA1 it!</h5>
	<form action="'.$this->pi_getPageLink($GLOBALS['TSFE']->id).'" method="POST">
		<input type="text" id="'.$this->prefixId.'_in" name="'.$this->prefixId.'[in]" value="'.htmlspecialchars($this->piVars['in']).'">
		<input type="submit" id="'.$this->prefixId.'_submit" name="'.$this->prefixId.'[submit_button]" value="SHA1 IT!">
	</form>
';

$content .= '<p id="the-result">';
if(!empty($this->piVars['in'])) {
	$content .= 'SHA1: '.sha1($this->piVars['in']);
}
$content .= '</p>';

return $content;

You already see a condition here. This is to still process the request in case JavaScript is not enabled. This is a little extra, of course you are free to choose if you want to provide your users with this. This function gives the following output:

Including AJAX

There are a couple of steps we need to take to make this work with AJAX. First of all we need some library or framework to make AJAX requests with. I will use jQuery, since it's stable and one of the easiest frameworks to use. Making an AJAX request with jQuery is going to look like this.

Making the AJAX request 
  1. $(document).ready(function() {
  2.         $('#tx_sdjfeajax_pi1_submit').click(function(){
  3.                 $.ajax({
  4.                         url: 'index.php',
  5.                         data: {
  6.                                 eID: 'sha1Converter',
  7.                                 tx_sdjfeajax_pi1: ({
  8.                                         'in': $('#tx_sdjfeajax_pi1_in').val()
  9.                                 })
  10.                         },
  11.                         success: function(data) {
  12.                                 $('#the-result').html(data);
  13.                         }
  14.                 });
  15.                 return false;
  16.         });
  17. });
$(document).ready(function() {
	$('#tx_sdjfeajax_pi1_submit').click(function(){
		$.ajax({
			url: 'index.php',
			data: {
				eID: 'sha1Converter',
				tx_sdjfeajax_pi1: ({
					'in': $('#tx_sdjfeajax_pi1_in').val()
				})
			},
			success: function(data) {
				$('#the-result').html(data);
			}
		});
		return false;
	});
});

Telling TYPO3 about your AJAX plans

In order for TYPO3 to know what to do, you will need a small configuration inside your extensions' ext_localconf.php. Here we enter the following line:

Binding your eID 
  1. $TYPO3_CONF_VARS['FE']['eID_include']['sha1Converter'] = 'EXT:sdj_fe_ajax/pi1/ajaxRequestHandler.php';
$TYPO3_CONF_VARS['FE']['eID_include']['sha1Converter'] = 'EXT:sdj_fe_ajax/pi1/ajaxRequestHandler.php';

This tells TYPO3, what script should be used when 'sha1Converter' is called. Which is in this case 'ajaxRequestHandler.php'. The code for this file is really simple. Since in this example we only hash a string into SHA1, we will just execute the function sha1() inside our handler file.

ajaxRequestHandler.php 
  1. <?php 
  2. $piVars = t3lib_div::_GP('tx_sdjfeajax_pi1');
  3. echo 'SHA1: '.sha1($piVars['in']);
  4. ?>
<?php
$piVars = t3lib_div::_GP('tx_sdjfeajax_pi1');
echo 'SHA1: '.sha1($piVars['in']);
?>

Limitations

To speed up the process of your AJAX request, many components are not loaded and initialized. This means that by default, you will only have access to some basic components. In my followup post I will explain how several things can be invoked manually, to extend the functionality of your AJAX request.

Try it yourself

As usual, I have attached the demo extension to this post. It's bundled with jQuery 1.4.2. To load the required scripts you will need to include the static template that is provided. A live demo is available at this location: http://sebastiaandejonge.com/examples/frontend-ajax-demo/

Attached files

Arrow downsdj_fe_ajax-1.0.0.t3x
31 K

Comments (7)

  1. Gravatar: Pim BroensPim Broenson September 22, 2010
    at 08:00
    Reply to this comment

    Good start

    Now let's see the manually invoking part. Wondering how far you were able to get this.
    Should come in pretty handy with a lot of things.

  2. Gravatar: Nitin SewtahalsingNitin Sewtahalsingon February 17, 2011
    at 15:58
    Reply to this comment

    Build cObj

    To build the cObj in de handler class:

    /**
    * Build cObj
    *
    * @return object $cObj
    */
    function build_cObj() {
    require_once(PATH_tslib.'class.tslib_fe.php');
    require_once(PATH_t3lib.'class.t3lib_userauth.php' );
    require_once(PATH_tslib.'class.tslib_feuserauth.php');
    require_once(PATH_t3lib.'class.t3lib_cs.php');
    require_once(PATH_tslib.'class.tslib_content.php') ;
    require_once(PATH_t3lib.'class.t3lib_tstemplate.php');
    require_once(PATH_t3lib.'class.t3lib_page.php');

    $TSFEclassName = t3lib_div::makeInstanceClassName('tslib_fe');
    $id = isset($HTTP_GET_VARS['id'])?$HTTP_GET_VARS['id']:0;

    $GLOBALS['TSFE'] = new $TSFEclassName($TYPO3_CONF_VARS, $id, '0', 1, '','','','');
    $GLOBALS['TSFE']->connectToMySQL();
    $GLOBALS['TSFE']->initFEuser();
    $GLOBALS['TSFE']->fetch_the_id();
    $GLOBALS['TSFE']->getPageAndRootline();
    $GLOBALS['TSFE']->initTemplate();
    $GLOBALS['TSFE']->tmpl->getFileName_backPath = PATH_site;
    $GLOBALS['TSFE']->forceTemplateParsing = 1;
    $GLOBALS['TSFE']->getConfigArray();

    $cObj = t3lib_div::makeInstance('tslib_cObj');
    return $cObj;
    }

  3. Gravatar: PatriciaPatriciaon October 3, 2011
    at 19:57
    Reply to this comment

    url

    Hi,

    One little question: why have you used 'index.php' as the url for the ajax call? I am not sure what I should put there..

    Thank you

  4. Gravatar: Sebastiaan de JongeSebastiaan de Jongeon October 3, 2011
    at 20:51

    RE: url

    Hi Patricia,

    The index.php file is the main PHP file within TYPO3 which processes all frontend requests. So all AJAX requests are also automatically processed through this file. If you are creating your own AJAX call on the TYPO3 frontend you don't need to change this.

    Cheers

  5. Gravatar: PatriciaPatriciaon October 4, 2011
    at 15:57
    Reply to this comment

    jQuery function

    Me again.. :) Thank you for your answer.

    I tried writing the jQuery function in a separate file called 'ajaxDisplayXml.js'. Then I added this in the static/setup.txt of my extension:
    page.includeJS >
    page.includeJS{
    jquery = EXT:xml_displayer/res/jQuery/jquery-1.4.2.min.js
    ajaxDisplayXml = EXT:xml_displayer/res/jQuery/ajaxDisplayXml.js
    }

    This didn't work.. How should I include the jQuery function?

    Thanks

  6. Gravatar: PatriciaPatriciaon October 4, 2011
    at 17:40
    Reply to this comment

    works! :)

    It seems that there was an error in my js file.. It's all working now.

    Many thanks. :)

  7. Gravatar: sivaprasadsivaprasadon April 28, 2012
    at 12:43
    Reply to this comment

    Typo3 Backend Example

    Hi greetings

    I am developing a new backend extention in typo3 which includes some ajax purpose .Can u please explain me how the backend module supports ajax call . Am new to typo3 .

Got something to say?

 
Notify me when someone adds another comment to this post
 

Search

Categories

Tags

Archive

Blogroll

Syndicate