11

I have a behavior that adds on to some checkboxes.

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

      $('.skip-line', context).on('change', function(){
        // some code
        if ( confirm(Drupal.t('Apply to all languages?')) ) {
          // applying...
        }
      });
    }
  };
})(jQuery);

It works very well, but checkboxes are in AJAX-loaded part. If I reload that part of the form, clicking on them makes confirmation popup twice. Now, I know I can test inside function if it's the first time in a row it's called, but I would prefer to make sure it is added to my element only once, and thus called only once. How can I do that?

19

The once() function will help with that,e.g.

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

      $('.skip-line', context).once('mymodule').on('change', function(){
        // some code
        if ( confirm(Drupal.t('Apply to all languages?')) ) {
          // applying...
        }
      });
    }
  };
})(jQuery);

One of the many references

  • 2
    Thanks. Worked like a charm. I guess that's one of these moments when I simply fail to ask Google properly. I asked about preventing twice and preventing multiple. If only I have asked about doing it once... – Mołot Nov 8 '13 at 11:47
  • 1
    @Mołot But thanks to your comment being indexed, I found it when I searched for prevent multiple :-D – frazras Oct 21 at 14:24
6

You need to use the once() function to achieve this. From this page

Drupal.behaviors.myModule = {
  attach: function (context, settings) {
    $('element', context).once('myModule', function () {
     // any behavior is now applied once
    });
  }
};

The string "myModule" passed to the function is set as a marker on the elements matching the jQuery selection, so the next time once is called it ignores them. Do not use the same string if you call the once function multiple times for different purposes, otherwise you may defeat its purpose.

  • Thank you for your explanation :) Accepted Clive's answer as his code worked for me directly and your didn't, but I like your description better. – Mołot Nov 8 '13 at 11:50
0

you can also do this too:

(function ($, Drupal, drupalSettings) {
    'use strict';
Drupal.behaviors.someThing = {
        attach: function (context) {
            if (context === document) {
               console.log('called inside'); // Once <-- 
            }
            console.log('called outside'); // can be manny manny  <-- 
         },
    };
})(jQuery, Drupal, drupalSettings);
0

here is another way to have a function that runs once:

(function($, Drupal) {

  var initialized;

  function init() {
    if (!initialized) {
      initialized = true;
      // Add your one-time only code here
    }
  }

  Drupal.behaviors.someKey = {
    attach: function() {
      init();
    }
  };

}(jQuery, Drupal));

Source: https://www.drupal.org/forum/support/module-development-and-code-questions/2018-06-15/run-js-funtion-once-not-attach-once#comment-12654121

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.