1

I've got a view of teasers; each teaser has 3 clickable <a> elements:

  • "morelink" toggles an extra row in a table.

  • "noderef" loads the referenced node into a div.

  • "ajaxview" sends the node id as an argument to ajax load a view into a <div>. This view contains a view of teasers which in turn each have 3 clickable <a> elements thus creating a nested view of teasers which in turn each have 3 clickable <a> elements.

This is the JavaScript code.

Drupal.behaviors.morelink = function(context) {
  $("a.morelink").click(function (e) {
    e.preventDefault();
    $('.xtrarow').eq( $('a.morelink').index( $(this) ) ).toggle();
  });
}

Drupal.behaviors.ajaxview = function(context) {

    $("a.ajaxclick").click(function(){
    var nid = $(".mynid").eq($('a.ajaxclick').index( $(this) )).val();
    $('.container').eq($('a.ajaxclick').index( $(this) )).load(Drupal.settings.basePath + 'myajax/' + nid);
    return false;
});
}

Drupal.behaviors.noderef = function(context) {

    $("a.nrefclick").click(function(e){
      e.preventDefault();
    var nref = $(".mynref").eq($('a.nrefclick').index( $(this) )).val();
    $('.container').eq($('a.nrefclick').index( $(this) )).load('node/' + nref );
    return false;
});
}

This is the HTML code.

<input type="hidden" class="mynref" value=<?php print $node->field_noderef[0]['nid']; ?> />
<a class="nrefclick" href = "<?php print url('node/' . $node->field_noderef[0]['nid']); ?>">
<img src="http://mysite/smallpinkarrowback.png" ALT="Back"></a>

<a class="morelink" href = "<?php print url('node/' . $node->nid); ?>">
<img src="http://mysite/smallyellowarrowdowninfo.png" ALT="Forward"></a>

<a class="ajaxclick" href="<?php print url('myajax/' . $node->nid); ?>">
<img src="http://mysite/smallpinkarrowforward.png" ALT="Forward"></a>

The behavior is erratic: The "morelink" works consistently and is fine; the ajaxview works intermittently, and seems to load ok for the first few clicks, but once you've clicked a few, the JavaScript stops working.

Can anyone spot the problem?

2 Answers 2

3

Here's what worked in the end;

Drupal.behaviors.ajaxview = function(context) {
  $('a.ajaxclick:not(.ajaxview-processed)', context)
  .addClass('ajaxview-processed').each(function() {
    $(this).click(function(e){
        e.preventDefault();
      $index = $('a.ajaxclick').index($(this));
      var nid = $(".mynid").eq($index).val();
      var toLoad = Drupal.settings.basePath + 'myajax/' + nid;
        xhr = $.ajax({
        url: toLoad,
        success: function(data) {
          $('#content').html($('.audioforumtable', data));
          Drupal.attachBehaviors(context);
        }
      });
    });
  });

 $('a.nrefclick:not(.ajaxview-processed)', context)
  .addClass('ajaxview-processed').each(function() {
    $(this).click(function(e){
        e.preventDefault();
      $index = $('a.nrefclick').index($(this));
      var nref = $(".mynref").eq($index).val();
      var toLoad = Drupal.settings.basePath + 'node/' + nref;
        xhr = $.ajax({
        url: toLoad,
        success: function(data) {
          $('#content').html($('.audioforumtable', data));
          Drupal.attachBehaviors(context);
        }
      });
    });
 });
}

I changed the container to content because it worked better for what I need but the problem seems likely to have been the lack of the Drupal.attachBehaviors(context) . Thanks to Baysaa for steering me in the right direction! I will vote your answer up when I have enough reputation points.

2

I can't tell the immediate problem, but one thing I notice is you're not using the context variable in your behaviors. Try the code below see if it makes any difference.

The classes are to prevent the behavior getting attached to an element already processed by the behavior.

Drupal.behaviors.morelink = function(context) {
  $("a.morelink:not(.morelink-procd)", context)
    .addClass("morelink-procd")
    .each(function(i){
      $(this).click(function(e) {
        e.preventDefault();
        $('.xtrarow').eq($('a.morelink').index($(this))).toggle();
      }); 
    }
  );
}

Drupal.behaviors.ajaxview = function(context) {
  $("a.ajaxclick:not(.ajaxclick-procd)", context)
    .addClass("ajaxclick-procd")
    .each(function(i) {
      $(this).click(function(e){
        e.preventDefault();
        $index = $('a.ajaxclick').index($(this));
        var nid = $(".mynid").eq($index).val();
        $(".container").eq($index).load(Drupal.settings.basePath + 'myajax/' + nid);
        return false;
      });
    }
  );
}

Drupal.behaviors.noderef = function(context) {
  $("a.nrefclick:not(.nrefclick-procd)")
    .addClass("nrefclick-procd")
    .each(function(i){
      $(this).click(function(e) {
        $index = $('a.nrefclick').index($(this));
        e.preventDefault();
        var nref = $(".mynref").eq($index).val();
        $('.container').eq($index).load('node/' + nref );
        return false;
      });
    }
  );
}

EDIT: Reverted the $.each() indexing as it may not be appropriate for this occasion.

2
  • Unfortunately it hasn't made a difference. I've noticed that clicking the a.ajaxview button in the first node works fine. Clicking the 2nd node will bring up a view for the third node. Clicking the 3rd and 4th nodes brings up views with "undefined" as the node id.
    – Meggy
    Apr 26, 2012 at 22:07
  • If you have a test page up online, post the link so we can see exactly what's going wrong.
    – Beebee
    Apr 27, 2012 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.