Reply to comment
Using Jquery, JSON, and AJAX in Drupal
- peter's blog
- Add new comment
- 1036 reads
I recently had the opportunity to dig into drupal's activemenu module, a seldom-used and not-entirely-functional ajax framework that can be used to build menus/trees on the fly. It provided a good roadmap that I was able to customize to work well for a project I did with rockpeaks.com.
Here's a quick screencast overview of the project and what it entailed:
I've used AJAX and jquery before occasionally, but it's not my specialty, so I had to learn a few things to pull this project together. I suspect most readers won't need to be bored by the details of what I had to learn, so I'll just include a few quick solutions to some of the obstacles I encountered:
- Some JSON data, especially the more complex items involving arrays, was not properly handled by drupal_to_js, as a result of which I needed to use json_encode() instead (the server callback ends in my code now ends with print json_encode ($items) ; exit;)
-
Using <a href=""> to store the path for subsequent calls to the server was not cross-browser compatible for my application, so I instead stored the path in an attribute of the <li> element. Here's my code in the js where I construct each li item, which is then appended into the <ul> containing element, which is in turn appended into the <li> containing element:
-
$.each( datax , function(i,item){ if (item.children) { $leaf_class = ''; } else { $leaf_class = 'leaf';} $newchildren += '<li class="collapsed ' + $leaf_class + ' "data-activemenu-ajax-path="'+item.path+' " >' + item.title + '</li>' ; });
-
-
I needed to use a slightly different test in the jquery click function to determine whether an element processing the click should do an ajax expand. I added the following code so that clicks on an interior child list element did not invoke an additional unnecessary double expansion of its parent:
-
var $click_is_real = 1 ;var yoffset = Drupal.mousePosition(e).y - $(this).offset().top;if ( $(this).is('.leaf') ) { $click_is_real = 0 ; } // we don't want clicks of expanded children to affect parents.if ($click_is_real) {
-
-
Finally, in order to allow the entire text of the <li> <span> elements to expand the li using the toggle function, I had to add the following to the beginning of Drupal.activemenuToggle:
-
if (e.target.parentNode == menu ) {e.target = e.target.parentNode}
-

