Building a custom module in Drupal 9.4.5. I need to have the user to select a country from one form select, and that would populate a second (states/provinces) using a form AJAX callback.
It works perfectly when I'm logged in as the admin, but when I log out, I get this error message when I attempt to select a country.
An error occurred while attempting to process /mem?ajax_form=1&_wrapper_format=drupal_ajax: ajax.$form.ajaxSubmit is not a function
This is the module I wrote.
qmem.libraries.yml
qmem_lib:
version: VERSION
dependencies:
- core/jquery
- core/drupal.ajax
qmem.routing.yml
qmem.content:
path: '/mem'
defaults:
_controller: '\Drupal\qmem\Controller\QMemController::content'
_title: 'QM Member List'
requirements:
_permission: 'access content'
qmem/src/Controller/QMemController.php
namespace Drupal\qmem\Controller;
use Drupal\Core\Controller\ControllerBase;
class QMemController extends ControllerBase {
public function content() {
$output['form'] = \Drupal::formBuilder()->getForm('\Drupal\qmem\Form\QMemFilters');
$output['#attached']['library'][] = 'qmem/qmem_lib';
// going to add a bunch of other stuff here later
return $output;
}
}
qmem/src/Form/QMemFilters.php
namespace Drupal\qmem\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Form that displays the filters for the courses page
*/
class QMemFilters extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'qmem_filters_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$country_opts = [
0 => '- Any -',
"United--States" => "United States",
"Canada" => "Canada",
"Mexico" => "Mexico",
];
if (empty($form_state->getValue('country'))) {
$selected_country = 0;
} else {
// Get the value if it already exists.
$selected_country = $form_state->getValue('country');
}
$form['country'] = array(
'#type' => 'select',
'#title' => $this->t('Country'),
'#default_value' => $selected_country,
'#options' => $country_opts,
'#prefix' => '<div class="columns large-3">',
'#suffix' => '</div>',
'#ajax' => [
'callback' => '::get_state_selector',
'wrapper' => 'states-container',
'event' => 'change'
],
);
// When the form is rebuilt during ajax processing, the $selected_country
// variable will now have the new value and so the options will change.
$form['state_province'] = [
'#type' => 'select',
'#prefix' => '<div id="states-container" class="columns large-3">',
'#suffix' => '</div>',
'#title' => $this->t('State/Province/Territory'),
'#options' => static::get_states($selected_country),
'#default_value' => !empty($form_state->getValue('state_province')) ? $form_state->getValue('state_province') : '',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
//nothing
}
public static function get_state_selector(array &$form, FormStateInterface $form_state) {
return $form['state_province'];
}
public static function get_states($country) {
$states_options = array(
'0' => '- Any -',
'AL'=>'Alabama',
'AK'=>'Alaska',
'AZ'=>'Arizona',
'AR'=>'Arkansas',
'CA'=>'California',
'CO'=>'Colorado',
);
$canada_options = array(
'0' => '- Any -',
'AB' => "Alberta",
'BC' => "British Columbia",
'MB' => "Manitoba",
);
$mexicoStatesList = array(
'0' => '- Any -',
'AG' => 'AGUASCALIENTES',
'BC' => 'BAJA CALIFORNIA',
'BS' => 'BAJA CALIFORNIA SUR',
'CH' => 'COAHUILA',
'CI' => 'CHIHUAHUA',
'CL' => 'COLIMA',
);
if(!empty($country)) {
$country = str_replace('--', ' ', $country);
}
$states = [0 => '- Any -'];
switch ($country) {
case 'United States':
$states = $states_options;
break;
case 'Canada':
$states = $canada_options;
break;
case 'Mexico':
$states = $mexicoStatesList;
break;
};
return $states;
}
I've already tried adding many different dependencies into my libraries.yml file, like core/jquery.form, core/drupal, or core/drupal.form without luck.