Closed olihar closed 1 month ago
So this is expected behaviour when calling submitForm()
via JS, purely because that function doesn't handle a few pre-submit tasks.
Take a look at our submit event listener:
You'll notice the process goes like:
onBeforeFormieSubmit
eventvalidate()
afterValidate()
validateCaptchas()
validatePayment()
submitForm()
So if you're overriding Formie's event listener on the submit
event, or doing something in the onBeforeFormieSubmit
event, then calling submitForm()
you're skipping a bunch of things Formie normally does.
To better cater for this, so you don't have to call everything yourself, I've added a processSubmit()
function in the dev-craft-4
branch. This is the function you should call when you want to submit the form as normal, with all the bits you'd expect.
Thank you, this sounds amazing. I've updated to composer require verbb/formie:"dev-craft-4 as 2.1.24" and changed
form.form.submitForm();
to
form.form.processSubmit();
the form submits, however the submission is still going into spam with the same error message.
Hmm, Are you able to send through a minimal example of your JS for submitting the form, and anything else (forms-related) you're doing just so I can check?
thank you for coming back so quickly, please see the javascript below.
`document.addEventListener('DOMContentLoaded', function() { const form = document.querySelector('#formOne form'); if(form){ const billingReqID = form.querySelector('input[name="fields[billingRequestFlowID]"]'); if(billingReqID && billingReqID.value != ''){ const billingReqIDValue = billingReqID.value; console.log('hidden field present', billingReqIDValue); initiateGoCardlessPayment(billingReqIDValue, form); }else{ console.log('no hidden field'); }
}
}); function initiateGoCardlessPayment(billingReqIDValue, form) { if (billingReqIDValue) { console.log('Initiating GoCardless with billingRequestFlowID:', billingReqIDValue); const handler = GoCardlessDropin.create({ billingRequestFlowID: billingReqIDValue, environment: 'sandbox', onSuccess: (billingRequest, billingRequestFlow) => { console.log('Payment successful'); const mandateID = billingRequest.mandate_request.links.mandate; const mandateField = form.querySelector('input[name="fields[referenceNumber]"]'); mandateField.value = mandateID; const customerID = billingRequest.resources.customer.id; const customerField = form.querySelector('input[name="fields[customerId]"]'); customerField.value = customerID; handler.exit(); form.form.processSubmit(); }, onExit: (error, metadata) => { console.log('Payment failed', error); form.form.formSubmitError(); const redirectUrl = 'https://............./form-testing/error/'; window.location.href = redirectUrl; } }); handler.open(); } else { console.error('Billing request flow ID not set.'); form.form.formSubmitError(); } }`
(apologies if my code is terrible, we're just in the early stages or testing/playing around with what's possible)
Right, so you're essentially doing something like:
setTimeout(function() {
const $form = document.querySelector('form');
$form.form.processSubmit();
}, 2000)
Which is just an example that submits the form on page load (with a delay), not using any events, just straight submitting the form. That's a slightly different way to what I imagined, and is more a programmatic way of submitting the form, and not relying on the submit
event of a form. That's fair enough.
For this use-case, I've further split things, as you're missing out on the onBeforeFormieSubmit
event that some things will need to use. The reason I mentioned processSubmit()
is that this is often called when you're listening to this event, and you don't want the onBeforeFormieSubmit
called again (because you're already inside it), but if your case that's not what you're doing.
So instead (sorry!) you can use the initSubmit()
event. Just run a composer require verbb/formie:"dev-craft-4 as 2.1.24"
That's working for me, and I can see recaptcha loading it's client-side token with that.
Thank you for your help, unfortunately I'm still getting the same error and the entry is going into spam. I'm using
form.form.initSubmit();
When I use dev tools under network - form page - payload the 'g-recaptcha-response' is empty. Sorry, I'm not sure where I'm going wrong?
Ah, no you're right. I believe you'll need to also include the submitAction
for the form, which is used to determine whether you're going back, saving, or submitting the form. This is usually automatically done by Formie and the submit action, in combination with a button-click event handler to figure out what sort of button you're pressing.
form.form.submitAction = 'submit';
Add that before submitting and see how that goes.
Updated in 2.1.25
Amazing, that worked, thank you so much for all of your help :)
Describe the bug
Not sure if this is a bug or something I've got wrong. Note the ReCaptcha works as expected on forms that are submitted in the normal way. This is only for one form, that I submit via Javascript.
So the form is intercepted by javascript - if a specific ID is present it needs to run a function. On success of this function I do the following
form.form.submitForm();
This submits the form and saves the data - however it ends up in spam with the error
Failed Captcha “Recaptcha”: “Client-side token missing.”
When I submit the form using the Javascript submitForm function do I need to do something to include the client side token that is missing?
On a side note - that may shed some light on things, when I add the following to my js file
document.addEventListener('onFormieInit', (e) => { console.log('formie initialised'); // Fetch the Form Factory once it's been loaded let Formie = e.detail.formie; let form = Formie.getFormByHandle('myForm'); });
I don't get a console.log message. It looks like the formie.js is loaded in the page source and I've put the above inside a DOMContentLoaded event listener but still no joy.
Not sure if this affects anything though, because if the form is submitted normally (i.e. not via javascript) I don't have a problem.
Steps to reproduce
Form settings
Craft CMS version
4.10.7
Plugin version
dev-craft-4
Multi-site?
No
Additional context
No response