Hello everyone!
We're migrating from Hubspot to Marketo on the company and using Global Forms. When I have to add only one on the page, everything is fine, but there's a specific page with a tabbed interface with four forms, and I have no idea how to add the same global form multiple times there.
I know there's a solution to add the same form multiple times, but since I need to use a redirect and change the CTA text script, I am still trying to figure out what to do. Here's the code I'm using:
<form id="mktoForm_1003"></form>
<script>
MktoForms2.loadForm("//info.mail.quorum.us", "590-ATW-173", 1003, function(form){
//Add an onSuccess handler
form.onSuccess(function(values, followUpUrl) {
// Take the lead to a different page on successful submit, ignoring the form's configured followUpUrl
location.href = "https://www.youtube.com/watch?v=HjBo--1n8lI";
// Return false to prevent the submission handler continuing with its own processing
return false;
});
});
MktoForms2.onFormRender( function(form) {
var loc = document.createElement('a'); // new Location object for easier parsing
loc.href = document.referrer;
document.querySelector('.mktoButton').innerText = "Watch Webinar"
decodeURIComponent( loc.search.substring(1) ); // use the whole query string as button label, this is just a demo
});
</script>
(The script to load the forms2.min.js goes separately on the header)
Thanks in advance for any help 🙂
Solved! Go to Solution.
Got it. So, here's a working solution:
HTML:
<form class="mktoForm" data-formId="X005" data-formInstance="one"></form>
<form class="mktoForm" data-formId="x005" data-formInstance="two"></form>
JS:
(function() {
/* config area - replace with your instance values */
var formIds = [X005],
podId = '//info.example.com',
munchkinId = '690-TWA-183';
/* no need to touch anything below this line */
var MKTOFORM_ID_PREFIX = 'mktoForm_', MKTOFORM_ID_ATTRNAME = 'data-formId';
formIds.forEach(function(formId) {
var loadForm = MktoForms2.loadForm.bind(
MktoForms2,
podId,
munchkinId,
formId
),
formEls = [].slice.call(
document.querySelectorAll('[' + MKTOFORM_ID_ATTRNAME + '="' + formId + '"]')
);
(function loadFormCb(formEls) {
var formEl = formEls.shift();
formEl.id = MKTOFORM_ID_PREFIX + formId;
loadForm(function(form) {
formEl.id = '';
formEls.length && loadFormCb(formEls);
});
})(formEls);
});
})();
MktoForms2.whenReady(function(readyForm){
var form = readyForm.getFormElem()[0];
var instance = form.dataset.forminstance;
/* Follow-up URLs */
// Add an IF/ELSE IF to each copy of the form and then change the location.href inside to change to where each copy needs to go after submitted
readyForm.onSuccess(function(submittedValues, followUpUrl){
if (instance == "one") {
location.href = "https://www.bing.com";
} else if (instance == "two" ) {
location.href = "https://www.google.com";
}
return false;
});
/* CTA Texts */
// querySelectorAll generates a NodeList. Copy a line to each copy of the form you have on the page, counting from zero
document.querySelectorAll('.mktoButton')[0].innerText = 'Watch Webinar 1';
document.querySelectorAll('.mktoButton')[1].innerText = 'Watch Webinar 2';
});
I know it can be better (and if anyone else finds a way to improve please post here) but it works! Thanks, @SanfordWhiteman for your help, I learned a lot working on this.
P.S: Remember that the forms2.min.js script is been loaded outside this on my case.
Switch to a central whenReady listener instead of using an onReady listener (onReady = the 4th argument to loadForm).
Then you can selectively add onFormRender and onSuccess listeners based on the form ID.
MktoForms2.whenReady(function(readyForm){
let formId = readyForm.getId();
readyForm.onSuccess(function(submittedValues, followUpUrl){
if( formId == 123 ) {
// choose follow up URL
} else if ( formId == 456 ) {
// choose another follow up URL
}
return false;
});
readyForm.onFormRender(function(renderedForm){
if( formId == 123 ) {
// set button text
} else if ( formId == 456 ) {
// set other button text
}
});
});
@SanfordWhiteman thank you very much for your answer but since it's a global form they all have the same ID. Perhaps I can add onFormRender and onSucess based on some data-attribute?
Yes, you can use a data-form-instance attribute.
Hi @SanfordWhiteman, thanks again.
I'm trying to use both codes ("same form, multiple times and the one you gave me) in one, and I'm probably missing something, but this new code isn't working 100%.
The first part, to multiply the form on the page, works perfectly, and the second part is being read until 'whenReady.' If I put any console.log or try any basic stuff with the variables I add there, it works fine, but nothing happens when I try to use onSuccess or onFormRender. Here's the code I'm using:
(function() {
/* config area - replace with your instance values */
var formIds = [123],
podId = '//info.example.com',
munchkinId = '590-WTA-183';
/* no need to touch anything below this line */
var MKTOFORM_ID_PREFIX = 'mktoForm_', MKTOFORM_ID_ATTRNAME = 'data-formId';
formIds.forEach(function(formId) {
var loadForm = MktoForms2.loadForm.bind(
MktoForms2,
podId,
munchkinId,
formId
),
formEls = [].slice.call(
document.querySelectorAll('[' + MKTOFORM_ID_ATTRNAME + '="' + formId + '"]')
);
(function loadFormCb(formEls) {
var formEl = formEls.shift();
formEl.id = MKTOFORM_ID_PREFIX + formId;
loadForm(function(form) {
formEl.id = '';
formEls.length && loadFormCb(formEls);
});
})(formEls);
});
})();
MktoForms2.whenReady(function(readyForm){
let instance = document.getElementsByClassName('mktoForm');
let form1 = instance.item(2).getAttribute('data-formInstance');
let form2 = instance.item(3).getAttribute('data-formInstance');
readyForm.onSuccess(function(submittedValues, followUpUrl){
if( form1 == "one" ) {
// choose follow up URL
} else if ( form2 == "two" ) {
// choose another follow up URL
}
return false;
});
readyForm.onFormRender(function(renderedForm){
if( form1 == "one" ) {
// set button text
} else if ( form2 == "two" ) {
// set other button text
}
});
});
Not sure what you’re trying to do there but I don’t like to see .item() in 2023! That’s some old, old stuff and by no means advisable.
Within that whenReady listener, the HTML form element is
readyForm.getFormElem()[0]
Oh, good to know! 😅
My idea was to try to filter the form by the form-instance attribute getting first all the forms with ClassNames and then creating a variable for each one. Since getElementsByClassNames give me an Object, the first thing I thought of using was item, but I confess that I need to update (and improve) my Javascript skills.
Anyway, thanks again for your help! 🙂
So, here I am again.
@SanfordWhiteman , thanks for letting me know how to grab the HTML form, and with that, I could improve the code. Now the first script is working fine, the whenReady is working fine, is capturing the forminstance and I can use it on the code. The thing now is, and I don't know why when the code gets to the readyform.onFormRender it stops. Nothing inside there is read. Here's the code updated:
(function() {
console.log("first script loading");
/* config area - replace with your instance values */
var formIds = [X004],
podId = '//info.example.com',
munchkinId = '950-TWA-183';
/* no need to touch anything below this line */
var MKTOFORM_ID_PREFIX = 'mktoForm_', MKTOFORM_ID_ATTRNAME = 'data-formId';
formIds.forEach(function(formId) {
var loadForm = MktoForms2.loadForm.bind(
MktoForms2,
podId,
munchkinId,
formId
),
formEls = [].slice.call(
document.querySelectorAll('[' + MKTOFORM_ID_ATTRNAME + '="' + formId + '"]')
);
(function loadFormCb(formEls) {
var formEl = formEls.shift();
formEl.id = MKTOFORM_ID_PREFIX + formId;
loadForm(function(form) {
formEl.id = '';
formEls.length && loadFormCb(formEls);
});
})(formEls);
});
})();
MktoForms2.whenReady(function(readyForm){
console.log('whenReady loading');
var forms = readyForm.getFormElem()[0];
var instance = forms.dataset.forminstance;
if (instance == "one") {
console.log('Form 1');
} else if (instance == "two" ) {
console.log('Form 2');
}
// Until here everything is working fine
readyForm.onFormRender(function(renderedForm){
console.log('onFormRender loading');
if (instance == "one") {
var loc = document.createElement('a'); // new Location object for easier parsing
loc.href = document.referrer;
document.querySelector('.mktoButton').innerText = "Watch Webinar 1"
decodeURIComponent( loc.search.substring(1) ); // use the whole query string as button label, this is just a demo
} else if (instance == "two" ) {
var loc = document.createElement('a'); // new Location object for easier parsing
loc.href = document.referrer;
document.querySelector('.mktoButton').innerText = "Watch Webinar 2"
decodeURIComponent( loc.search.substring(1) ); // use the whole query string as button label, this is just a demo
}
});
});
As you can see I put some console.log to check where the code is going and when it gets to whenReady the first log is read and the first if-else works fine. After that, nothing. If I understand correctly after the form is rendered at least the 'onFormRender loading' log was supposed to show it, right?
Can you (or someone else) give a light on what's happening?
FYI: After this post I decided to test it changing the readyform.onFormRender to MktoForms2.onFormRender and it worked for the first form.
FYI: OnSuccess works fine. The issue is with definitely on the onFormRender.