0

I have custom module called interface, through which I'm adding a javascript file. This code is in plain old javascript, no jQuery, and has been working for me.

I now want to be able to add some jQuery functions to this code, I thought this would be possible since jQuery and javascript should be compatible with each other, right?

So here's a simplified example of what I'm doing inside the .js file:

(function ($) {
    Drupal.behaviors.interface = {
    attach: function()
    {
        function foofunction() {
        // execute some code
        }
    function WelcomeScreen()
    {
        Screen.apply( this );
        this.html = function(){
        return "<p></p>";
        };
this.activate = function(){
document.getElementById("main").innerHTML = "<a id=\"button\" onClick\"foofunction()\">Test</a>";
        };
        }

    }
    }
})(jQuery)

This code results in the following error in Chrome dev tools:

Uncaught ReferenceError: foofunction is not defined 

My guess is that somehow the required jquery wrapper or the drupal behaviors wrapper are causing the functions to no longer be 'global'.

One obvious answer, I think, is rewriting everything in proper jQuery syntax. But I'm interested in how to make these javascript functions compatible with jQuery.

2 Answers 2

1

First off, onClick misses an = sign. Secondly, Chrome is right. From the point of view of the <a id="button"> element, the function is not visible even though it seems to be in scope of WelcomeScreen function. That's because it's not the function that invokes it, but the element on a page. Try onClick="Drupal.behaviors.interface.foofunction()". But better off - make it unobtrusive by removing the onClick attribute and saying at the document.ready level:

(function ($) {
    Drupal.behaviors.interface = {
    // code
    }

    $(function(){
      $('#button').live('click', Drupal.behaviors.interface.foofunction);
    });
})(jQuery)

Of course this is just a rudimentary suggestion, you might want to optimize the code further. If you're using jQuery 1.7+, you'd rather use .on() than .live().

7
  • By the document.ready level, you mean inside the Drupal.behaviors? This is giving me Uncaught TypeError: Object #<Object> has no method 'foofunction'
    – jessems
    Feb 6, 2013 at 19:53
  • adding the code to my answer for better formatting Feb 6, 2013 at 19:57
  • Thanks for your help so far. So this is outside the Drupals.behaviors {} and the subsequent attach: function() {}? It's still giving me Uncaught TypeError: Object #<Object> has no method 'foofunction'
    – jessems
    Feb 6, 2013 at 20:11
  • Oops, I guess we're missing invoking Drupal.attachBehaviors(document) before the #button line. Feb 6, 2013 at 20:21
  • I'm still getting the same error.
    – jessems
    Feb 6, 2013 at 20:43
1

Artur is basically right - "Drupal way " is to attach events in behaviors. Here is code I'm using without problems:

(function($) { 
  Drupal.behaviors.mymodule= {
    attach: function (context, settings) {

      function test(param) {
        alert($(param).attr('token'));
      }

      $(':input', context).on('keyup change', function(){
        test(this);
      });
    }
  };
})(jQuery);

Or simpler:

(function($) { 
  Drupal.behaviors.mymodule= {
    attach: function (context, settings) {

      function test() {
        alert($(this).attr('token'));
      }

      $(':input', context).on('keyup change', test);
    }
  };
})(jQuery);

Rewrite your code to that syntax, make sure you are using jQuery Update, and you should be good.

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.