I'm working on a block form that needs to update certain elements in the form based on what the user selects with certain elements. I've defined the internal class method and it's getting called correctly; however, it can't access the values stored in the form from the $form_state
.
For example, when I call $form_state->getValue('filter_field')
, it returns an empty value, even though it has been set on the page. I suspect that this may be due to the fact that I'm setting the callback like so: 'callback' => [get_class($this), 'updateWidgetAjax']
, and in the final comment in the API, it says to do it like this: 'callback' => '::updateWidgetAjax'
. However, when I try this, I get the The specified #ajax callback is empty or not callable.
error. I tried following the tutorial on the API page as well as here, yet neither of them worked properly, spouting out the same error as before. I also went through this checklist, but most of the items don't apply.
Additionally, and this is just something annoying but related, if I don't mark updateWidgetAjax
as static I get the following message in my log: Deprecated function: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Drupal\global_filter\Plugin\Block\FilterBlock::updateWidgetAjax() should not be called statically
, which I suspect will be resolved with fixing the above issue.
In short, how do I get the form values in my Ajax callback?
The element calling the Ajax:
$form['filter_field'] = [
'#type' => 'select',
'#name' => 'filter_field',
'#title' => t('Select field to get the filter value from.'),
'#options' => self::getAvailableFields(),
'#empty_option' => t('Select a field'),
'#ajax' => [
'callback' => [get_class($this), 'updateWidgetAjax'],
'event' => 'change',
'wrapper' => 'default-value-ajax-wrapper',
//The wrapper is elsewhere on the form
]
'#required' => TRUE,
];
The Ajax callback function:
public function updateWidgetAjax(array &$form, FormStateInterface $form_state) {
$widget = '';
$multichoice = FALSE;
switch ($form_state->getValue('widget_type')) {
//code that sets $widget
}
//Return a render array
$render = [
'#type' => $widget,
'#name' => 'default_value',
'#title' => t('Default value'),
'#description' => t('Select the default value for this filter. Leave blank for none.'),
'#options' => self::getOptions($widget, $form_state->getValue('filter_field')),
'#required' => TRUE,
];
return $render;
}
EDIT: I forgot to mention that the form is defined with a blockForm
, since I'm trying to create new blocks with this. I'm following the Drupal documentation found here. I think this might be a big part of the issue.