SOLVED

Re: Global forms - show custom CTA button for Known people

Go to solution
Yavor_Todorov
Level 3

Global forms - show custom CTA button for Known people

Hello,

we use global forms and we have this form CTA "{{my.FormCTA}}". This way, once we create new event program, we can easily change the form CTA from Register to Watch on-demand via program token "FormCTA".

But this seems to work only with the all-fields form.  It doesn't work with the Known Visitors form, as below:

 

<p>Welcome back, {{lead.FirstName}}!</p>
<p>{{form.Button:default={{my.FormCTA}}}}</p>
<p class="notYou">{{form.NotYou:default=Not you?}}</p>

 

I know we cannot use custom tokens in KV forms, but I know there is a way to bypass this with a JS code, I just don't know how to imlement it for the CTA button.

 

Thanks,

Yavor

 

1 ACCEPTED SOLUTION

Accepted Solutions
SanfordWhiteman
Level 10 - Community Moderator

Re: Global forms - show custom CTA button for Known people

It’s not safe to use {{my.tokens}} anywhere in Form Editor, even where they seem to be supported, because they aren’t encoded correctly, i.e. for JSON. It’s very easy to break the whole form descriptor with an otherwise legit token value.

 

What you should always do — and I have a blog post about this coming up — is put the tokens in a <datalist> where they’re correctly encoded, then read them out using JS and pop them into the form.

 

For your example:

<datalist id="marketo-tokens">
<option label="my.CTA Text">{{my.CTA Text}}</option>
</datalist>

<script>
MktoForms2.whenReady(function(readyForm){
    const formEl = readyForm.getFormElem()[0];
    const tokenList = document.querySelector("datalist#marketo-tokens");
    const kvHTML = formEl.querySelector(".mktoTemplateBox");
    
    if(tokenList && kvHTML){
        const ctaText = tokenList.querySelector("option[label='my.CTA Text']");
        const kvHTMLButton = kvHTML.querySelector("button[type='submit']");
        kvHTMLButton.innerHTML = ctaText.innerHTML;
    }
});
</script>

 

View solution in original post

4 REPLIES 4
SanfordWhiteman
Level 10 - Community Moderator

Re: Global forms - show custom CTA button for Known people

It’s not safe to use {{my.tokens}} anywhere in Form Editor, even where they seem to be supported, because they aren’t encoded correctly, i.e. for JSON. It’s very easy to break the whole form descriptor with an otherwise legit token value.

 

What you should always do — and I have a blog post about this coming up — is put the tokens in a <datalist> where they’re correctly encoded, then read them out using JS and pop them into the form.

 

For your example:

<datalist id="marketo-tokens">
<option label="my.CTA Text">{{my.CTA Text}}</option>
</datalist>

<script>
MktoForms2.whenReady(function(readyForm){
    const formEl = readyForm.getFormElem()[0];
    const tokenList = document.querySelector("datalist#marketo-tokens");
    const kvHTML = formEl.querySelector(".mktoTemplateBox");
    
    if(tokenList && kvHTML){
        const ctaText = tokenList.querySelector("option[label='my.CTA Text']");
        const kvHTMLButton = kvHTML.querySelector("button[type='submit']");
        kvHTMLButton.innerHTML = ctaText.innerHTML;
    }
});
</script>

 

Yavor_Todorov
Level 3

Re: Global forms - show custom CTA button for Known people

Thanks for the reply, @SanfordWhiteman.

The code seems to work. I wanted to add the same functionality to the Full form CTA button as below:

<datalist id="marketo-tokens">
	<option label="my.Form CTA Full">{{my.Form CTA Full}}</option>
	<option label="my.Form CTA Known">{{my.Form CTA Known}}</option>
</datalist>
<script type="text/javascript">
MktoForms2.whenReady(function(readyForm){
    const formEl = readyForm.getFormElem()[0];
    const tokenList = document.querySelector("datalist#marketo-tokens");
    const kvHTML = formEl.querySelector(".mktoTemplateBox");
    const fullForm = formEl;
 	if(tokenList && fullForm){
        const ctaTextFullForm = tokenList.querySelector("option[label='my.Form CTA Full']");
        const kvHTMLButtonFullForm = fullForm.querySelector("button[type='submit']");
        kvHTMLButtonFullForm.innerHTML = ctaTextFullForm.innerHTML;
    }

    if(tokenList && kvHTML){
        const ctaText = tokenList.querySelector("option[label='my.Form CTA Known']");
        const kvHTMLButton = kvHTML.querySelector("button[type='submit']");
        kvHTMLButton.innerHTML = ctaText.innerHTML;
    }

});
</script>

 

This works on the KV form, but if I click "Not you?" and go to the full form, I usually see some old token value, not the latest one I've inserted in Marketo. And I have to refresh in order to see the latest one. Is there a fix for this? If we can combine the 2 tokens into 1 and use only one "if" statement, it would be perfect.

 

Thanks,

Yavor

SanfordWhiteman
Level 10 - Community Moderator

Re: Global forms - show custom CTA button for Known people

Your code is incorrect. There’s always a <form> element. The existence of the element doesn’t mean you’re seeing the full form, so this line is totally misleading:

const fullForm = formEl;

 

If you want to switch behavior based on whether the kvHTML variable is truthy or falsy, do that. Don’t try to reuse unrelated variables.

 


I usually see some old token value, not the latest one I've inserted in Marketo.

I don’t understand what you mean but the {{my.token}} is the {{my.token}}. It only has one value at a given point in time. Maybe you have some old cached version of the page.

 

SanfordWhiteman
Level 10 - Community Moderator

Re: Global forms - show custom CTA button for Known people


Maybe you have some old cached version of the page.

Addendum: Marketo (via CloudFlare) does serve cached versions of anonymous pages — that is, pages viewed outside of a specific lead because the lead is not yet known, as is the case when you hit Not You? But those cached pages should not survive reapproval + a few minutes.