What a great blog! It's a pity that i can't find your rrs address. If you can offer rrs subscription service, i can track your blog easier!
; $Id$ name = "Dynamic Products" description = "Returns a list of products according to category." core = 6.x package = Example Ajax ModulesCopy, pase & save the above code into “dynamic_products.info”. After we have our .info file created, we continue to create our .module file. This file includes the actual server side code.Go ahead and create “dynamic_products.module” file in our module’s folder.
<?php
function dynamic_products_menu() {
$items = array();
$items['products/get'] = array(
'title' => 'Dynamic Products',
'page callback' => 'dynamic_products_get_by_category_id',
'access arguments' => array('access dynamic_products content'),
'type' => MENU_CALLBACK
);
return $items;
}
This tells Drupal to intercept all calls to “http://www.example.com/?q=products/get” or http://www.example.com/products/get, and call the dynamic_products_get_by_category_id callback function.
function dynamic_products_perm() {
return array('access dynamic_products content');
}
More info about setting permissions can be found here.
function dynamic_products_get_by_category_id($cat_id){
$items = '';
switch($cat_id){
case 12:
$items = '<ul><li>Product 1</li><li>Product 2</li></ul>';
break;
case 20:
$items = '<ul><li>Product 3</li><li>Product 4</li></ul>';
break;
}
// create a JSON object. The object will contain a property named “products” that will be set with the $items variable.
return drupal_json(array('products'=>$items));
exit;
}
Our callback function, accepts a single parameter ($cat_id). Depending on its value, a different list is returned.
// $Id$
Drupal.behaviors.dynamic_products = function (context) {
$('a.categoryLink:not(.categoryLink-processed)', context).click(function () {
// This function will get exceuted after the ajax request is completed successfully
var updateProducts = function(data) {
// The data parameter is a JSON object. The “products” property is the list of products items that was returned from the server response to the ajax request.
$('#divProducts').html(data.products);
}
$.ajax({
type: 'POST',
url: this.href, // Which url should be handle the ajax request. This is the url defined in the <a> html tag
success: updateProducts, // The js function that will be called upon success request
dataType: 'json', //define the type of data that is going to get back from the server
data: 'js=1' //Pass a key/value pair
});
return false; // return false so the navigation stops here and not continue to the page in the link
}).addClass('categoryLink-processed');
}
Copy, paste and save the above code into the dynamic_products.js file.
We are done with the js file.
function dynamic_products_theme() {
return array(
'dynamic_products_javascript' => array(
'arguments' => array(),
),
);
}
function dynamic_products_init() {
theme('dynamic_products_javascript');
}
function theme_dynamic_products_javascript() {
drupal_add_js(drupal_get_path('module', 'dynamic_products') . '/dynamic_products.js');
}
Save the .module file.
<div id=”topDiv”> <a class="categoryLink" href="/products/get/12">Cat. 1</a> <a class="categoryLink" href="/products/get/20">Cat. 2</a> </div> <div id="divProducts"></div>Create your Drupal page, copy and paste the above code, and that’s it. When you view the page, if you will click one of the “categories” links, a call will be made to the server, and the page will display a list of products specific to the category clicked.
What a great blog! It's a pity that i can't find your rrs address. If you can offer rrs subscription service, i can track your blog easier!
I keep getting the response on a new page, i.e. the menu link that calls drupal function e.g. http://example.com/cities/get/22 and the contents like this
{ "cities": "\x3cul\x3e\x3cli\x3e\x3ca href=\"/retail/get/26\" class=\"categoryCity\" title=\"Chicago\"\x3eChicago\x3c/a\x3e\x3c/li\x3e\x3cli\x3e\x3ca href=\"/retail/get/24\" class=\"categoryCity\" title=\"New York\"\x3eNew York\x3c/a\x3e\x3c/li\x3e\x3cli\x3e\x3ca href=\"/retail/get/25\" class=\"categoryCity\" title=\"Dallas\"\x3eDallas\x3c/a\x3e\x3c/li\x3e\x3c/ul\x3e" }
So i am a bit confused, my .js file looks like this.
// $Id$
if (Drupal.jsEnabled) {
$(document).ready(function(content) {
$('a.categoryLink:not(.categoryLink-processed)',content).click(function () {
// This function will get exceuted after the ajax request is completed successfully
// var updateCities =
// alert(this.href);
$.ajax({
type: 'POST',
url: $(this).href,
success: function(data) {$('#cityId').html(data.cities);}, // The js function that will be called upon success request
dataType: 'json', //define the type of data that is going to get back from the server
data: 'js=1' //Pass a key/value pair
});
return false; // return false so the navigation stops here and not continue to the page in the link
}).addClass('.categoryLink-processed');
});
}
Hi Albert,
Looks like you don't have "exit;" right after you post back the JSON object data.
How does the callback function looks like?
fantastic. googled in despair and this article came through.
Thank you
I would love to see how we could basically do the same but loading a node from within drupal dynamically. I want to dynamically load a node in place of the one i am currently on.
Thanks for the tutorial!
Great post first off.
I'm wondering why in hook_menu your not implementing 'page arguments' =>array(2), on the MENU_CALLBACK you setup? I see that it works without it, but should that be there following drupal standards?
BTW, hundreds of teachers will be benefiting from this write up you did, it gave me the jumpstart i needed for my module.
Regarding your question about the page arguments, I tried to make this tutorial as simple as possible, and ignored few other Drupal standards I'm aware of.
The tutorial is, as you said, only a a jump-start for other developers, and each should take responsibility for the way they write their code and follow coding standards.
I made a module as your instruction, .module .info .js, MENU_CALLBACK,
and drupal_json something in my callback function,but when I clicked the page link to the page callback address ,it always said "page not found"...
any suggestion.?
First, try to type the url for the menu callback in your browser and verify that you get a response from the server. It should return a JSON object.
If you still get "page not found" message, try to re-install the module.
If the problem is not with the server side, try to debug your js with a debugger or with alerts to verify that you refer to the right menu callback.
good luck
thank you for this great tutorial
really it helps me a lot
Clicking on the links after creating and installing the module returns no results, am I missing something?
dont forget to print the base_path function
products/get/20>Cat.2
I'm unable to get this to work. When i go to my page and click on the links nothing happens. I've followed this to a tee with a fresh install of 6.15. Am i supposed to give the drupal page with the html code a url of products/get?
Excellent tutorial! I wanted to be able to do this in Drupal 5 and this gave me a great start in understanding the process. Thought I would share my changes that allow this to be done under Drupal 5.
One thing to note is that I had to update jQuery as the default version that comes with Drupal 5 doesn't handle $.ajax (see http://drupal.org/project/jquery_update).
Here are my changes...
dynamic_products.info:
; $Id$
name = "Dynamic Products"
description = "Returns a list of products according to category."
package = Example Ajax Modules
dynamic_products.modules:
<?php
function dynamic_products_menu() {
$items = array();
$items[] = array(
'path' => 'products/get',
'title' => 'Dynamic Products',
'callback' => 'dynamic_products_get_by_category_id',
'access' => user_access('access dynamic_products content'),
'type' => MENU_CALLBACK
);
return $items;
}
function dynamic_products_perm() {
return array('access dynamic_products content');
}
function dynamic_products_get_by_category_id($cat_id){
$items = '';
switch($cat_id){
case 12:
$items = '
';
break;
case 20:
$items = '
';
break;
}
// create a JSON object. The object will contain a property named “products” that will be set with the $items variable.
print drupal_to_js(array('products'=>$items));
exit();
}
function dynamic_products_theme() {
return array(
'dynamic_products_javascript' => array(
'arguments' => array(),
),
);
}
function dynamic_products_init() {
theme('dynamic_products_javascript');
}
function theme_dynamic_products_javascript() {
drupal_add_js(drupal_get_path('module', 'dynamic_products') . '/dynamic_products.js');
}
dynamic_products.js
// $Id$
if (Drupal.jsEnabled) {
$(document).ready(function(content) {
$('a.categoryLink:not(.categoryLink-processed)').click(function (content) {
// This function will get exceuted after the ajax request is completed successfully
var updateProducts = function(data) {
// The data parameter is a JSON object. The "products" property is the list of products items that was returned
// from the server response to the ajax request.
$('#divProducts').html(data.products);
}
$.ajax({
type: 'POST',
url: this.href, // Which url should be handle the ajax request. This is the url defined in the html tag
success: updateProducts, // The js function that will be called upon success request
dataType: 'json', //define the type of data that is going to get back from the server
data: 'js=1' //Pass a key/value pair
});
return false; // return false so the navigation stops here and not continue to the page in the link
}).addClass('categoryLink-processed');
});
}
Hi I think this tutorial is fantastic but by some reason when I click on a link a new tab is open with the JSON content { "products": "\x3cul\x3e\x3cli\x3eProduct 3\x3c/li\x3e\x3cli\x3eProduct 4\x3c/li\x3e\x3c/ul\x3e" }
Do you know why this is happening?
thanks in advance
Hello Alberto,
I think the reason you see the JSON is because something is wrong with your client side script.
Do you get the JSON object printed after you make the AJAX call?
Do you have “return false;” in you JavaScript after the AJAX call?
Zion
Very good post, thanks a lot.
great tutorial- very useful.
for anyone looking for learning pro-drupal-development book has a similar style
Great break down, thank you very much for taking the time to share your knowledge.
I've been banging my head against a virtual wall for days now, reading,searching,reading but your example has put it all into to place for me. You've opened a very interesting door for me.
thanks a million.
A.
ps quotes and some extra spaces in the html threw me for a while, the following got it working for me.
That really helped me a lot on my Ubercart dynamic catalog page, using Ajax. Please continue to provide tutorials around this, maybe with more complex scenarios.
Maybe with how you talked about the views being returned instead of the simple list.
Thanks,
Robert
Fantastic, this is just what I need. But would you be so kind as to write a tutorial for updating a cck field as well? :D
Thanks!
Very good post, thanks a lot.
This tutorial has certainly
Submitted by WinniG (not verified) on Thu, 03/04/2010 - 13:59.This tutorial has certainly gave me light about Ajax and Drupal, too bad I'm still confused, I guess I'll just keep on reading more of your articles.