Form pre-fill workaround

Jay_Jiang
Level 10

Form pre-fill workaround

This was originally posted on 20/05/2019. After the community upgrade, a member made aware to me that they could not access the post. I'm re-posting here so people can see the content again.

 


 

There's nothing worse than going on leave and coming back to find something broken. Such was the reality for our email preference centre. If you've been affected by the pre-fill fiasco (https://nation.marketo.com/docs/DOC-6909-form-pre-fill-feature-upgrade), the most likely place impacted would be your email preference centre. What I found was that forms were submitting and saving unsubscribes (phew!), but the user experience was broken.

 

So if you were in the same situation as me, here's a workaround to get pre-fill working again so you don't have to compromise on user experience.

 

If you've been reading discussions in the general community, you'll probably have read to deploy Sanford Whiteman's javascript plugin. But there is another way, which is to use the Marketo forms javascript API combined with tokens of the fields that you need pre-filled in your form. You will have to list every field by it's field ID that needs pre-filling per form, and repeat the code for each form on a landing page (with some customisation to the code below) if there are multiple forms. So deploying the workaround is easier if you've to set up global forms and a master landing page template.

 

Here's the code example:

 

 

MktoForms2.whenReady(function (form) {
  var prefillFields = {
    "Email":"{{lead.Email Address}}",
    "emailPreferencesPause":"{{lead.Email Preferences - Pause}}",
    "emailPreferencesPauseUTCTimestamp":"{{lead.Email Preferences - Pause UTC Timestamp}}"
  },
  prefillCheckboxes = {
    "Unsubscribed":"{{lead.Unsubscribed}}",
    "listEvents":"{{lead.List - Events}}",
    "listNewsletters":"{{lead.List - Newsletters}}",
    "listProductUpdates":"{{lead.List - Product Updates}}",
    "listVocusBusinessUpdates":"{{lead.List - Vocus Business Updates}}"
  },
  initFields = {},
  text = "<prefillFields>";
  MktoForms2.$.each(prefillFields,function(key,val){
    if(val.length){text += "<"+key+">"+val+"</"+key+">";}
  });
  text += "</prefillFields>";
  var parser = new DOMParser(),
  xmlDoc = parser.parseFromString(text,"text/xml"),
  xmlNodes = xmlDoc.documentElement.childNodes;
  for (i = 0; i < xmlNodes.length; i++) {
    initFields[xmlNodes[i].nodeName] = xmlNodes[i].childNodes[0].nodeValue;
  }
  MktoForms2.$.each(prefillCheckboxes,function(key,val){
    if(val){initFields[key]="yes"}
  });
  form.vals(initFields);
});

 

 

 

Explanation:

When a landing page is "generated" by Marketo, tokens in the HTML is replaced with data from the backend (which is the whole point of personalisation). We're using the Marketo forms javascript to set the field values as soon as the form is loaded with the tokens of the same fields as the form.

 

One thing to note is, fields have to be split between checkboxes and every other type of field. The reason is that Marketo saves and reads checkbox data as 1, but the Marketo forms javascript only understands "yes" or "no".

 

You will need to customise the code if you have more than 1 form on a page.

 

2020-05-12 Code updated thanks to Sanford pointing out compatibility with special chars

 

5 REPLIES 5
SanfordWhiteman
Level 10 - Community Moderator

Re: Form pre-fill workaround

This code doesn't deal properly with HTML encoding. My Pre-Fill JS is doing more than you think!

Jay_Jiang
Level 10

Re: Form pre-fill workaround

A bit better? 

SanfordWhiteman
Level 10 - Community Moderator

Re: Form pre-fill workaround

Yes, but you're creating a new document object for every value. That's why I use an XML data block. One object, one parser run.

Jay_Jiang
Level 10

Re: Form pre-fill workaround

Amended again

Jep_Castelein2
Level 10

Re: Form pre-fill workaround

Thanks Jay, this worked for me. 

 

I also had to prefill a multi-select field with multiple checkboxes and found out that this can be handled as a regular field, since the data is stored as a semicolon separated string in a TextArea field.