Problem/Motivation
Any form, when rendered in a block, does not show any form validation error messages or status messages until after a page refresh.
When the same form is rendered using routing, messages are shown as expected without requiring a page refresh. This behaviour can be replicated in 8.1 and 8.2
Steps to reproduce
In a vanilla Drupal Core install, place the User login form block in the left sidebar. Logout, then attempt to login but deliberately enter the username and/or password incorrectly. The status message does not display.
Refresh the page and the error/validation/status message/s will now show.
Proposed resolution
Ensure that when a form in a block is submitted, any error, validation, and status messages render without requiring a page refresh.
Remaining tasks
TBD
User interface changes
None
API changes
TBD
Data model changes
TBD
Comment | File | Size | Author |
---|---|---|---|
#29 | form_validation_errors-2773333-29-interdiff.txt | 1.21 KB | Berdir |
#29 | form_validation_errors-2773333-29.patch | 2.84 KB | Berdir |
#24 | form_validation_errors-2773333-24.patch | 2.49 KB | Berdir |
#24 | form_validation_errors-2773333-24-tests-only.patch | 1.11 KB | Berdir |
#18 | form_validation_errors-2773333-18.patch | 1.38 KB | Juterpillar |
Comments
Comment #2
renukakulkarni CreditAttribution: renukakulkarni commentedComment #3
jospratiklive CreditAttribution: jospratiklive at Intelliswift commentedHI Renuka,
are you coding something like below :
$form = \Drupal::formBuilder()->getForm(Drupal\user\Form\UserLoginForm::class);
and later simply assigning to variable $variables['foo_form'] = $form;
Comment #4
Juterpillar CreditAttribution: Juterpillar commented+1
I'm also having this issue on my 8.1.8 site. I have also checked on a vanilla install of Drupal Core (8.1.9-dev) by placing the User login form block in the left sidebar and deliberately entering the username/password incorrectly. The status message does not display until the page is refreshed.
Is it possible that the messages for the page are being collated and rendered before the validation error message/s from forms in blocks have been set? Any advice, patches, or suggestions for where/how to patch would be greatly appreciated.
Comment #5
Juterpillar CreditAttribution: Juterpillar commentedAfter discussing this issue with other, more prominent contributors to Drupal, I have re-written this issue description using the recommended issue template.
I have also bumped the priority of this issue to 'Major', because this bug is present in Drupal core, and it interferes with normal site visitors' use of the site. There is no current workaround that I am aware of.
Comment #6
Fabianx CreditAttribution: Fabianx as a volunteer commentedReproduced on simplytest.me on 8.3.x, too.
I think actually this is a critical UX regression of not seeing a message for the form.
Steps to reproduce again in bullet form:
Comment #7
Wim LeersUgh, this sounds like a bug in the render system, potentially related to placeholders.
Comment #8
Wim LeersBy the way, great catch! Thanks for reporting this!
Comment #9
Fabianx CreditAttribution: Fabianx as a volunteer commentedI stay by it being a critical regression and potentially a release blocker.
It amazingly still works in 8.0.x, but fails in 8.1.x and 8.3.x. I did not test 8.2.x.
Comment #10
BerdirYes, see test history on https://www.drupal.org/pift-ci-job/450541, it apparently broke between april and mai. We're currently trying to figure out which change that was exactly.
Comment #11
Wim LeersI suspect this is an unintended (and unwanted) side-effect of either:
Comment #12
Fabianx CreditAttribution: Fabianx as a volunteer commentedI suspect it is:
#2702609: Disable placeholdering (and BigPipe) on unsafe requests to help find forms as fast as possible (to allow EnforcedResponses to work)
because we disable placeholdering, it means that the messages block might be already displayed when the other block is executed.
I think we must only disable auto-placeholdering and/or use a real placeholder for the messages block (e.g. #attached placeholders) so it gets replaced as late as possible in the page request in any case.
Comment #13
Fabianx CreditAttribution: Fabianx as a volunteer commentedConfirmed, if I place the messages block in the footer, the messages do show up.
Comment #14
Wim Leers… but didn't #2712935: Messages are not rendered last, meaning those messages set within placeholders only appear on the next request fix exactly that?
Can you explain how this somehow still renders messages before rendering other blocks? Because upon re-reading the #2712935: Messages are not rendered last, meaning those messages set within placeholders only appear on the next request patch, that should be impossible AFAICT.
Comment #15
Fabianx CreditAttribution: Fabianx as a volunteer commentedUntested, but that should be all that is needed to fix this once and for all.
Messages are just very special.
Comment #16
Fabianx CreditAttribution: Fabianx as a volunteer commented#14:
The reason is that we disable _all_ placeholdering for POST requests, so the other fix with the order never even is run.
So suddenly the order of the blocks matter again:
is the relevant snippet.
Maybe we should also just do the opt-out of placeholdering for POST requests for non-explicit placeholders (e.g. auto-placeholders) instead of for all ...
Comment #17
Wim LeersGahhhhhhh. An edge case of an edge case, all because of
EnforcedResponse
s, which we had to do this for in #2702609: Disable placeholdering (and BigPipe) on unsafe requests to help find forms as fast as possible (to allow EnforcedResponses to work).Comment #18
Juterpillar CreditAttribution: Juterpillar at Catalyst IT commentedThanks everyone for escalating this so quickly!
I have attached a patch that uses Fabianx's suggestion. I had to allow render_placeholder_generator to be a public service for this to work. I'm not sure what unintended consequences this may have.
The patch attached appears to fix this issue.
Comment #19
Wim LeersThanks, @Juterpillar! :)
We definitely still need tests for this. Tests that reproduce this problem. Looking at the steps to reproduce in the issue summary, that should be easy.
Comment #20
Wim LeersComment #22
GoldWim,
Julia has left for a 3 week break. Personally, I've not had the opportunity to play with D8 yet but this sounds like a good chance. If I can find the time I'll have a look at writing the tests for this some time this week.
Comment #23
Wim LeersAwesome, thanks a lot! I'm happy to provide reviews/tips to help you get this patch to RTBC!
Comment #24
BerdirI hope you're not too mad about me stealing away the issue :)
Here are tests using the user login block, where the existing user login block tests are. Not the perfect place to test a regression in the render system, we could also move it somewhere else, but I personally could live with them being there ;)
I've also verified with the failing simplenews tests, they pass again now with the patch applied.
Comment #25
BerdirComment #27
Wim LeersI don't think anyone is :) Thanks for jumping in!
So, basically… this patch is special-casing the messages placeholder even more. It's overriding the default behavior at:
… and is instead always calling that service. It's essentially omitting the final condition in the if-test.
In other words, once #2367555: Deprecate EnforcedResponseException support lands, this work-around will also become unnecessary and should be reverted. Hence we should duplicate that same
@todo
to the changes we're making inStatusMessages
and to the fact that we're making a private service public.Comment #28
Fabianx CreditAttribution: Fabianx as a volunteer commented+1 to adding a @todo
Comment #29
BerdirThe current issue title of that issue implies to me that we can not actually remove this yet, as it just says to deprecate it, we'd still have to support it until it is actually removed? Also, making a service public is fine, but making it private again could break some other code so it would be an API change on its own.
Anyway, added the @todo's, if it doesn't happen in that issue the in the follow-up to actually remove that. And we can decide there about the service, on purpose used "Consider".
Comment #30
Fabianx CreditAttribution: Fabianx as a volunteer commentedRTBC - Nice work!
Comment #31
catchs/to be placeholder/to be placeholdered/
- fixed on commit to 8.3.x/8.2.x, thanks!
Comment #34
Wim Leers#29: thanks for adding that. Even if it doesn't get changed during the 8.x cycle, it should definitely be fixed in 9.x. Having a
@todo
there is just a valuable reminder, because this sort of change would easily be forgotten otherwise.Comment #36
nitin.k CreditAttribution: nitin.k as a volunteer and commentedGreat #29 is working perfectly. I was facing this issue from a long time.
Many thanks !!