Behaviors and Ajax

Events happening in the community are now at Drupal community events on www.drupal.org.
hershel's picture

I am using the http://drupal.org/project/quicktabs module to load custom block content which comes from a custom module. In that content are links and I want those links to have the same functionality as the tab links, i.e. they should load new content into their respective tab.

There are two issues--one is to ajaxify links in content loaded by the initial click on the tab (or when the page loads) and then to again ajaxify links in content loaded after the user clicked on one of those ajaxified links.

I believe that

Drupal.behaviors.myModuleBehavior(newcontext), where newcontext would be the new, AJAX-delivered content

(from the JavaScript Startup Guide) would be the ideal way to handle this, but given the fact that the initial load may be handled by the quicktabs module, I don't see how to do that--I don't have control over that code. Not to mention that fact that using jQuery's load() I haven't anyhow gotten this method (of reapplying behaviors) to work.

Here is the code I am using that is working. It uses setajax() to setup the functionality and doajax() first finds the correct DOM object into which to load the new content, then sets up there a progress bar and then loads the actual content, asking jQuery to run setajax() again after the content is loaded to ajaxify any new links which may have been loaded:

Drupal.behaviors.mymodule = function (context) {
  setajax();
};
function setajax() {
  $('#quicktabs-1 div.quicktabs_tabpage a').click(doajax);
}
function doajax() {
  var target= $(this);
  do {
   target = $(target).parent();
  } while (!$(target).hasClass("block"));
  var progressBar = new Drupal.progressBar('jec_media');
  progressBar.setProgress(-1, Drupal.t('Loading'));
  $(target).html(progressBar.element);
  $(target).load($(this).attr('href'),null,setajax);
  return false;
}

The other piece is to add this in the Drupal module output:

<script type="text/javascript">setajax();</script>

In reality I am thus not even using the first three lines of my main code:

Drupal.behaviors.mymodule = function (context) {
  setajax();
};

and I could remove them.

If anyone has any feedback regarding this methodology, I would be interested to hear.

Comments

The quicktabs module calls

katbailey's picture

The quicktabs module calls Drupal.attachBehaviors after it loads content via ajax - this means that your Drupal.behaviors.mymodule function will get called automatically both on page load and when new content is loaded in your tab via ajax. There should be no need for this: <script type="text/javascript">setajax();</script>. Also, instead of passing in setajax as a parameter to your .load() call, you can simply call Drupal.attachBehaviors(target) immediately after it. I guess I would do something more like the following:

Drupal.behaviors.mymodule = function (context) {
  $('#quicktabs-1 div.quicktabs_tabpage a:not(.myModule-processed)', context).addClass('myModule-processed').each(function(){
    $(this).bind('click', Drupal.myModule.doajax);
  });
};

Drupal.myModule = {};

Drupal.myModule.doajax = function() {
  var target= $(this);
  do {
   target = $(target).parent();
  } while (!$(target).hasClass("block"));
  var progressBar = new Drupal.progressBar('jec_media');
  progressBar.setProgress(-1, Drupal.t('Loading'));
  $(target).html(progressBar.element);
  $.get($(this).attr('href'), null, function(response) {
    $(target).html(response);
    Drupal.attachBehaviors(target);
  });
  return false;
};

By the way, Quick Tabs is still in very active development (we're hoping to release rc3 early next week followed by a stable release hopefully not too long after that) and ajax-loaded content is one of the areas most in need of testing. Please let me know whether you get this working as desired.

Drupal.attachBehaviors Call Not Found

hershel's picture

The quicktabs module calls Drupal.attachBehaviors after it loads content via ajax - this means that your Drupal.behaviors.mymodule function will get called automatically both on page load and when new content is loaded in your tab via ajax.

This I do not see, based on empirical analysis. I had looked through the code to find this also, which I didn't. It can be tested very simply by making a custom module which defines a block with a bit of content and then this use JS:

Drupal.behaviors.mymodule = function (context) {
  alert('hi');
};

When I use this and then click the tab to load the content for my custom block via Ajax, there is no alert box. When the page first loads (and loads custom block content) I do of course see it.

Seems to me that you need to add

Drupal.attachBehaviors()

to the end of

Drupal.quicktabs.tab.prototype.success = function(data) {

in quicktabs.js. If I do that, then it does work.

Your solution overall, is more elegant than mine, but it only works with that one line added to quicktabs.js.

Thanks.

--
CiviHosting -- Drupal and CiviCRM Hosting Specialists -- 100% Satisfaction Guaranteed

Ah right - that got added

katbailey's picture

Ah right - that got added with this commit, which was on Jan 22nd - 3 days after the rc2 release came out :-/ Well, rc3 will hopefully be out next week :-)

Great. Thanks for that--it

hershel's picture

Great. Thanks for that--it works perfectly.

--
CiviHosting -- Drupal and CiviCRM Hosting Specialists -- 100% Satisfaction Guaranteed

Quicktab

niva's picture

I have two tab in my quicktab. on clicking first tab it works perfectly but when i click on second tab it shows nothing .Please anybody could help me.

Quick Tab

reddyweb's picture

For tabs, need to select tab type 'block, view or node' and also need to select tab content.

  1. If any arguments are there for View, need to pass arguments like %1 or %2 in arguments field.

  2. In some cases, block or view content is empty, it shows nothing in the tab.

You can find these options here /admin/build/quicktabs/%/edit

I hope it helps for you.

Thanks

Javascript

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: