By Csabbencs on
I'm new to AJAX + Drupal, I can't solve the following simple problem, please advise.
I have a table with people names and ages. I'd like to list the names of people on the page, by default ordered by name. Then if the link 'sort by age' is pressed, they should be listed by age without page reload.
My module:
drupal_add_js("./sites/default/modules/my_module/my_module.js");
function my_module_menu() {
$items['my_module'] = array(
'page callback' => 'my_module_all',
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
function my_module_all(){
if (isset($_POST['ord'])) $ord = $_POST['ord']; else $ord = 'name';
global $page_content;
$page_content .= "<div id=\"mydiv\">";
$page_content .= "<a href='#' class='order_button' id='name'> sort by name </a>";
$page_content .= "<a href='#' class='order_button' id='age'> sort by age </a><br>";
$list = get($ord);
$page_content .= $list."</div>";
// does not matter if I comment it out or not
/*
if(isset($_POST['ord'])) {
header("Content-type: application/json");
drupal_to_js($list);
}
*/
return $page_content;
}
// returns the name of people ordered by name or age
function get($ord){
// simple table with 2 columns: name, age
$query = "SELECT name FROM people ORDER BY %s";
$result = db_query($query, $ord);
while ($objects = db_fetch_object($result)) {
$list .= $objects->name."<br>";
}
return $list;
}
And my js:
Drupal.behaviors.my_module = function(context) {
$('a.order_button:not(.mymodule-processed)', context).addClass('mymodule-processed')
.bind('click', function(){
$.post('my_module', {"ord": this.id}, callback_result);
return false;
});
}
var callback_result = function(response) {
var result = Drupal.parseJson(response);
$('#mydiv').html(result.data); //works only with 'data' written
}
Comments
You might be best to use
You might be best to use views for this.
It has a table style plugin that supports click sorting on the headers and supports ajax.
If you're defining your own tables, you need to implement hook_views_data to let views know about your table's fields.
Aside: you should prefix your function and table names with that of your module to avoid namespace collisions.
Lee Rowlands
mysterious
Thanks for the reply. Views might be a good solution, I'll definitely check that.
But for now, I'd rather stick to my version to get to know how things work when using drupal for ajax.
I did some small modificatons that you can see in the code above and it started working almost as I expected. Though I'd like to point out some things I totally don't understand:
1., After you click, not the expected result ($list .= $objects->name) is put into "mydiv", but the whole page ($page_content).
2., The code part commented out has no influence on the result.
3., The code stops working if I leave out "data" from the following javascript line: $('#mydiv').html(result.data);
2 and 3 are the most mysterious.
Could you help please?
can you try returning $list
can you try returning $list instead of $page_content and see what happen?
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
$list is not enough
$list holds only the records from the database.
$list is part of the page content, but page content is more than just a list, so $list is not sufficient to return.
yes but did the $list
yes but did the $list successfully returning data via ajax?.
as I see in the code you didn't load any more content data aside $list?
Anyway, if the $list is returning data correctly via ajax, you can add more data to $list like node_load($nid) result for additional content.
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
I did load other content data
I did load other content data into the page: there are 2 links that you need to press to start ajax:
If I return $list only, nothing happens since the links that would start ajax are gone. (In this case, only the list of records are there without any capability being sorted by ajax.)
can you change this
can you change this
to
and
to
and see what happen?
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
nope
I tried.
Without returning $page_content, the resulting page gets pretty ugly due to
drupal_json(array('data' => $page_content));It will be a blank white page outputting only the following :
{ "data": " ..." }Could you just print the
Could you just print the $page_content instead of returning it?
Lead Developer and Founder of StreamRiot.com
nope
If I do it, all drupal html stuff is gone, the page is showing only what I put in the variable: 2 links and the list of records.
"It will be a blank white
"It will be a blank white page outputting only the following : { "data": " ..." }"
That is the right way, now you need to "attach" the "{"data" : "...."} to the div area in your content using jQuery
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
you mean function callback_result?
I don't get it. Could you be a bit more specific?
You mean the function callback_result? That's already in the code.
I mean u need to tell the js
I mean u need to tell the js to grab the data and attach it to the div element that you wish to update.
example ajax jquery code :
--------------------------------------------------------------------------------------------------------
if you can use drupal why use others?
VicTheme.com
hmm
My code is also from an example and I checked a lot of examples otherwise I wouldn't have come here to ask.
What you suggest is the same I put in my code:
$.post('my_module', {"ord": this.id}, callback_result);(By the way I tried yours and didn't work)
I wouldn't think that I'm very lame, but for now let's suppose I am.
Could you please either try out my original code up above and find the bug or send your own working solution without pseudo code?
I'm starting to feel that the time we both spent on this issue is much more than I would have needed to write the code without Drupal...
A Simple Sortabe Table
Hi,
Drupal comes with built-in table sort mechanisms. Try this:
Note! In your original post, please nix the php statement that is not placed inside a function:
NIX ->
drupal_add_js("./sites/default/modules/my_module/my_module.js");Recommendation: If you are new to programming in general, I would recommend "walk then run". Most beginning programmers can not describe the difference between synchronous and asynchronous. Ajax is not a "beginners" task. In other words, see if my example helps :) It should at least get you started.
In addition, your database table should contain a primary key (unique identifier). If you are using MySql with Drupal your hook_schema implementation includes
'type' => 'serial',to define a primary key. A table with just name and age fields is not going to work very well. However, for a very limited "proof of concept", it will do :)That's all you need.
Hope that helps :)
same with ajax?
Thanks for the reply!
I agree regarding "walk then run". :)
I completely understand your example and, of course, I can do and I'm already done sorting the table this way.
In my case the point is AJAX. I'd like to do the sorting without page refresh.
Could you please extend YOUR example so that no page refresh happens? That might help me a lot!