This is a recipe that I used to load the content of my "Portfolio of Websites" page. I took advantage of jQuery and Drupal menu system to generate an asynchronous http request, serve the content and show it inside a div tag.
This is the module code:
.info file
; $Id: asynch.info,v 1.0 2008/02/24 14:07:53 pposada Exp $
name = Asynchronous Loading of content from any page
description = Helper module to load page output asynchronously.
package = Custom
dependencies = pagearray
; recommended = jquery_interface jquery_update.module file
<?php
/**
* Implementation of hook_perm()
*/
function asynch_perm(){
return array('load content asynchronously');
}
/**
* Implementation of hook_menu()
*/
function asynch_menu($may_cache){
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'asynch/load',
'callback' => 'asynch_printer',
'type' => MENU_CALLBACK,
'access' => user_access('load content asynchronously'),
);
}
return $items;
}
/**
* Called jQuery
* This submits a request to asynch/load page and returns the content part of the page
*/
function asynch_printer($nid){
$path = "node/".$nid;
$return = pagearray_page($path);
print drupal_to_js(array('content' => $return['page']['content']));
exit();
}
?>php snippet that goes inside the page body:
<?php
//jquery_interface_add();
// jquery content loader
drupal_add_js(
'$(document).ready(function(){
$(".view-item-work-sample").css("cursor","pointer");
var first = $("#dynamic-filter-work_sample").find(".view-data-node-nid:first").text();
$("#placeholder").html("<center><img src=\"/sites/all/themes/pedroposada/images/ajax-loader.gif\" align=\"center\"></center>");
$("#placeholder").load("/asynch/load/" + first, function(){
var result = Drupal.parseJson($("#placeholder").html());
$("#placeholder").html(result["content"]);
$(".ws-thumb > img").mouseover(function(){
var source = "/files/imagecache/sample_big/files/" + $(this).attr("alt");
$(".ws-big > img").attr("src",source);
});
$("#placeholder").attr("title",first);
});
$(".view-item-work-sample, .view-item-work-sample-side").click(function(){
var path = $(this).find(".view-data-node-nid").text();
if($("#placeholder").attr("title") != path ){
$("#placeholder").html("<center><img src=\"/sites/all/themes/pedroposada/images/ajax-loader.gif\" align=\"center\"></center>")
.load("/asynch/load/" + path, function(){
var result = Drupal.parseJson($("#placeholder").html());
$("#placeholder").html(result["content"]);
$(".ws-thumb > img").mouseover(function(){
var source = "/files/imagecache/sample_big/files/" + $(this).attr("alt");
$(".ws-big > img").attr("src",source);
});
$("#placeholder").attr("title",path);
});
}
return false;
});
});',
'inline'
);
?>
<div id="placeholder">
</div>This is just one more example of how you can implement the jQuery and Drupal to load content asynchronously.
This is a great idea. I am trying to get it to work on my site, but the directions are a bit too thin for me to actually get it running. Could you give some more details?
For instance, your calling path =/asynch/load/ , but make no mention as to what the directory is for or that one should create it.....?
Basically you just need to create a menu item in the module as explained there. When you use the hook_menu, you create there a new menu item that will call the function. Every menu item is a page in drupal, this menu item I created here is the page that generates the JSON code which then gets parsed by jQuery and renders the content.
I hope this is what you were asking for.
Im sorry, I just don't understand. I am obviously missing a step. Here is what I am doing:
- Creating a module folder that contains the .module and .info files.
- Enabling the module in admin.
- Creating a Page with the PHP snippet above and selecting "PHP code" from the "input format" drop down.
From this point on I am lost.
Ok, you will need to make sure that all the HTML tags have the correct "class" and "id" on the page you are creating.
You can take a closer look at my Portfolio of Websites page to check if you are using the correct ids and classes for the links. You can test this by just creating one link on your page.
You can see that I am using:
$(".view-item-work-sample, .view-item-work-sample-side").click(function(){});You need to use these same classes so that when you click on those tags you will send the http request.
Please tell me what happens when you click on you links.
I had originally copied the links from your portfolio page and replaced your node numbers with my own. When I click on one of the links, the loading gif appears, which shows that its obviously triggering something, however the node never appears.
As far as I can tell all of the classes and ids do indeed match consistently.
Well, I would try just returning a string first. Instead of loading a whole node, try returning the same string . I remember that happened to me first but I am not sure how I fixed it. Instead using the page array just return a simple string. I hope you get it working.
Where exactly would I make the change to load something other than a node? I have a tried everywhere I can think of and nothing seems to change the outcome.
I had noticed that on your portfolio page you have some javascript that seems to be required, but isn't mentioned in your recipe here. Perhaps theres something else missing from here as well?
You need to change:
<?php
/**
* Called jQuery
* This submits a request to asynch/load page and returns the content part of the page
*/
function asynch_printer($nid){
$path = "node/".$nid;
$return = pagearray_page($path);
//print drupal_to_js(array('content' => $return['page']['content']));
print "my string";
exit();
}
?>
note the "my string"
yeah, I had already tried that but wasn't sure. The string isn't returned.
What part of the code is actually communicating with the module? I noticed that if I disable the module, nothing seems to change.
The part that communicates with the module is the
load()function in the jQuery code snippet.That function sends a http request to the module and the module returns the string.
The string is encoded using the
drupal_to_js()I have tried everything I can think of to get this thing to work, but with no luck.
If you could offer any further information or suggestion I would be very grateful. Otherwise, Im going to have to abandon this idea.
I took a look at my code again to make sure nothing was missing in this post.
Make sure you have the "jquery update" module installed and the latest version of jquery.js in your drupal installation.
ahh... that would explain how you had a different version of jquery than I originally did. I had before manually included the newest version without the jquery update module, I have now added this module as you suggested, but there is still no change.
What does this refer to : "asynch/load/"?
When I browse to that directory on your server I see a bunch of content;
"...=\"last taxonomy_term_4\"\x3e\x3ca href=\"/category/blog/phpscripts\" rel=\"tag\" title=\"\" class=\"taxonomy_term_4\"\x3ephp scripts\x3c/a\x3e\x3c/li\x3e\n\x3c/ul\x3e\x3c/span\x3e\n \x3cdiv ..."
However, when I browse to that directory on my site, I get a "page not found" error. This is expected since I don't have that folder in my root directory. Can you shed some light on this?
That is exactly what you are missing. It seems that you have not created the menu item correctly in your module.
There is no actual folder on the server. There is a function that gets called when you type that address in your browser.
Take a look at my code again under "Implementation of hook_menu()" and you will see "asynch/load" there. That's the drupal path to call the function that generates the actual content. The jQuery script sends a request to that path and retrieves the content. There is no actual directory on the server.
Ok, so what exactly am I suppose to edit in that part of the module?
Have you checked the access permissions? You need to give access to the anonymous user to your module. Its called "load content asynchronously".
I don't actually see the module appear in the access control page. The module is active though.
Take a look at this function here:
<?phpfunction asynch_perm(){
return array('load content asynchronously');
}
?>
this hook creates an entry in the access control page for this module. This module is supposed to show up in that page. Go to "admin/user/access" and check again and make sure that "anonymous user" has access to it.
Post new comment