How to trigger function on an embedded form's submission?

I set this example up to paint the picture of what I am trying to achieve. I have an embed Hubspot form and I want to trigger an action on submit of the form. For this example if you could have it click the ‘change color’ button once the form is submitted, I can translate that to my actual use case inside of webflow.
I would love to share the actual link to the project but can’t with this client.
image

Here is the link to the page that you can use to create a solution: Static Template

Please please please let this be possible… Thank you to anyone that helps!

Would something like this work?

const submitButton = $('.hs-button')
const changeColorButton = $('#btn2')

submitButton.on('click', (event) => {
    event.preventDefault()
    console.log('submitButton clicked')
    changeColorButton.click()
})

typically something like this would work but I think since it is an embed, it cant identify the button by it’s class. I just tried that code and it didn’t work. This one is really making me scratch my head…

Anyone else have a solution?

Yea weird I’m actually seeing the same thing now. Sometimes my query selectors will return the expected result but sometimes they don’t.

I tried const b = document.querySelector('[data-reactid=".hbspt-forms-0.5.1.0"]') and it worked the first time. Refreshed the page and tried again and it was undefined.

Do you think its caused on hubspots side?

I think it has to do with how the page is embedding… we are querying from document object but it looks like there may be more than one document actually…

Ok got it working with this code:

const ccBtn = document.querySelector('#btn2')
const frames = document.querySelectorAll('iframe')
const submitBtn = frames[0].contentDocument.querySelector('.hs-button')

submitBtn.addEventListener('click', (event) => {
    event.preventDefault()
    ccBtn.click()
    console.log('click')
})

Shifted from jQuery to javascript just because. Looks like we have to query the iframe first. In this case, there are two iframes on the page (open in sandbox on bottom) so I just got them both and then access the one from Hubspot by calling frames[0]. Now we can query that embed by accessing the contentDocument.

The code could probably be improved by…

  1. Access the Hubspot from by id which is “hs-form-iframe-0” something like document.querySelector(“#hs-form-iframe-0”).contentDocument.querySelector(‘.hs-button’)
  2. Wrap everything in a ‘DOMContentLoaded’ event listener to make sure the iframes have loaded up everything.

On reading the documentation, it looks like DOMContentLoaded doesn’t wait for styles, images, and subframes so might be better of to use ‘load’.

e.g.

document.addEventListener('load', () => {
    const ccBtn = document.querySelector('#btn2')
    const submitBtn = document.querySelector("#hs-form-iframe-0").contentDocument.querySelector(".hs-button")

    submitBtn.addEventListener('click', (event) => {
        event.preventDefault()
        ccBtn.click()
        console.log('click')
    })
})

Here’s a video showing how I arrived at this code: How to select elements inside iframe with Javascript - YouTube

Dude you rock! Im excited to try this out. Will update you on how this works.

1 Like

This worked great! Thank you.
Only thing I had to change to get it to work in Webflow was change

document.addEventListener('load', () => {

to

window.addEventListener('load', function () {

Once I did that, it worked perfectly. The only thing I need to change now is having the event trigger on the form actually submitting and not just the click of the button.
This is the current code I have now but it doesnt validate if the form is actually submitted. Like if the field has an error and the form doesnt submit, it will still trigger it.

window.addEventListener('load', function () {
const testbtn = document.querySelector("#test-btn");
const submitBtn = document.querySelector("#hs-form-iframe-0").contentDocument.querySelector(".hs-button");
const hsform = document.querySelector("#hs-form-iframe-0").contentDocument.querySelector(".hs-form");

  hsform.addEventListener("submit", (event) => {
  testbtn.click();
  })
})

BTW, I’ll definitely subscribe and mark as the solution. You need one of those “buy me a coffee” links in your bio. Ill definitely buy you one for your help!

1 Like

Could you use the JavaScript constraint validation API to add a conditional statement within the submit event to check if the form is valid and then only run the click function?

Or could you get rid of browser validation altogether by adding the novalidate attribute to the form? (Mentioned in the link above)

I am totally stuck here. Ive been trying for hours to get this form to validate the info before acting out the function. Any code would help a ton.

We worked this problem a bit more in DMs. Here’s the code we ended up using:

window.addEventListener('load', function () {
const btn2 = document.querySelector("#btn2");
let form = document.querySelector("#hs-form-iframe-0").contentDocument.querySelector('.hs-form')
const subButton = form.querySelector(".hs-button");
    
  form.addEventListener("submit", (event) => {
    if (form.checkValidity()) {
      btn2.click();
    }
  })
})