3

I’ve built a Drupal 8 Form example using code found here: http://www.drupalcontrib.org/api/drupal/contributions%21examples%21ajax_example%21ajax_example.module/function/ajax_example_dependent_dropdown/8

The code, when run, dispalys 2 selects. When a change is made to the first Select an Ajax call is made and is supposed to set a new set of options in the second Select. However when changed I get a “Uncaught PHP Exception” - "The specified #ajax callback is empty or not callable." I’ve tried multiple adjustment but am unable to get the code to run as desired.

Any answers or ideas would be greatly appreciated.

<?php
namespace Drupal\dependent_selects\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CssCommand;
use Drupal\Core\Ajax\HtmlCommand;

include 'dependent_selects.config';

class DependentSelectsForm extends FormBase
{
public function getFormId()
{
    return 'dependent_selects';
}

public function buildForm(array $form, FormStateInterface $form_state)
{
    $options_first = $this->_ajax_example_get_first_dropdown_options();
    $formValues = $form_state->getValues();
    $selected = (isset($formValues['dropdown_first'])) ? $formValues['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
      '#type' => 'select',
      '#title' => 'Instrument Type',
      '#options' => $options_first,
      '#default_value' => $selected,
      '#ajax' => array(
        'callback' => 'ajax_example_dependent_dropdown_callback',
        'wrapper' => 'dropdown-second-replace',
      ),
    );

    $form['dropdown_second'] = array(
      '#type' => 'select',
      '#title' => $options_first[$selected] . ' ' . t('Instruments'),
      '#prefix' => '<div id="dropdown-second-replace">',
      '#suffix' => '</div>',
      '#options' => $this->_ajax_example_get_second_dropdown_options($selected),
      '#default_value' => isset($formValues['dropdown_second']) ? $formValues['dropdown_second'] : '',
    );
    return $form;
}

public function ajax_example_dependent_dropdown_callback($form,  &$form_state)
{
    return $form['dropdown_second'];
}

public function _ajax_example_get_first_dropdown_options()
{
    $instType = array(
      'String' => 'String',
      'Woodwind' => 'Woodwind',
    );
    return $instType;
}

function _ajax_example_get_second_dropdown_options($key = '')
{
    $options = array(
      'String' =>
      array(
        'Violin' => 'Violin',
        'Viola' => 'Viola',
      ),
      'Woodwind' =>
      array(
        'Flute' => 'Flute',
        'Clarinet' => 'Clarinet',
      ),
    );
    if (isset($options[$key])) {
        return $options[$key];
    }
    else {
        return array();
    }
}

public function validateForm(array &$form, FormStateInterface $form_state)
{
    $a = 1;
}
public function submitForm(array &$form, FormStateInterface $form_state)
{
    $a = 1;
}

}

1 Answer 1

6

They way you specify your callback means that it is a function. You define it in your class, which means, it is not.

Prefix it with ::, that's a shortcut that tells Drupal that it's a method on the form class. You should also use camel case for the method's names. So, something like ::ajaxExampleDependentDropdownCallback (to be clear, you also have to rename your method, not just the callback string).

I also don't understand what you're trying to do with include 'dependent_selects.config';?

2
  • Thanks @Bedir the '::' works. Can you explain a bit more what you mean by :"They way you specify your callback means that it is a function. You define it in your class, which means, it is not." Can
    – Mike
    Commented Feb 19, 2016 at 22:20
  • 1
    You might want to read php.net/manual/en/language.types.callable.php. You specifiy a callback. A callback string means it's a function. But you don't have functions, you have methods. The only exception from that rule is the special '::methodName' which is explicitly supported in this case by Drupal as a method on the form class. It's just a shortcut for array($this, 'methodName). If it's the function vs method thing you're not sure about, read this: php.net/manual/en/language.oop5.basic.php
    – Berdir
    Commented Feb 19, 2016 at 23:13

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.