I am building a module that uses 3rd party jquery plugin. To start this plugin my module adds a script that passes parameters and initiates the plugin. Something like this:

$(function() { 
  $('some_selector').startPlugin({
    option1: value1,
    option2: value2,
    optionN: valueN
  });
});

The module adds this script as a file via backdrop_add_js and passes options via the same function:

backdrop_add_js('path/script_filename.js', 'file');
backdrop_add_js($options_array, 'settings');

It all works fine until I have one instance(i.e. block) of my module per page. If I have multiple instances then the script is supposed to be added once per instance passing different options each time. But in that case only one module on the page actually works. It appears that the script file is added only once no matter how many modules are on a page. I wonder if there is a way to add same script file multiple times to the same page? I have tried using 'cache' and 'preprocess' options when calling backdrop_add_js, but no result. 

I actually managed to solve this by using 'inline' mode and passing a script code as a string with inserted option values. But it would be more convenient for me to use file and settings so I wonder if there is a way to make this.

Accepted answer

@BWPanda, your advice was very helpful, thank you!

I explored a module that has some common functionality (Views Slideshow in particular) and found a solution there. Though it now looks simple I will put it here for future reference.

Script settings for each module instance are added as arrays with unique ids:

$id = create_some_unique_id();

$settings = array(
  $id => array(
    'option1' => value1, 
    'option2' => value2,
    'optionN' => valueN,
  ),
)

backdrop_add_js(array('my_module' => $settings), 'settings');
backdrop_add_js('script_file.js', 'file');

And the script iterates through the settings. Each iteration corresponds to one module instance:

(function($) {

  Backdrop.behaviors.myModule = {

    attach: function (context, settings) {
      for(var i in settings.my_module) {
        $('#' + i).startPlugin({
          option1: settings.my_module[i].option1,
          option2: settings.my_module[i].option2,
          optionN: settings.my_module[i].optionN,
        });
      }
    }

  };
})(jQuery);

That's it.

Comments

BWPanda's picture

path/script_filename.js should only be added to the page once, whereas you should call backdrop_add_js($options_array, 'settings'); as many times as you need with different options in the array.

See if you can find other modules that do a similar thing and see how/when they call these things, and how they access the passed-in settings from the script file.

@BWPanda, your advice was very helpful, thank you!

I explored a module that has some common functionality (Views Slideshow in particular) and found a solution there. Though it now looks simple I will put it here for future reference.

Script settings for each module instance are added as arrays with unique ids:

$id = create_some_unique_id();

$settings = array(
  $id => array(
    'option1' => value1, 
    'option2' => value2,
    'optionN' => valueN,
  ),
)

backdrop_add_js(array('my_module' => $settings), 'settings');
backdrop_add_js('script_file.js', 'file');

And the script iterates through the settings. Each iteration corresponds to one module instance:

(function($) {

  Backdrop.behaviors.myModule = {

    attach: function (context, settings) {
      for(var i in settings.my_module) {
        $('#' + i).startPlugin({
          option1: settings.my_module[i].option1,
          option2: settings.my_module[i].option2,
          optionN: settings.my_module[i].optionN,
        });
      }
    }

  };
})(jQuery);

That's it.