SOLVED

JavaScript Forms API is loading form elements more than once

Go to solution
Highlighted
Level 1

JavaScript Forms API is loading form elements more than once

We have a lot of clickable CTA elements on our website (sidebar graphics, download buttons, hyperlinks, etc) that contain a Marketo form id via the CTA element's data-attribute. When a CTA element is clicked, the form id is retrieved from the data-attribute, and then using the JavaScript API loadForm method we render the form inside of a panel that slides up from the bottom of the page.

This functionality has worked well for months, until recently when we discovered an issue that if the user rapidly clicks the CTA multiple times, the form children elements (input fields, labels, submit buttons, etc) are getting duplicated. The problem seems to be that if the forms script is aborted before it has a chance to render the form, when executed again it appends the form elements from the previous call to the current form object, causing duplicates of the form's elements to get loaded.

I've tried all the typical methods I would think would fix the issue (disabling the element that gets clicked, setting flag variables, timeouts, etc.) to ensure the loadForm script isn't being called multiple times, but maybe I should be looking at using a different method of retrieving/rendering the form?

I've created a codepen displaying the issue here: https://codepen.io/jonbenwaa/pen/aWapvL

It may take a few tries to get it to occur, but it will happen if you rapidly click on the of the sidebar images fast enough. Also I attached a screenshot of it occurring as well so you can see what I'm talking about. Any help is appreciated.

codepen-form-loading-twice.png

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Level 10 - Community Moderator

Re: JavaScript Forms API is loading form elements more than once

Thanks! I was actually looking over your pens before making this post, Sanford Whiteman 2 (FigureOne)

It's actually Sanford Whiteman for the future . (That's one of my other accounts.)

Before I start rewriting my actual code to restructure the Marketo methods, I wanted to ask you a few things on your pen-
  • Is the a#doClix element you added in the HTML along with the click listener (JS line 48) just an example of triggering the getMktoForm method?
  • Lastly, what is going on with the array you're iterating through in the jQuery click event? I know I'm a little behind on my ES6 syntax, but I don't get what's going on with a 1-5 loop inside the click event.

Woopsy, I just deleted that stuff. That was debug code. Nothing to worry about!

  • is there logic in the loadForm method that looks to see if there is a form id already on the page? Is that why clearing it in whenReady helps resolve this issue

Yep. It's in the internal XHR callback from loadForm. So you can't intercept it directly, but if there's no form with the matching ID it becomes a no-op.

View solution in original post

8 REPLIES 8
Highlighted
Level 10 - Champion Alumni

Re: JavaScript Forms API is loading form elements more than once

Highlighted
Level 10 - Community Moderator

Re: JavaScript Forms API is loading form elements more than once

Thanks man. On it as soon as I get done with some other stuff.

Highlighted
Level 10 - Community Moderator

Re: JavaScript Forms API is loading form elements more than once

Yep, Forms 2.0 isn't fully evented for a deployment like this, and you have a race condition. But you can vastly reduce the real-world cases by clearing the form id whenReady, as shown here:

     MktoForms2 :: <form> singleton

Your code also had an inevitable memory leak warning (not necessarily an actual memory leak, depending on the browser) because you were constantly adding to the event stack. No need to do that: you should pull the whenReady out of the instantiation routine, as in my Pen. Also a lot less wear-and-tear on the DOM that way, FWIW.

Highlighted
Level 1

Re: JavaScript Forms API is loading form elements more than once

Thanks! I was actually looking over your pens before making this post, Sanford Whiteman 2 (FigureOne)​, so that's awesome that you're the one responding.

Before I start rewriting my actual code to restructure the Marketo methods, I wanted to ask you a few things on your pen-

  • Is the a#doClix element you added in the HTML along with the click listener (JS line 48) just an example of triggering the getMktoForm method?
  • After seeing where you put whenReady, it makes more sense to call it once after a form object has been created, as oppose to each time the loadForm method is called. But how is clearing the form id at this point helping prevent the double load issue? I get that the id is no longer needed once the form has already been loaded, but is there logic in the loadForm method that looks to see if there is a form id already on the page? Is that why clearing it in whenReady helps resolve this issue?
  • Lastly, what is going on with the array you're iterating through in the jQuery click event? I know I'm a little behind on my ES6 syntax, but I don't get what's going on with a 1-5 loop inside the click event.

Regardless, I appreciate your help and have enough to get started on the real code.

Thanks again

Highlighted
Level 10 - Community Moderator

Re: JavaScript Forms API is loading form elements more than once

Thanks! I was actually looking over your pens before making this post, Sanford Whiteman 2 (FigureOne)

It's actually Sanford Whiteman for the future . (That's one of my other accounts.)

Before I start rewriting my actual code to restructure the Marketo methods, I wanted to ask you a few things on your pen-
  • Is the a#doClix element you added in the HTML along with the click listener (JS line 48) just an example of triggering the getMktoForm method?
  • Lastly, what is going on with the array you're iterating through in the jQuery click event? I know I'm a little behind on my ES6 syntax, but I don't get what's going on with a 1-5 loop inside the click event.

Woopsy, I just deleted that stuff. That was debug code. Nothing to worry about!

  • is there logic in the loadForm method that looks to see if there is a form id already on the page? Is that why clearing it in whenReady helps resolve this issue

Yep. It's in the internal XHR callback from loadForm. So you can't intercept it directly, but if there's no form with the matching ID it becomes a no-op.

View solution in original post

Highlighted
Level 1

Re: JavaScript Forms API is loading form elements more than once

Actually scratch the second question, I see in the API reference that

     "If there is already a form that is ready at the time this function is called, the passed callback will be called immediately."

So after seeing your solution, I'm assuming this looks for a form element with an existing id- so clearing the id forces it to reinitialize it?

Highlighted
Level 1

Re: JavaScript Forms API is loading form elements more than once

Geez you're fast lol. But thanks for the clarification!

Level 10 - Community Moderator

Re: JavaScript Forms API is loading form elements more than once

So after seeing your solution, I'm assuming this looks for a form element with an existing id- so clearing the id forces it to reinitialize it?

Actually, your first instinct was correct, which is that it relies on undoc'd behavior, not anything in the published event model.