4

We have a JS file (basic-page.js) that has the following Drupal Behavior. In this, we created what we believe is considered a Drupal object (need help with correct term) that contains a function that can be called. In the latest request, we need the ability to reuse the same code from the Drupal Behavior in another Drupal Behavior.

How could we reuse the code? Currently the article.js is not able to use the code from basic-page.js, no errors or warnings are given.

basic-page.js (where Drupal object resides)

(function($) {
  'use strict';
  Drupal.customObj = {
    'function1': function(element) {
      /* perform some logic here */
    },
    'function2': function(var) {
      /* perform some other logic here */
    }
  };

  Drupal.behaviors.customName = {
    attach: function(context, setting).once('customName').each(function() {
      /* behavior runs here */
      var func1 = Drupal.customObj;
      var results = func1.function1($('body'));
      //process results
    });
  };
})(jQuery);

article.js (where we want to reuse Drupal.customObj.function1)

(function($) {
  'use strict';

  Drupal.behaviors.articleResults = {
    attach: function(context, setting).once('articleResults').each(function() {
      /* behavior runs here */
      var customObj = Drupal.customObj;
      var results = customObj.function1($('body'));
      //process results
    });
  };
})(jQuery);
2
  • 1
    Neither of those are valid JS so you should definitely be seeing errors in the console (attach: function(context, setting).once('articleResults').each(function() { specifically). Are you sure those files are in the page?
    – Clive
    Commented Feb 21, 2018 at 21:07
  • @Clive i have updated the weights but no luck. What do you mean by valid JS? How should those be written? My understanding is the when using once() you want to pass in the behavior that you would like to run once? remove 'articleResults' and leaving it as once() has the same behavior Commented Feb 21, 2018 at 22:19

1 Answer 1

7

I'll focus on the inclusion first, then describe what Clive was referring to, while mentioning that your JS is not valid:

For your use case you should add a common library to your module/theme that extends the Drupal object. (You don't even have to extend the Drupal object, but can create an own one, if you prefer.)

Then use dependencies to make sure the object is available in your basic page JS, as well as in your article JS.

Example

In your *.libraries.yml

mymodule/common:
  js:
    js/mymodule-common.js: {}
  dependencies:
    - core/drupal
    - core/jquery

mymodule/page:
  js:
    js/mymodule-page.js: {}
  dependencies:
    - mymodule/common
    - core/drupal
    - core/jquery
    - core/jquery.once

mymodule/article:
  js:
    js/mymodule-article.js: {}
  dependencies:
    - mymodule/common
    - core/drupal
    - core/jquery
    - core/jquery.once

You can then split your JS to the three separate files containing your code. The dependencies section makes sure the scripts your library depends on are loaded before.

Now to the scripts itself:

mymodule-common.js

(function($) {
  'use strict';

  Drupal.customObj = {
    'function1': function(element) {
      /* perform some logic here */
    },
    'function2': function(var) {
      /* perform some other logic here */
    }
  };

})(jQuery);

mymodule-page.js

(function($) {
  'use strict';

  Drupal.behaviors.customName = {
    attach: function(context, setting) {
      $('body').once('customName').each(function() {
        var func1 = Drupal.customObj;
        var results = func1.function1($('body'));
        //process results
      });
    }
  };

})(jQuery);

And similar in your mymodule-article.js.

And here the promised feedback to the comment of Clive: Compare the attach property in the last example. It expects a callable that will be executed every time a page/ajax load finished. Within its body you can then do your magic.

References:

https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview https://www.drupal.org/docs/8/theming-drupal-8/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-theme

1
  • The thing that i was missing was the dependency on the article library. After updating it fixed the issues Commented Feb 22, 2018 at 17:32

Your Answer

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

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