DrupalCon Paris 2009
The combination of JQuery and Drupal makes it super easy to create AJAX-enabled websites. Drupal has auto-complete ability already built in, leaving only the actual data searching up to you to implement. Other AJAX functionality has been made a piece of cake to implement.
Here's how to build a form that asks the user for a node title (which it auto-completes) and fetches the node and displays it below the form, without reloading the page.
name = AJAX demo
description = Demonstrates the use of AJAX requests and Drupal autocomplete
package = Demo
version = "6.x-0.0"
core = 6.x<?php
/* ---- System hooks ---- */
function ajax_demo_menu(){
return array(
/*
First register the menu path to our form,
and tell Drupal what to do when we visit the path:
*/
'demo' => array(
/* Anybody should be able to access this URL: */
'access arguments' => array('access content'),
/* Tell Drupal to render a form: */
'page callback' => 'drupal_get_form',
/* Which form to render: */
'page arguments' => array('ajax_demo_form'),
'title' => 'Ajax demo',
/*
This is a normal item that should be
displayed within the navigation menu:
*/
'type' => MENU_NORMAL_ITEM, ),
/*
Then we let Drupal know what to do when
our auto-complete element asks for data:
*/
'ajax/get-node-titles' => array(
/* Anybody should be able to access this URL: */
'access arguments' => array('access content'),
/* The function to execute when this path is requested: */
'page callback' => 'ajax_demo_get_node_titles',
/*
This is a utility URL used by our site,
and should not be displayed anywhere in the menu system:
*/
'type' => MENU_CALLBACK,
),
/*
We register a path where our nifty
form can retrieve node data from:
*/
'ajax/getdata' => array(
/* Anybody should be able to access this URL: */
'access arguments' => array('access content'),
/* Which function should respond to this path: */
'page callback' => 'ajax_demo_get_data',
/*
This is a utility URL used by our site,
and should not be displayed anywhere in the menu system:
*/
'type' => MENU_CALLBACK,
),
);
}
/* ---- Forms ---- */
/*
The function that tells drupal what our form should contain:
*/
function ajax_demo_form(){
/*
Add the Javascript/JQuery to handle the
node fetching when the button is clicked:
*/
drupal_add_js(drupal_get_path('module', 'ajax_demo') . '/ajax-demo.js');
return array(
'node-autocomplete' => array(
/*
Tell Drupal that this is an autocomplete field,
and where to fetch auto-complete suggestions from:
*/
'#autocomplete_path' => 'ajax/get-node-titles',
/*
Note that autyocomplete_path attribute is the only difference
between normal textfield and auto-complete field definitions.
*/
'#title' => t('Type part of a node title'),
'#type' => 'textfield',
),
/* The button to trigger fetching of node data: */
'get-node' => array(
'#value' => t('Click to fetch the node'),
'#type' => 'button',
),
/* Add an empty div at the end of the form to hold fetched nodes: */
array(
'#value' => '<div id="node-area"></div>',
),
);
}
/* ---- Callbacks ---- */
/*
Fetch and return suggestions to the node title auto-complete:
(Because we mapped ajax/get-node-titles to this function,
any additional 'path elements' will be passed as variables
to the function. eg.
ajax/get-node-titles/bla
will cause the value of $part to be 'bla'
)
*/
function ajax_demo_get_node_titles($part){
$results = array();
$rows = db_query("SELECT title FROM {node} WHERE title LIKE('%%%s%');", $part);
/*
This'll fetch node titles that contain the user typed text
We can show only titles that start with the text by changing:
LIKE('%%%s%')
to:
LIKE('%s%')
*/
while ($row = db_fetch_array($rows)){
$results[$row['title']] = $row['title'];
}
/* The values of this array will be displayed to the user,
while the keys will be used to replace what the user typed
on selection.
*/
/* Format the response to be acceptible to javascript */
drupal_json($results);
}
/* Fetch and return the rendered node: */
function ajax_demo_get_data($title){
$nid = db_result(db_query("SELECT nid FROM {node} WHERE title='%s'", $title));
if ($nid){
// Load and render the node:
$node = node_load($nid);
// print the rendered output as is to the response:
print node_view($node);
} else {
print t('No node with that title could be found!');
}
}| Attachment | Size |
|---|---|
| ajax_demo.zip | 1.6 KB |