6

I'm using Drupal 8.

What I'm trying to do is:

  • Access the active node
  • From the node get the value of field_test and assign it to a variable
  • Pass the variable to the drupalSettings function and subsequently to a custom module 'mycustommodule' that triggers an alert

In my content type, I created a field_test field, which is the field I reference in my code. The block is placed on a page of this content type.

This is the code I am using.

mycustomblock.libraries.yml

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

MyCustomBlock.php

<?php
/**
 * @file
 *
 */

namespace Drupal\mycustomblock\Plugin\Block;
use Drupal\Core\Block\BlockBase;

/**
 * Creates a 'Foobar' Block
 *
 * @Block(
 * id = "block_mycustomblock",
 * admin_label = @Translation("MyCustomBlock"),
 * category = @Translation("Blocks")
 * )
 */
class MyCustomBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */

  public function build() {

  // get the variable from field_test
  if ($node = \Drupal::routeMatch()->getParameter('node')) {
      $test = $node->field_test->value;
      $variables['#attached']['library'][] = 'mycustomblock/custom'; 
      $build['#attached']['drupalSettings']['mycustomblock']['test'] = $test;
    }
}

custom.js

(function ($, Drupal, drupalSettings) {
  var testMe = Drupal.settings.mycustomblock.test;
  alert(testMe);
)(jQuery, drupalSettings);

How can I tell if the JavaScript file is being loaded from the block? I checked in the inspector, and do not see it being loaded when the page with the block on it loads.

Furthermore, how can I properly access the field value and pass it to JavaScript?

  • Your build method doesn’t return anything so it’s a moot point. Until you return a render array that has both the library and settings attached (currently you’re assigning those to 2 different variables for some reason), none of it will work – Clive Dec 26 '17 at 11:17
  • @clive that gives me a little direction, thank you. When you say I am attaching the library and settings to two different variables, can you please explain how I would attach them to only one? – lane Dec 26 '17 at 11:26
9

The code doesn't work because the build() method doesn't return anything, which for PHP is like returning NULL. (In other words, you are telling Drupal not to render anything.)
If you fix that, then you would also have to attach the library to the same variable to which you attach the settings.

public function build() {
  $build = [];
  // get the variable from field_test
  if ($node = \Drupal::routeMatch()->getParameter('node')) {
    $build['#attached']['library'][] = 'mycustomblock/custom'; 
    $build['#attached']['drupalSettings']['mycustomblock']['test'] = $node->field_test->value;
  }

  return $build;
}

As side note, as per Drupal coding standards, class names should follow the UpperCamel naming, a.k.a. PascalCase.

As for the JavaScript code, take node.js as guide.

(function ($, Drupal, drupalSettings) {
  Drupal.behaviors.nodeDetailsSummaries = {
    attach: function attach(context) {
      var $context = $(context);

      $context.find('.node-form-author').drupalSetSummary(function (context) {
        var $authorContext = $(context);
        var name = $authorContext.find('.field--name-uid input').val();
        var date = $authorContext.find('.field--name-created input').val();

        if (name && date) {
          return Drupal.t('By @name on @date', { '@name': name, '@date': date });
        } else if (name) {
          return Drupal.t('By @name', { '@name': name });
        } else if (date) {
          return Drupal.t('Authored on @date', { '@date': date });
        }
      });

      $context.find('.node-form-options').drupalSetSummary(function (context) {
        var $optionsContext = $(context);
        var vals = [];

        if ($optionsContext.find('input').is(':checked')) {
          $optionsContext.find('input:checked').next('label').each(function () {
            vals.push(Drupal.checkPlain($.trim($(this).text())));
          });
          return vals.join(', ');
        }

        return Drupal.t('Not promoted');
      });
    }
  };
})(jQuery, Drupal, drupalSettings);

Drupal modules should use behaviors.

See the first and the last line of the code I copied here. Your JavaScript code should use the same lines, and access the settings with drupalSettings.mycustomblock.test.

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.