This might be a core issue, not sure yet how to properly fix this.
We used to implement the event and now the widget alter hook to set address default values based on fields on the logged in user. That worked fine for the first payment method. However, when you already have a stored payment method, for example with stripe, and then want to add a new one, the default values aren't there.
Took me quite some debugging but I tracked it down to some form ajax trickery that initializes the user input of all fields to NULL and then somehow that doesn't get overwritten with the actual fields.
It could be related to how the fields are created during process callbacks, so maybe for example date fields are affected in a similar way.
I found some existing issues which might the same issue, e.g. #3037289: On duplicated entities, field address is always empty or #2914208: Address field not keeping it's value when being edited inside an ief, which was closed as duplicate of the default value issue, but might actually have been this. I have been testing with the most recent version. Was actually hoping that would fix my problem, but it didn't :)
As a workaround, I did now this in my widget alter hook:
// Workaround for initializing an address field on ajax, which might have
// its input values set to null.
$input = $form_state->getUserInput();
$address_input = &NestedArray::getValue($input, array_merge($element["#field_parents"], ['address', 0, 'address']));
if (is_array($address_input) && array_key_exists('country_code', $address_input) && $address_input['country_code'] === NULL) {
NestedArray::unsetValue($input, array_merge($element["#field_parents"], ['address', 0, 'address']));
$form_state->setUserInput($input);
}
Obviously not very pretty.
Comment | File | Size | Author |
---|---|---|---|
#5 | 3047340-5-fix-default-value.patch | 7.52 KB | bojanz |
| |||
#2 | unknown-render-array-key.patch | 1.64 KB | drugan |
Comments
Comment #2
drugan CreditAttribution: drugan as a volunteer commentedI had the same issue with the commerce coupon ajax-fied pane. The reason is the invalid render key, like:
'24243535353' => NULL,
The fix is pretty the same: remove that key from the render array.
Comment #3
bojanz CreditAttribution: bojanz at Centarro commentedNarrowed it down to this part of FormBuilder::handleInputElement:
Input is processed twice (build then rebuild), the first time the address NULL value gets expanded into a an array with a NULL value for each address property, the second time that array makes Address::valueCallback() skip the default value.
We need a test. And we need to make Address::valueCallback() ignore inputs with NULL country codes (cause in reality it's never NULL, even on an optional field it's an empty string when nothing is selected).
Comment #4
bojanz CreditAttribution: bojanz at Centarro commentedComment #5
bojanz CreditAttribution: bojanz at Centarro commentedHere's a fix and a test.
Confirmed that the new test fails without the fix.
Confirmed that Commerce checkout works well with the fix.
Added Commerce specific test coverage in #3022850: [Addressbook, part 1] Rework the ownership model for customer profiles.
Comment #7
bojanz CreditAttribution: bojanz at Centarro commentedCommitted.