4

I want to create a button on a form that when clicked:

  1. Calls some custom JavaScript
  2. Does not submit the form

Is this possible with Drupal 8 Forms?

5

Set the button_type to button:

$form['js_action'] = array(
  '#type' => 'button', 
  '#value' => t('Click me'), 
);

Custom JS you would attach, like:

$form['js_action']['#attached'] => array(
  'js' => array(
     drupal_get_path('module', 'ajax_example') . '/ajax_example.js',
);

Invoking ajax looks like this:

$form['js_action']['#ajax'] => array(
  'callback' => 'poll_choice_js',
  'wrapper' => 'poll-choices',
  'method' => 'replace',
  'effect' => 'fade',
),

With a menu callback like this:

/**
 * Menu callback for AJAX additions. Render the new poll choices.
 */
function poll_choice_js($form, $form_state) {
  return $form['choice_wrapper']['choice'];
}

Check the API for more infos ..

4

In this example, I've added a custom button action to a Drupal 8 Form. When the button is clicked, it prevents the form from being submitted and allows custom JavaScript to do some work.

Here are the 3 pieces:

  1. The form button element, with an #attached library
  2. Your custom module's library declaration
  3. The library's .js file

And here is the example code:

in ExampleForm.php

$form['actions']['clear'] = [
  '#type' => 'button',
  '#value' => $this->t('Clear'),
  '#attributes' => [
    'onclick' => 'return false;'
  ],
  '#attached' => array(
    'library' => array(
      'example/foo',
    ),
  ),
];

example.libraries.yml

foo:
  js:
    js/foo.js: {}

js/foo.js

Drupal.behaviors.example_hello = {
  attach: function (context, settings) {

    // Attach a click listener to the clear button.
    var clearBtn = document.getElementById('edit-clear');
    clearBtn.addEventListener('click', function() {

        // Do something!
        console.log('Clear button clicked!');

    }, false);

  }
};

Don't forget to clear all your caches to ensure your new foo.js library is picked up by Drupal 8.

3

Setting button_type to 'button' won't change the 'type' attribute of the resulting tag, just will add a class. There is no way to create a button with type other than 'submit' if you use 'button' or 'submit' form elements. You can always attach a javascript that prevents default behaviour of such a button, but I wouldn't recommend so.

My preferred way is to create a dedicated button by means of general-purpose html_tag element:

$element['nosubmit_button'] = [
  '#type' => 'html_tag',
  '#tag' => 'input',
  '#attributes' => [
    'type' => 'button',
    'value' => t("It won't trigger submit"),
    'class' => 'button',
    'name' => 'nosubmit_button',
  ],
  '#attached' => [
    'library' => [
      'mylibrary',
    ],
  ],

Please also note that in Drupal 8 you should attach libraries, not individual js or css files.

There are other ways to achieve the same goal, for example, you may use 'markup' element type and supply desired html markup of the button as '#markup' property. Pay attention then to #allowed_tags property also, because markup is filtered and not any tag will pass through by default (eg button tag will not).

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.