5

I stand on the following tricky situation:

I have a node with geofield coordinates attached. I am constructing an array of points. Something like:

Array
(
[86] => Array
    (
        [0] => Array
            (
                [lat] => 39.1641410477
                [lon] => -2.633972168
            )

        [1] => Array
            (
                [lat] => 41.0420738489
                [lon] => -2.633972168
            )

        [2] => Array
            (
                [lat] => 41.0420738489
                [lon] => 1.2524414063
            )

        [3] => Array
            (
                [lat] => 39.1641410477
                [lon] => 1.2524414063
            )
        [4] => Array
            (
                [lat] => 39.1641410477
                [lon] => -2.633972168
            )
    )

[85] => Array
    (
        [0] => Array
            (
                [lat] => 39.1641410477
                [lon] => -2.633972168
            )

        [1] => Array
            (
                [lat] => 41.0420738489
                [lon] => -2.633972168
            )

        [2] => Array
            (
                [lat] => 41.0420738489
                [lon] => 1.2524414063
            )

        [3] => Array
            (
                [lat] => 39.1641410477
                [lon] => 1.2524414063
            )
        [4] => Array
            (
                [lat] => 39.1641410477
                [lon] => -2.633972168
            )
    )
)

I want to pass this to my-googlemaps.js in order to be used by google's init map Google map is defined as:

my-map:
  header: true
js:
  js/my-googlemaps.js: { }
  https://maps.googleapis.com/maps/api/js?key=my_key&callback=initMap: {type: external, attributes: {defer: true,async: true}}
dependencies:
  - core/drupal
  - core/drupalSettings

my-googlemaps.js:
  console.log(Drupal.settings);
  function initMap() {}

This way I get Drupal.settings undefined, which makes sense I guess. On the other hanve if I place initMap into a behavior It can not be seen as a callback as defined in googleapis.com before.

Has anyone stumbled with this before? Any idea how to attack the problem?

11

You can follow document.

Attaching configurable JavaScript

In some cases, you may want to add JavaScript to a page that depends on some computed PHP information.

In this case, create a JavaScript file, define and attach a library just like before, but also attach JavaScript settings and have that JavaScript file read those settings, via drupalSettings (the successor to Drupal 7's Drupal.settings). However, to make drupalSettings available to our JavaScript file, we have to do the same work as we had to do to make jQuery available: we have to declare a dependency on it.

So that then becomes:

cuddly-slider:
  version: 1.x
  js:
    js/cuddly-slider.js: {}
  dependencies:
    - core/jquery
    - core/drupalSettings

and

$build['#attached']['library'][] = 'fluffiness/cuddly-slider';
$build['#attached']['drupalSettings']['fluffiness']['cuddlySlider']['foo'] = 'bar';

Where 'bar' is some calculated value.

Then cuddly-slider.js will be able to access drupalSettings.fluffiness.cuddlySlider.foo (and it will === 'bar').

In your case. You need use hook_preprocess_node() to add array geofield.

function YOUR_MODULE_preprocess_node($vars) {
  // You nedd process to get $geofield
  $vars['#attached']['drupalSettings']['geoField'] = $geofield
}

and file js/my-googlemaps.js you need code.

(function($, Drupal, drupalSettings) {
  Drupal.behaviors.yourbehavior = {
    attach: function (context, settings) {
       var geoField = drupalSettings.geoField.
      // You can init map here.
    }
  };
})(jQuery, Drupal, drupalSettings);
  • but this solution is buggy and cache the value, as an example I've added in preprocess on node $vars['#attached']['drupalSettings']['my_rand'] = rand(2,9999999); and in my js (function ($, drupalSettings) { Drupal.behaviors.stripe = { attach: function (context) { console.log(drupalSettings.my_rand); } }; })(jQuery, drupalSettings); always return the first generated item and cache till until I rebuild the cache it doesn't chage. – Yusef Jun 15 '18 at 6:08
  • @zhilevan You need to add cache tag node. Following topic – MrD Jun 15 '18 at 7:19
  • 1
    can you add it in your solution for the question sample? – Yusef Jun 15 '18 at 14:21

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.