Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
When "Validate fields on submit" is active and the commerce checkout form has errors and one submits the form, the error validation is handled client side, how ever the ajax spinner is present in the page and the checkout button is no longer clickable.
Comment | File | Size | Author |
---|---|---|---|
#30 | 1775750-30.patch | 1.84 KB | khiminrm |
| |||
#21 | bind-enable-disable-button-listener-1775750-21.patch | 1.98 KB | eric.chenchao |
#20 | disable-button-on-submit-instead-of-click-1775750-3.patch | 849 bytes | getu-lar |
#13 | reenable-continue-if-submit-prevented-1775750-13.patch | 2.18 KB | TomTech |
Comments
Comment #1
attiks CreditAttribution: attiks commentedThere's is code in Commerce that does this, but that code assumes the page will be submitted. I'm afraid this is a commerce problem, they disable the button to fast and they don't provide a way back.
PS: This is also a problem without clientside_validation: if a user submits the form and presses escape because he/she wants to alter something, the button is gone as well.
Comment #2
rszrama CreditAttribution: rszrama commentedDoesn't sound like a problem so much as an incompatibility. In this case, Clientside Validation is interrupting the form submission process that you'd expect when the submit button is pressed, so it can simply re-enable the button / hide the throbber again if validation fails. It would have to be baked into this module or I suppose a very small secondary module that integrates the two.
Is this something you're interested in supporting in this module or is it possible to leave this off for the checkout form and document the incompatibility?
Comment #3
attiks CreditAttribution: attiks commented@ryan, clientside_validation allows override of separate forms, so it can be disabled.
It's not something that will be solved in clientside_validation, if we start doing that we have to support way too many modules.
Easy solution is that commerce adds a cancel class so clientside validation isn't fired.
Moving back to commerce, feel free to close this if it can not be solved in commerce.
Comment #4
rszrama CreditAttribution: rszrama commentedWe also can't support every other contrib in Commerce. ; )
I don't know what cancel class you're talking about, but if that's your recommended approach, then it sounds like the incompatibility just needs to be documented with that workaround implemented through a custom module or the theme layer.
Comment #5
attiks CreditAttribution: attiks commentedI you add
class="cancel"
to the submit button, clientside_validation will not validate the form. In the future we will allow custom classes. See also #1765892: Commerce Payment option change and #1707032: Make Client side validation not respond to certain input elements like Cancel button with classes other than "cancel".Comment #6
rszrama CreditAttribution: rszrama commentedOk, I wouldn't endorse that for a button that's semantically not a "cancel" button. If the class were something like "no-clientside-validation" or something, that would be better. Never know if someone has themed "cancel" buttons to look specific in an eCommerce application. : D
For what it's worth, I don't think modules should be globally altering the behavior of standard Drupal elements. We had this same problem with the Meta Tags module when it blindly added itself to any entity form, even Commerce entities that had no business having meta tag settings. The situation was even worse back in the Ubercart days when WYSIWYG modules added themselves to any textarea on the site until modules like CKEditor got really advanced filtering rules for enabling the editors on just the elements you want.
I'd strongly recommend you make Clientside Validation off by default on forms and require users to turn it on for the forms they actually want to add validation to. Perhaps in your settings form you could turn it on for a few common forms, like user registration, but leave it up to users to turn it on for additional forms.
Comment #7
attiks CreditAttribution: attiks commentedYou're right about the 'cancel' class, that's why there's a PR created upstream (we use jquery.valdiate.js), see #1707032: Make Client side validation not respond to certain input elements like Cancel button with classes other than "cancel"., but this will probably not solve #1765892: Commerce Payment option change since the form is submitted using a radio button.
I agree with you on the metatags and wysiwyg problem, I used ubercart in the past as well, but the it's not completely the same, the only thing we do is 'translating' php validation to javascript validation, I didn't had the time to look into your code, but how do you circumvent the validation happening on the other form elements? Or are you sending only part of the form using AJAX?
The philosophy of clientside_validation is to be "enable and forget", but we allow different settings for each form, so people can disable it in case of a problem. I think that most people would love to have it on the checkout page, we only need to figure out how.
Good thing is, Drupal 8 will probably have a better AJAX system supporting GET requests so we probably have less problems ;-)
Comment #8
rszrama CreditAttribution: rszrama commentedAll we're doing is client-side disabling of the button so customers don't click it multiple times. There isn't anything AJAXy going on for general form submission. The throbber is just there to indicate the form submission is in progress.
Comment #9
attiks CreditAttribution: attiks commentedActivating this and turning it into documentation, so people can use this as a work-around
Comment #10
rszrama CreditAttribution: rszrama commentedOk, and just for my clarification, does your module actually implement form level validation or just element level validation?
Comment #11
Jelle_S@rszrama Mostly element level validation. We do however support comparing two elements with each other and some other similar actions (require one of several fields,...). Whether you would call that form level validation... that's up to you ;-p
Comment #12
rszrama CreditAttribution: rszrama commentedI just wanted to make sure this module wasn't executing the form level #validate handlers, because in Drupal Commerce the checkout form uses a form level handler to "validate and submit" checkout panes, with the form level #submit handler being the one that actually progresses to the next page.
Comment #13
TomTech CreditAttribution: TomTech commentedThis issue is biting me right now.
@rszrama, would you consider this patch that I'm currently using?
It primarily rolls back the disabling that the click did if the submit is prevented/cancelled.
It also adds a detach so that the behavior is not attached multiple times when an ajax call is made on a checkout pane.
I tried to work this as separate behavior(s) without patching commerce_checkout, but couldn't see how to do that without replicating the initial bind. (The processed class is added before the click bind, so adding a behavior to "unprocess" was not enough, as a second click would not add the "processed" class, and throw subsequent clicks.)
I had an urge to remove the clone/disable/hide code. I could't really discern why that was happening, rather than just disabling the continue button itself. But, it seems to be a carryover from ubercart, so maybe there is some edge case that justifies ti being there.
Cheers!
Comment #14
MD3 CreditAttribution: MD3 commentedIs there any update to this solution at this point? I'm using HostedPCI, so if the user forgets to accept the Terms Of Service, they have to re-enter their Credit Card information again because HostedPCI is an iFrame and the page reloads. This is extremely frustrating for my users.
Comment #15
getu-lar CreditAttribution: getu-lar commentedObviously I've run into this very same issue. Amazing that nobody seems to care enough to come up with a permanent solution ... in three years.
In any case, here's my take on a workaround / fix: Couldn't the issue be resolved while maintaining functional backwards compatibility simply by executing the button-disable-code in the submit event instead of the click event? From a conceptual JavaScript perspective, this makes more sense since the purpose of the code as far as I understood is to prevent double submissions - and as we've established, clicking on a button does not necessarily imply a submission. I'm not too sure about the inner workings of the clientside validation code, but it looks to me like the relevant piece of validation is performed in a "beforeSubmit" Drupal AJAX handler which should be fine.
Some basic testing on my end supports my theory that it basically works and doesn't break anything else.
Assuming that this is a workable solution, would it be possible to integrate this into the commerce code directly?
Comment #16
getu-lar CreditAttribution: getu-lar commentedSorry. Attached the wrong patch before.
Comment #17
getu-lar CreditAttribution: getu-lar commentedComment #20
getu-lar CreditAttribution: getu-lar commentedAnd another try with a re-rolled patch against the latest HEAD.
Comment #21
eric.chenchao CreditAttribution: eric.chenchao commentedIs it possible to add listeners to enable/disable continue button? By doing this, other modules can control button status in their logic?
I have attached a patch for suggestion. So other module can just trigger event to enable continue button by using JavaScript as below:
Also I have created a small module commerce_clientside_validation to fix issue when using clientside validation in Commerce checkout pages
https://www.drupal.org/sandbox/cityreader/2545780
Comment #22
rooby CreditAttribution: rooby commentedSince this has been made a meta issue can someone update the main post with a list of the known difficulties?
Either that or change the title to better describe the issue. It is a bit confusing as it currently is.
Comment #23
ahillio CreditAttribution: ahillio commentedThere are multiple ways that a website might have jquery form validation - via the theme, via the clientside_validation module as discussed here, and CiviCRM also includes jquery form validation. It would be nice for lowly sitebuilders like myself to have a fix for this committed.
The two recent patches failed to apply to 1.11 but #20 applied successfully to 7.x-1.11+33-dev (didn't try #21). Thank you for the patches!!!
Comment #24
rooby CreditAttribution: rooby commentedSo can we remove the " [META] Drupal Commerce known difficulties -- " part of the title and just make it "Conflicts with various jquery validation methods"?
Comment #25
ahillio CreditAttribution: ahillio commentedGiven that the title was three years old and that there are now patches to test... I think so. I had to look up what meta means in this context. For me, this was an actual functional fix, as without it the checkout page would effectively break for customers. Simple fix I think, hope to see one committed :)
Comment #26
cosolom CreditAttribution: cosolom commentedI have the same issue. I have enabled commerce_checkout_login and custom shipping module with required fields. when i have not filled required fields and press "continue checkout" i have unclickable checkout button with throbber and browser message that required fields is empty. #20 helped me
Comment #27
TomTech CreditAttribution: TomTech commentedI would be careful with the proposed solution in #20.
It is possible this will not prevent the problem the original code is trying to prevent.
If someone double-clicks the button, The two clicks can fire before the submit handler is fired for the first event, allowing the form to be submitted twice. Not good in a commerce solution, as you want to avoid double orders.
The original proposed solution in #13 (and I think also the variant in #21) continues the behavior of disabling on the initial click, preventing multiple submissions, but takes care of re-enabling the button if the submit fails or is prevented, allowing the button to be invoked again.
Comment #28
cosolom CreditAttribution: cosolom commented@TomTech do you tried by double clicking on submit button get several duplicated orders? I don't think that this is possible, because spent a lot of time in entrails of commerce. and i don't want submit data if not all required fields is filled. this is part of client side validation. But in any case thanks for a warning
Comment #29
sushilkr CreditAttribution: sushilkr commented#20 patch work for me, main thing is behaviour was click we need to change submit behaviour
Comment #30
khiminrm CreditAttribution: khiminrm at Centarro commentedTested both patches from #13 and #20. Patch from #20 doesn't make any sense. A code inside 'submit' event is never triggered. It just removes functionality from the button on click 'event'. The patch from #13 looks more logical. And when form is submitted after successful client side validation, btn is disabled and ajax spinner is added as before using the patch . I've re-rolled the patch to last dev version.
Comment #31
danmer CreditAttribution: danmer at Lemberg Solutions, Centarro commentedTested. Patch from comment #30 works as expected.
Comment #32
rszrama CreditAttribution: rszrama at Centarro commentedThanks for working through this everyone. Committing now for Commerce 1.16.
Comment #33
rszrama CreditAttribution: rszrama at Centarro commented