1

This is my first time writing custom JavaScript for Drupal, and at the moment I am attempting to bind onClick events to buttons within a block generated by a view, but I suspect I am approaching this from the wrong angle by doing what I'm familiar with in other frameworks. I believe I could, and likely will, use views to achieve the desired effect in this case, but I will need the ability to apply jQuery to different ends later on and would like to learn using this example.

At the moment I have a .js file with only basic alert bindings using the jQuery .click function and the buttons' ID selectors wrapped in a function to allow the use of the $ shortcut for jQuery:

(function ($) {

    $('#previous-arrow').click(function () {
        alert('previous clicked');
    });

    $('#next-arrow').click(function () {
        alert('next clicked');
    });

}(jQuery));

I have included this file both in the theme .info file and by calling drupal_js_add() in several locations throughout the site, and I have verified both that the file is being included and jQuery is correctly functioning within this function each time.

The issue I am hitting is that at the time this file is included and the function executed, the DOM does not appear to be completely built, and the elements I am attempting to target do not yet exist - only the calls to include the needed files. Attempting to retrieve the HTML of elements such as the body return a null value, while displaying the output of $('*').html() at the beginning of my file shows the following:

<!--<![endif]--><head>
      <meta charset="utf-8">
<meta about="/home" property="sioc:num_replies" content="0" datatype="xsd:integer">
<link rel="shortcut icon" href="http://mysite.localhost/sites/all/themes/my_theme/favicon.ico" type="image/vnd.microsoft.icon">
<meta content="Home Page" about="/home" property="dc:title">
<link rel="shortlink" href="/node/10">
<meta name="Generator" content="Drupal 7 (http://drupal.org)">
<link rel="canonical" href="/home">
  <title>Home Page | mysite.localhost</title>

      <meta name="MobileOptimized" content="width">
    <meta name="HandheldFriendly" content="true">
    <meta name="viewport" content="width=device-width">
    <meta http-equiv="cleartype" content="on">

  <style>@import url("http://mysite.localhost/modules/system/system.base.css?nd8mqy");</style>
<style>@import url("http://mysite.localhost/misc/ui/jquery.ui.core.css?nd8mqy");
@import url("http://mysite.localhost/misc/ui/jquery.ui.theme.css?nd8mqy");
@import url("http://mysite.localhost/modules/overlay/overlay-parent.css?nd8mqy");
@import url("http://mysite.localhost/modules/contextual/contextual.css?nd8mqy");</style>
<style>@import url("http://mysite.localhost/modules/comment/comment.css?nd8mqy");
@import url("http://mysite.localhost/modules/field/theme/field.css?nd8mqy");
@import url("http://mysite.localhost/modules/node/node.css?nd8mqy");
@import url("http://mysite.localhost/modules/search/search.css?nd8mqy");
@import url("http://mysite.localhost/modules/user/user.css?nd8mqy");
@import url("http://mysite.localhost/sites/all/modules/views-7.x-3.8/views/css/views.css?nd8mqy");</style>
<style>@import url("http://mysite.localhost/sites/all/modules/ctools-7.x-1.4/ctools/css/ctools.css?nd8mqy");
@import url("http://mysite.localhost/modules/shortcut/shortcut.css?nd8mqy");
@import url("http://mysite.localhost/modules/toolbar/toolbar.css?nd8mqy");
@import url("http://mysite.localhost/sites/all/libraries/superfish/css/superfish.css?nd8mqy");
@import url("http://mysite.localhost/sites/all/libraries/superfish/style/default.css?nd8mqy");</style>
<style>@import url("http://mysite.localhost/sites/all/themes/my_theme/css/styles.css?nd8mqy");</style>
  <script src="http://mysite.localhost/misc/jquery.js?v=1.4.4"></script>
<script src="http://mysite.localhost/misc/jquery.once.js?v=1.2"></script>
<script src="http://mysite.localhost/misc/drupal.js?nd8mqy"></script>
<script src="http://mysite.localhost/misc/ui/jquery.ui.core.min.js?v=1.8.7"></script>
<script src="http://mysite.localhost/misc/jquery.ba-bbq.js?v=1.2.1"></script>
<script src="http://mysite.localhost/modules/overlay/overlay-parent.js?v=1.0"></script>
<script src="http://mysite.localhost/modules/contextual/contextual.js?v=1.0"></script>
<script src="http://mysite.localhost/misc/jquery.cookie.js?v=1.0"></script>
<script>var switchTo5x = true;</script>
<script src="http://w.sharethis.com/button/buttons.js"></script>
<script>if (stLight !== undefined) { stLight.options({"publisher":"dr-e13af4e9-811b-621c-becb-9db3833a59fd","version":"5x"}); }</script>
<script src="http://mysite.localhost/modules/toolbar/toolbar.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/libraries/superfish/jquery.hoverIntent.minified.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/libraries/superfish/sfsmallscreen.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/libraries/superfish/supposition.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/libraries/superfish/superfish.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/libraries/superfish/supersubs.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/modules/superfish-7.x-1.9/superfish/superfish.js?nd8mqy"></script>
<script src="http://mysite.localhost/sites/all/themes/my_theme/js/ui-scripts.js?nd8mqy"></script></head>

(If there any paths that don't make sense here, they have been [hastily] anonymized)

My guess is that there is a correct way in Drupal to do what I'm attempting that I am not aware of, and stand to waste a lot of time trying to shoehorn my approach into the framework. What is the way to accomplish event bindings in an included custom JavaScript file?

  • There's no difference to 'standard' jQuery, you just need to make sure you bind events when the DOM is ready. Drupal does have a wrapper though in the form of behaviors – Clive Oct 14 '14 at 18:30
  • You are correct, I overlooked and forgot to include document.ready - this is working now! – Ghetto Dragon Tamer Oct 14 '14 at 19:35
-1

If you are getting alert message while loading the page then your Drupal and Javascript are working properly together.

That said, the problem you are facing with DOM elements, in your case #previous-arrow and #next-arrow, not loading when Jquery function executes is true. To overcome that you have to execute your Jquery inside $(document).ready() condition so your code will execute only when everything on the page is loaded.

So try with this:

(function ($) {

  $(document).ready(function() {

    $('#previous-arrow').click(function () {
      alert('previous clicked');
    });

    $('#next-arrow').click(function () {
      alert('next clicked');
    });

  });

}(jQuery));
  • I can hardly believe I forgot this, I must have confused the wrapper function with the shorthand for document.ready and overlooked it. Thanks for catching my mistake, this now works correctly. – Ghetto Dragon Tamer Oct 14 '14 at 19:34
  • JS Code that does not use Behaviors is trouble waiting to happen. – Mołot Oct 14 '14 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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