12

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?

2
  • 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
    Commented Dec 26, 2017 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
    Commented Dec 26, 2017 at 11:26

1 Answer 1

18

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 add the library to the render array returned from build() ($build['#attached'] in the following code).

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 a side note, class names that follow the Drupal coding standards should use the UpperCamel naming, a.k.a. PascalCase.

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 quoted. Your JavaScript code should use the same lines, and access the settings with drupalSettings.mycustomblock.test.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.