Skip to main content

Drupal 7 vs Drupal 8, behaviors, and jQuery Once

When porting some front-end code from Drupal 7 to Drupal 8, I ran into an unexpected change in the use of jQuery.once(). In Drupal 7, you’d do this in a behavior:

//DRUPAL 7
Drupal.behaviors.exampleBehavior = {
  attach: function(context, settings) {
    $('.example', context).once('example-behavior', function() {
      // Do stuff.
    });
  },
  detach: function(context, settings, trigger) {
    $('.example', context).removeOnce('example-behavior', function() {
      // Undo stuff.
    });
  }
};

In Drupal 8, however, you can’t pass in a function to jQuery.once(), as the API for that jQuery plugin has changed. It now acts like jQuery.filter(), in that it filters out any elements that have already been processed so they aren’t processed more than once, and returns a jQuery collection. So, in Drupal 8, the example would be:

//DRUPAL 8-9
Drupal.behaviors.exampleBehavior = {
  attach: function(context, settings) {
    $('.example', context).once('example-behavior').each(function() {
      // Do stuff.
    });
  },
  detach: function(context, settings, trigger) {
    $('.example', context).removeOnce('example-behavior').each(function() {
      // Undo stuff.
    });
  }
};

In order to have access to jquery and the Drupal JS features you need to add this in your custom libraries yml file

search_results:
  version: VERSION
  css:
    theme:
      css/search_results.css: {}
  js:
    js/search_results.js: {}
  dependencies:
    - core/drupal
    - core/js-cookie
    - core/jquery
    - core/jquery.once

Where search_results is my custom "library" in the custom_modules.libraries.yml file.

And then in your search_results.js file you will have something like this

/**
 * Attaches the single_datetime behavior.
 *
 * @type {Drupal~behavior}
 */
(function ($, Drupal, drupalSettings) {
  'use strict';
  Drupal.behaviors.rangeSliderDistance = {
    attach: function (context, drupalSettings) {


        $(context).find("#distance-slider").once("apply_range_slider_distance").each(function () {

          // Do magic JS here           

        }); //end of once filter

      }
    };

})(jQuery, Drupal);

 

From: https://ambientimpact.com/web/snippets/drupal-8-behaviors-and-jquery-on…

javascript custom module