Use AJAX with modxAPI

From MODx Wiki

Jump to: navigation, search

You want to create AJAX stuff in modx? Find below 2 possible solutions to do that

Contents

Introduction

The first one called "Full MODx solution" which offers a full access to MODx API

The second one called "Lightweight solution"

The recipe Three layers of code

To use modx API in AJAX calls we need to create 3 files: 2 php files + 1 javascript file

1 controller program (snippet or standalone php program) for backend stuff

1 view snippet for frontend stuff (forms who sends data to backend program)

1 javascript file to handle the AJAX connection (we use mootools to achieve this)

The Full MODx solution

In this example we would like to display ditto results.

Ingredients

Javascript file

window.addEvent('load', function() {
	var element = $('container');
	var mySlider = new Fx.Slide(element, {duration: 500,transition: Fx.Transitions.backOut});
	$('demoForm').addEvent('submit', function(e) {
		mySlider.hide()
		new Event(e).stop();
		//asuming that the backend snippet is located in document 22
		new Ajax("[~22~]",{
		//get all the variable/value pairs from the form
			postBody:$('demoForm').toQueryString(),
			onComplete:showResponse,
			update:element
		}).request();
	});
 
	function showResponse(request){
		mySlider.hide()
		mySlider.toggle() //toggle the slider up and down.
	}
})

frontend snippet

<?php
	$modx->regClientStartupScript("manager/media/script/mootools/mootools.js"); 
	$modx->regClientStartupScript("[~21~]");//asuming that my javascript file for do the trick is located in the document 21
 
	switch($action){
		//each case will have a mirror in the backend snippet
		//in this example we will call a simple ditto snippet
		//for this example i use a container div for update the content via ajax
		//the most important line of code of this form is the hidden input, because this line has the action for the backend
		case "dittoAjax":
		//asuming that the backend snippet is located in document 22
			$output ='
				<form method="post" action="[~22~]" id="demoForm">
				<input id="action" name="action" type="hidden" value="dittoAjax" />
				<button type="submit">run ditto</button>
				</form><br/><br/><div id="container"></div>';
 
			echo $output;	
     
		break;
}
?>

backend snippet

<?php
 
	$action=$modx->db->escape($_POST['action']);
 
	switch($action){
		case "dittoAjax":
 
			$params['startID'] = 0;
			$params['display'] = 5;
			$params['randomize'] = 1;
 
			$html = $modx->runSnippet('Ditto', $params);
			echo $html."<br/></div>";//this is for adjusting some error with the animation in safari
		break;
}
?>

How to cook the files

We need to make three documents in the modx manager, one for the javascript file, one for the frontend snippet and one for the backend snippet. Both the backend and the javascript documents must not have a template assigned, just set that to blank <- this is really important! Also make sure to set the content type for the javascript document to "text/javascript"! In the backend documents' content field just enter [[nameOfBackendSnippet]], the javascript code is pasted directly into the javascript document.

The frontend snippet will be placed in any document you want, and you need to call it [!anyName? &action=`dittoAjax`!] to make appear the form that will call the backend part via the javascript mootools function for handling the ajax calls.

If you want more functionality in your ajax framework, you only need to add more cases in both snippets.

If anyone uses this technique or wants to do so (or knows how to perfect it...) please visit me at dospuntocero.cl and drop me a line ;)

Lightweight solution

We will take as example the display of informations (member card) of a "member" from a member list

Ingredients

Javascript file : assets/snippets/memberList/js/memberList.js

// Frontend Snippet folder location
var _base = 'assets/snippets/memberList/';
 
window.addEvent('domready', function(){
		
    lis = $$("#memberlist li");
    for(i=0;i<lis.length;i++){
        li = lis[i];
        li.addEvent('click', function(e) {
            e = new Event(e).stop();
      				
      			var url = _base + 'memberCard.php';
      				
      			var pars = Object.toQueryString({
      				  q: url,
                id: this.id
            });
 
            new Ajax('index-ajax.php', {postBody: pars, update: $('card') }).request();
            });
    }
});

frontend snippet : assets/snippets/memberList/memberList.php.tpl

<?php
 
  $modx->regClientStartupScript("manager/media/script/mootools/mootools.js"); 
  $modx->regClientStartupScript("assets/snippets/memberList/js/memberList.js");
 
  return '<h3>Members list :</h3>
  <div id="card"></div>
  <ul id="memberlist">
   <li id="23"><a href="#">Pierre Ponce</a></li>
   <li id="37"><a href="#">Jean Bonneau</a></li>
   <li id="41"><a href="#">Melusine Enfaillite</a></li>
   <li id="48"><a href="#">Paul Ochon</a></li>
  </ul>';
?>

backend php program : assets/snippets/memberList/memberCard.php

The memberCard program do a search in the database and display the information card of the member

<?php
 
require_once(MODX_MANAGER_PATH . '/includes/protect.inc.php');
    
// Setup the MODx API
define('MODX_API_MODE', true);
// initiate a new document parser
include_once(MODX_MANAGER_PATH.'/includes/document.parser.class.inc.php');
$modx = new DocumentParser;
 
$modx->db->connect(); // provide the MODx DBAPI
$modx->getSettings(); // provide the $modx->documentMap and user settings
 
$id = $modx->db->escape($_POST['id']);
    
$fields = "country, fullname, email, phone, comment";
$from = $modx->db->config['table_prefix']."memberlist";
$where = "id = $id";
 
$card = $modx->db->getRow($modx->db->select($fields, $from, $where));
  
echo "<span> Country: {$card['country']} Full name: {$card['fullname']} Email: {$card['email']} Phone: {$card['phone']} Comment: {$card['comment']} </span>";
 
?>

How to cook the files

We need one document in the modx manager for the frontend snippet and the two files in the snippet folder, one for the javascript file, one for the backend program. As in the "Full MODx solution", the javascript file could be managed as a MODx document too (see above).

The frontend snippet will be placed in any document you want, and you need to call it [!MemberList!] to make appear the member list. Click on any name will call the backend part via the javascript mootools function for handling the ajax calls.

If you want more functionality in your ajax framework, you only need to add more cases in both snippet and backend program.

Keep in mind that in this "lightweight solution" you have a part of the MODx core, not all the MODx API available.

If anyone uses this technique or wants (or knows how to perfect it...) please visit me at modx.wangba.fr and dropme a line ;)


Differences and conclusions

In the "full MODx API solution" the ajax request is setting up with : new Ajax("[~22~]",{

In the "lightweight" solution: new Ajax('index-ajax.php', {postBody: pars, update: $('card') }).request();});

In the first solution you set up your ajax request with index.php and you call the MODx parser method to build the answer. In the second solution you set your ajax request with index-ajax.php and you call only the initialisation of database Variables. So you need to initiate a new document parser to use the global $modx and populate the $modx->documentMap array with:

// Setup the MODx API
define('MODX_API_MODE', true);
// initiate a new document parser
include_once(MODX_MANAGER_PATH.'/includes/document.parser.class.inc.php');
$modx = new DocumentParser;
 
$modx->db->connect(); // provide the MODx DBAPI
$modx->getSettings(); // provide the $modx->documentMap and user settings

The choice of the solution depends of your needs and of your MODx programming knowledge. "Full MODx API solution" offer all the MODx facilities and a great level of reuse. But running entire MODx application to service an ajax script could be overkill and heavy if you need a simple and fast answer to your ajax request.

"Lightweight solution" is faster but offer a "limited" MODx API and needs to deep into the code.

Personal tools