I am using Drupal Commerce 2 and have created a CheckoutPaneBase for shipping methods that we get from an internal service. I am not using Ajax and when the user adds their shipping address, they go to the ShippingServicePane.
in the buildPaneForm, I call out to the service and then create an array of options that appear in a radio button input. They show correctly but when I hit continue to go to the preview pane, it gives me a 'An illegal choice has been detected. Please contact the site administrator.' All the issues I am finding online seem to relate to an Ajax call, which my site is not using, or a missing value, which my options are not missing.
Here is my buildPaneForm
public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
$service= new ShippingServiceRepository();
$options = [];
$shipping_methods = $service->get_shipping_methods();
$i = 0;
foreach ($shipping_methods as $shipping_object) {
$options[$i] = $this->t($shipping_object->Name.' - '.str_replace('USD ','',$shipping_object->TotalCharge));
$i++;
}
$pane_form['shipping_service'] = [
'#type' => 'radios',
'#default_value' => 0,
'#options' => $options,
'#required' => FALSE,
];
return $pane_form;
}
which generates a radio field like this:
<div class="js-form-item form-item js-form-type-radio form-type-radio js-form-item-shipping-services-custom-pane-shipping-service form-item-shipping-services-custom-pane-shipping-service">
<input data-drupal-selector="edit--shipping-services-custom-pane-shipping-service-0" type="radio" id="edit-shipping-services-custom-pane-shipping-service-0" name="shipping_services_custom_pane[shipping_service]" value="0" checked="checked" class="form-radio">
<label for="edit-shipping-services-custom-pane-shipping-service-0" class="option">UPS Ground - $12.06</label>
</div>
I saw and tried adding '#required' => FALSE but it also didn't solve the issue.
When I hardcoded the options, it works fine:
$options = [
0 => $this->t('Free Shipping $0'),
1 => $this->t('Next Day $15')
];
$config['system.logging']['error_level'] = 'verbose';
to settings.php to see the actual error. OR check the drupal log/admin/reports/dblog
– No Sssweat Dec 1 '20 at 19:49#process
or#pre_render
callback in order to inject options. The error you are receiving essentially means that the form, as presented, is not consistent with the form as stored in cache. Setting'#validated' => TRUE
is just tricking the form into skipping validation for that field, which will create the appearance of a functioning form while masking a deeper error. The first thing that I think you should check is whether or notbuildPaneForm
is, in fact, being called for every step. – Beau Dec 7 '20 at 21:05