SOLVED

PURL not prefilling and what if Code is wrong

Go to solution
Highlighted
Level 5

PURL not prefilling and what if Code is wrong

All,

two issues:

Basic PURL behaviour

I've been working to get PURLs behaving and haven't had any joy thus far. 

I have a Marketo Landing Page.  On that landing page, I have dropped a Marketo form.

I have enabled PURLs in Admin.

I have enabled PURLs in the Landing Page.

I have enabled prefill of forms in Admin.

I have enabled prefill of forms in the Landing page.

I have read widely on the forums, and have yet to become enlightened 😞

If I type in https://mydomain/mylandingpage/mycode, I do not get anything being prefilled.

 

Fall back PURL behaviour

If someone enters a URL with an invalid PURL Unique Code, is there a way to display an entirely different landing page (or at least to hide the form and replace it with different text)?

 

Cheers and thanks in advance for the help.

Jo

2 ACCEPTED SOLUTIONS

Accepted Solutions
Highlighted
Level 10 - Community Moderator

Re: PURL not prefilling and what if Code is wrong


If someone enters a URL with an invalid PURL Unique Code, is there a way to display an entirely different landing page (or at least to hide the form and replace it with different text)?


You can detect if a token on the page that should be filled in (say, Postal Code, since you're doing direct mail) is empty.

 

if( "{{lead.Postal Code}}" == "" ) {
  // do something
}

View solution in original post

Highlighted
Level 5

Re: PURL not prefilling and what if Code is wrong

@SanfordWhiteman ,

It WORKS!!!!

 

I've now got this code in the LP template I am using: 

 

    <script id="teknklFormsPlus-base-1.0.3" src="//cdpn-js.figureone.com/teknkl-formsplus-1.0.3.min.js"> </script>
    <script id="teknklFormsPlus-purl-1.0.0" src="//cdpn-js.figureone.com/teknkl-formsplus-purl-1.0.0.min.js"> </script>
    <script> FormsPlus.pURL.fixSession(); </script>

 

As per this blog post of yours, this code is sitting right under the <title> tags in the <head> section.

 

I've removed my cookie deletion stuff from the page code, so I now have this:

 

<datalist class="exported-tokens">
  <option data-replace-into-mktoform-field="LastName">{{lead.Last Name}}</option>
  <option data-replace-into-mktoform-field="FirstName">{{lead.First Name}}</option>
  <option data-replace-into-mktoform-field="Email">{{lead.Email Address}}</option>
</datalist>

<script>
document.addEventListener("DOMContentLoaded", function() {
  var arrayify = getSelection.call.bind([].slice);
  
  function replaceWithExports(parentContainer) {
    var exportedTokens = arrayify(document.querySelectorAll(".exported-tokens option")),
        replaceablesByTarget = arrayify(parentContainer.querySelectorAll(".replace-with-exported-token:not(.replace-done)")),
        replaceablesBySource = exportedTokens.filter(function(token){ return token.hasAttribute("data-replace-into-selector") || token.hasAttribute("data-replace-into-mktoform-field"); }),
        replaceables = replaceablesByTarget.concat(replaceablesBySource);
    
        replaceables
          .forEach(function(replaceable) {
            var contentSource,
                contentTarget,
                contentTargetType,
                contentProperty;
                      
            if( replaceable.hasAttribute("data-replace-into-mktoform-field") ) {
              contentSource = replaceable;
              contentTarget = {};
              contentTargetType = window.MktoForms2;
            } else if( replaceable.hasAttribute("data-replace-into-selector") ) {
              contentSource = replaceable;
              contentTarget = parentContainer.querySelector(replaceable.getAttribute("data-replace-into-selector"));
              contentTargetType = HTMLElement;
            } else {
              contentSource = exportedTokens.filter(function(token){ return token.label == replaceable.getAttribute("data-exported-token"); })[0];
              contentTarget = replaceable;
              contentTargetType = HTMLElement;
            }
          
            if ( !(contentSource && contentTarget && contentTargetType) ) return;

            if( contentTargetType == window.MktoForms2 ) {
               contentProperty = contentSource.getAttribute("data-replace-into-mktoform-field");
            } else if( contentSource.hasAttribute("data-target-related-property") || contentTarget.hasAttribute("data-target-related-property") ) {
               contentProperty = contentSource.getAttribute("data-target-related-property") || contentTarget.getAttribute("data-target-related-property");
            } else if( contentSource.hasAttribute("data-allow-html") || contentTarget.hasAttribute("data-allow-html") ) {
               contentProperty = "innerHTML";
            } else {
               contentProperty = "textContent";              
            }
                    
            contentTarget[contentProperty] = contentSource.value;
            
            if( contentTargetType == window.MktoForms2 ) {
              MktoForms2.whenReady(function(form){
                form.setValuesCoerced(contentTarget);
              });
            } else if ( contentTargetType == HTMLElement ) {
              contentTarget.classList.add("replace-done");
            }
          }

);
  }

  replaceWithExports(document);

  // This fires an alert if the code is invalid.  Replace with a redirect to error LP when done.
  if( "{{lead.Last Name}}" == "" ) {
                  //window.location.href = "https://put.your.domain.here/your.incorrect.code.page.here.html";
                  window.alert("dead soldier");
                }
 
});
</script>

 

Which gives me pURL prefill working very nicely AND diversion to a different landing page if there is an issue with the supplied Unique Code (e.g. the person has typed it incorrectly).

 

This solution now works!!!  Thanks for your help, and hopefully this will now be a nice worked example for others to follow (pulling together three topics; Clearing cookies, pURL pre-filling, and pURL fall back pages into one place).

 

Cheers

Jo

 

 

View solution in original post

7 REPLIES 7
Highlighted
Level 10 - Community Moderator

Re: PURL not prefilling and what if Code is wrong

pURLs don't automatically Pre-Fill, but that's OK. You can get the same effect using tokens correctly output ("exported") to the page and then pushed to the form.

 

Add a <datalist> to the page, including all the interesting fields you want. 

 

<datalist class="exported-tokens">
  <option data-replace-into-mktoform-field="Company">{{company.Company Name}}</option>
  <option data-replace-into-mktoform-field="FirstName">{{lead.First Name}}</option>
  <option data-replace-into-mktoform-field="Email">{{lead.Email Address}}</option>
  <!-- ... add additional tokens following same pattern... -->
</datalist>

 

 

Then include the JS in the JS pane from here: MktoForms2 :: {{lead.token}} replacement via separate datalist v1.1.0

 

 

Highlighted
Level 5

Re: PURL not prefilling and what if Code is wrong

@SanfordWhiteman ,

cool.. I think this is the missing link that is catching out so many people.  I shall try that very shortly.

 

Any thoughts on the fall back issue?  (i.e. someone types in mydomain/mylp/123xyy, which doesn't exist as a code).  How can I throw a different LP to say 'try again hammer fingers' (or something a little nicer than that 🙂 🙂 ).

 

Cheers

Jo

 

 

Highlighted
Level 10 - Community Moderator

Re: PURL not prefilling and what if Code is wrong


If someone enters a URL with an invalid PURL Unique Code, is there a way to display an entirely different landing page (or at least to hide the form and replace it with different text)?


You can detect if a token on the page that should be filled in (say, Postal Code, since you're doing direct mail) is empty.

 

if( "{{lead.Postal Code}}" == "" ) {
  // do something
}

View solution in original post

Highlighted
Level 5

Re: PURL not prefilling and what if Code is wrong

@SanfordWhiteman , I've got it working like a charm - with one caveat, namely our old chum the Marketo Tracking cookie (and even that has a caveat).

I extended your original code with two things:

  1. The Marketo approved method for deleting the tracking cookie - that is working a charm
  2. Code to detect if the last name field is empty (this is a mandatory field in the DB, so safe to use)

My Code has ended up looking like this:

 

 

 

<datalist class="exported-tokens">
  <option data-replace-into-mktoform-field="LastName">{{lead.Last Name}}</option>
  <option data-replace-into-mktoform-field="FirstName">{{lead.First Name}}</option>
  <option data-replace-into-mktoform-field="Email">{{lead.Email Address}}</option>
</datalist>

<script>
function delete_cookie (name, path, domain) {
    document.cookie = name + "=" +
      ((path) ? ";path="+path:"")+
      ((domain)?";domain="+domain:"") +
      ";expires=Thu, 01 Jan 1970 00:00:01 GMT";
    }
 
function delete_marketo_cookie () {
    delete_cookie ( '_mkto_trk', '/', '.you.dont.need.to.know');
    }


document.addEventListener("DOMContentLoaded", function() {
  var arrayify = getSelection.call.bind([].slice);
  
  function replaceWithExports(parentContainer) {
    var exportedTokens = arrayify(document.querySelectorAll(".exported-tokens option")),
        replaceablesByTarget = arrayify(parentContainer.querySelectorAll(".replace-with-exported-token:not(.replace-done)")),
        replaceablesBySource = exportedTokens.filter(function(token){ return token.hasAttribute("data-replace-into-selector") || token.hasAttribute("data-replace-into-mktoform-field"); }),
        replaceables = replaceablesByTarget.concat(replaceablesBySource);
    
        replaceables
          .forEach(function(replaceable) {
            var contentSource,
                contentTarget,
                contentTargetType,
                contentProperty;
                      
            if( replaceable.hasAttribute("data-replace-into-mktoform-field") ) {
              contentSource = replaceable;
              contentTarget = {};
              contentTargetType = window.MktoForms2;
            } else if( replaceable.hasAttribute("data-replace-into-selector") ) {
              contentSource = replaceable;
              contentTarget = parentContainer.querySelector(replaceable.getAttribute("data-replace-into-selector"));
              contentTargetType = HTMLElement;
            } else {
              contentSource = exportedTokens.filter(function(token){ return token.label == replaceable.getAttribute("data-exported-token"); })[0];
              contentTarget = replaceable;
              contentTargetType = HTMLElement;
            }
          
            if ( !(contentSource && contentTarget && contentTargetType) ) return;

            if( contentTargetType == window.MktoForms2 ) {
               contentProperty = contentSource.getAttribute("data-replace-into-mktoform-field");
            } else if( contentSource.hasAttribute("data-target-related-property") || contentTarget.hasAttribute("data-target-related-property") ) {
               contentProperty = contentSource.getAttribute("data-target-related-property") || contentTarget.getAttribute("data-target-related-property");
            } else if( contentSource.hasAttribute("data-allow-html") || contentTarget.hasAttribute("data-allow-html") ) {
               contentProperty = "innerHTML";
            } else {
               contentProperty = "textContent";              
            }
                    
            contentTarget[contentProperty] = contentSource.value;
            
            if( contentTargetType == window.MktoForms2 ) {
              MktoForms2.whenReady(function(form){
                form.setValuesCoerced(contentTarget);
              });
            } else if ( contentTargetType == HTMLElement ) {
              contentTarget.classList.add("replace-done");
            }
          });
  }

  delete_marketo_cookie ();
  replaceWithExports(document);
  // This fires an alert if the code is invalid.  Replace with a redirect to error LP when done.
  if( "{{lead.Last Name}}" == "" ) {
    //window.location.href = "https://you.dont.need.to.know/a_landing_page.html";
    window.alert("dead soldier");
  }
 
});
</script>

 

 

If you hunt for this comment: 

 

 

// This fires an alert if the code is invalid. Replace with a redirect to error LP when done.

 

 

you'll find where I'm testing for the last name.

The first time this runs, it always comes up with the alert.  Hit refresh, and the data gets loaded (the caveat on the caveat 🙂 ).

Of course, if I remove the cookie deleting stuff and run it in an incognito window, all works perfectly.

As usual, I know I'm missing something obvious, I just don't know what 🙂

Your help (as always) is immensely appreciated.

 

Level 10 - Community Moderator

Re: PURL not prefilling and what if Code is wrong

I assume you're trying to clear the cookie to help the pURL work — which is a good idea given bugs in the past — but you're not forcibly refreshing immediately after clearing it, so it's not the same as my original pURL-fixing code.

 

When you go to the page in a new Incognito mode session, there's no cookie being sent to Marketo on the initial request.  That's what you want to simulate.

Highlighted
Level 5

Re: PURL not prefilling and what if Code is wrong

By 'original pURL-fixing code', do you mean the stuff you provided earlier in this thread that I'm leveraging, or some other piece of black magic that you've constructed 🙂

 


@SanfordWhiteman wrote:

When you go to the page in a new Incognito mode session, there's no cookie being sent to Marketo on the initial request.  That's what you want to simulate.


Yes - so very very much!!!!

Highlighted
Level 5

Re: PURL not prefilling and what if Code is wrong

@SanfordWhiteman ,

It WORKS!!!!

 

I've now got this code in the LP template I am using: 

 

    <script id="teknklFormsPlus-base-1.0.3" src="//cdpn-js.figureone.com/teknkl-formsplus-1.0.3.min.js"> </script>
    <script id="teknklFormsPlus-purl-1.0.0" src="//cdpn-js.figureone.com/teknkl-formsplus-purl-1.0.0.min.js"> </script>
    <script> FormsPlus.pURL.fixSession(); </script>

 

As per this blog post of yours, this code is sitting right under the <title> tags in the <head> section.

 

I've removed my cookie deletion stuff from the page code, so I now have this:

 

<datalist class="exported-tokens">
  <option data-replace-into-mktoform-field="LastName">{{lead.Last Name}}</option>
  <option data-replace-into-mktoform-field="FirstName">{{lead.First Name}}</option>
  <option data-replace-into-mktoform-field="Email">{{lead.Email Address}}</option>
</datalist>

<script>
document.addEventListener("DOMContentLoaded", function() {
  var arrayify = getSelection.call.bind([].slice);
  
  function replaceWithExports(parentContainer) {
    var exportedTokens = arrayify(document.querySelectorAll(".exported-tokens option")),
        replaceablesByTarget = arrayify(parentContainer.querySelectorAll(".replace-with-exported-token:not(.replace-done)")),
        replaceablesBySource = exportedTokens.filter(function(token){ return token.hasAttribute("data-replace-into-selector") || token.hasAttribute("data-replace-into-mktoform-field"); }),
        replaceables = replaceablesByTarget.concat(replaceablesBySource);
    
        replaceables
          .forEach(function(replaceable) {
            var contentSource,
                contentTarget,
                contentTargetType,
                contentProperty;
                      
            if( replaceable.hasAttribute("data-replace-into-mktoform-field") ) {
              contentSource = replaceable;
              contentTarget = {};
              contentTargetType = window.MktoForms2;
            } else if( replaceable.hasAttribute("data-replace-into-selector") ) {
              contentSource = replaceable;
              contentTarget = parentContainer.querySelector(replaceable.getAttribute("data-replace-into-selector"));
              contentTargetType = HTMLElement;
            } else {
              contentSource = exportedTokens.filter(function(token){ return token.label == replaceable.getAttribute("data-exported-token"); })[0];
              contentTarget = replaceable;
              contentTargetType = HTMLElement;
            }
          
            if ( !(contentSource && contentTarget && contentTargetType) ) return;

            if( contentTargetType == window.MktoForms2 ) {
               contentProperty = contentSource.getAttribute("data-replace-into-mktoform-field");
            } else if( contentSource.hasAttribute("data-target-related-property") || contentTarget.hasAttribute("data-target-related-property") ) {
               contentProperty = contentSource.getAttribute("data-target-related-property") || contentTarget.getAttribute("data-target-related-property");
            } else if( contentSource.hasAttribute("data-allow-html") || contentTarget.hasAttribute("data-allow-html") ) {
               contentProperty = "innerHTML";
            } else {
               contentProperty = "textContent";              
            }
                    
            contentTarget[contentProperty] = contentSource.value;
            
            if( contentTargetType == window.MktoForms2 ) {
              MktoForms2.whenReady(function(form){
                form.setValuesCoerced(contentTarget);
              });
            } else if ( contentTargetType == HTMLElement ) {
              contentTarget.classList.add("replace-done");
            }
          }

);
  }

  replaceWithExports(document);

  // This fires an alert if the code is invalid.  Replace with a redirect to error LP when done.
  if( "{{lead.Last Name}}" == "" ) {
                  //window.location.href = "https://put.your.domain.here/your.incorrect.code.page.here.html";
                  window.alert("dead soldier");
                }
 
});
</script>

 

Which gives me pURL prefill working very nicely AND diversion to a different landing page if there is an issue with the supplied Unique Code (e.g. the person has typed it incorrectly).

 

This solution now works!!!  Thanks for your help, and hopefully this will now be a nice worked example for others to follow (pulling together three topics; Clearing cookies, pURL pre-filling, and pURL fall back pages into one place).

 

Cheers

Jo

 

 

View solution in original post