How to Make HTML5 Placeholders in Marketo Forms

Edit: Forms 2.0 came out! And this is now native functionality. The new attribute to change Placeholder in the form 2.0 editor is “Hint.” See it in action on our updated responsive landing page templates

Recently we had a question in the Marketo community about how to make placeholder text for Marketo forms. This has been a current development challenge for one of our clients, whose design required moving the labels into the form fields as placeholders. While this is quite simple when coding from scratch, it is more difficult with using Marketo forms, since there is very little control over the code of Marketo forms. At the moment, Javascript is the only way to create placeholders in Marketo input fields.

Marketo Infield Label Instructions Example

Oooohhh, pretty placeholders…

Why is this Marketo infield label solution the best?

  • It’s scalable. There are mostly two lines of code that can be placed in every single template, and then there is (nearly) no maintenance work required. Add a new form field? Same code. Change forms? Same code. Change a field’s title? Same code.
  • It uses native Marketo functionality (the “Instructions” field) to create the placeholder text. That means it’s rather intuitive, and non-coders will be able to edit the placeholder text down the line.
  • It maintains Marketo auto-fill values. Because HTML5 placeholders are separate than setting field values, you don’t have to worry about overwriting any of that convenient information. Returning visitors still have their information filled instead of having to re-type anything.
  • It guards against false lead submittals. Getting the placeholder information as the lead data is a danger with some HTML5 placeholder solutions in Marketo. Some more basic Javascript could change the actual value of a field to “First Name,” and a user who just hits the “Submit” button will create a new lead with improper values. HTML5 placeholders don’t have this problem!
  • It doesn’t reinvent the wheel. Placeholder Javascript has been written a million times, and I trust other people to have created better solutions than I could do from scratch. This way utilizes Marketo native functionality and then adds two lines of code to make it utilize other developers’ hard work.

How it’s done, technical side:

This draws from the “title” property of the input field, then copies it through jQuery into a new “placeholder” property of the same input field. This looping process continues through all input fields on the page. After the HTML5 “placeholder” property is established, we include a Javascript polyfill so that this placeholder property has backwards-compatible support from older browsers.

The magic secret of how to make these Marketo in-field labels is that the “title” attribute on a an input is actually the field’s “Instructions” in the form editor. You can change the “instructions” to what you want the placeholder text to be. For our forms, these are pretty obvious: First Name*, Last Name*, Company, etc.

Using Marketo Instructions Field as Placeholder Text

After you have all of these “Instructions” filled with your desired placeholder text, it’s time to place the code onto your pages with forms! There will be two snippets: the first adds the “placeholder” attribute to your fields, and the second makes “placeholder” work in all browsers (since it’s relatively new code, older browsers don’t have native support).

Copy and paste this into your landing page or template (right before the </head> tag for templates, or in the “Custom HEAD HTML” for individual landing pages) :

<script>
// use no conflict mode for jQuery
var $ = jQuery.noConflict();
$(document).ready(function() {
// loop through inputs and add placeholders from input titles
$(‘input’).each(function() {
$(this).attr(“placeholder”, ($(this).prop(‘title’)) );
});
});
</script>

The next snippet is where you can insert your desired placeholder polyfill. There are many placeholder polyfills that already exist, each with its own pros and cons. I chose to use this one (because it uses <span> instead of changing the actual value). If you want to use this version, copy and paste this code into your landing page or template:

<script>
/*! jquery.placeholder.js | https://github.com/diy/jquery-placeholder | Apache License (v2) */
(function(f){var j=”placeholder”in document.createElement(“input”),h=”-moz-box-sizing -webkit-box-sizing box-sizing padding-top padding-right padding-bottom padding-left margin-top margin-right margin-bottom margin-left border-top-width border-right-width border-bottom-width border-left-width line-height font-size font-family width height top left right bottom”.split(” “);f.fn.placeholder=function(g){var k=this;g=g||{};if(j&&!g.force)return this;window.setTimeout(function(){k.each(function(){var e=
this.tagName.toLowerCase();if(“input”===e||”textarea”===e)a:{var b,d,a=f(this),c;try{b=a[0].getAttributeNode(“placeholder”);if(!b)break a;d=a[0].getAttribute(“placeholder”);if(!d||!d.length)break a;a[0].setAttribute(“placeholder”,””);a.data(“placeholder”,d)}catch(g){break a}e={};for(b=0;b<h.length;b++)e[h[b]]=a.css(h[b]);b=parseInt(a.css(“z-index”),10);if(isNaN(b)||!b)b=1;c=f(“<span>”).addClass(“placeholder”).html(d);c.css(e);c.css({cursor:a.css(“cursor”)||”text”,display:”block”,position:”absolute”,
overflow:”hidden”,”z-index”:b+1,background:”none”,”border-top-style”:”solid”,”border-right-style”:”solid”,”border-bottom-style”:”solid”,”border-left-style”:”solid”,”border-top-color”:”transparent”,”border-right-color”:”transparent”,”border-bottom-color”:”transparent”,”border-left-color”:”transparent”});c.insertBefore(a);e=a.offset().top-c.offset().top;d=parseInt(c.css(“margin-top”));isNaN(d)&&(d=0);c.css(“margin-top”,d+e);c.on(“mousedown”,function(){a.is(“:enabled”)&&window.setTimeout(function(){a.trigger(“focus”)},
0)});a.on(“focus.placeholder”,function(){c.hide()});a.on(“blur.placeholder”,function(){c.toggle(!f.trim(a.val()).length)});a[0].onpropertychange=function(){“value”===event.propertyName&&a.trigger(“focus.placeholder”)};a.trigger(“blur.placeholder”)}})},0);return this}})(jQuery);
</script>

Save your pages and templates, approve them, and wha-la! Working placeholders for your fields. As you can see in the example image I included at the top, some of our designs hide the label altogether. Feel free to do this with a few lines of CSS if you’d like.

Well now you know how to make HTML5 placeholders in Marketo… how about putting those into our free responsive Marketo landing page template?

Pin It
  • CJ

    Hi. I had to make some slight alterations to get this to work for me… thought I’d share in case anyone else is having similar issues …

    var $jQ = jQuery.noConflict();

    $jQ(document).ready(function(){

    $jQ(‘input’).each(function () {

    var foo = $jQ(this).attr(‘title’);

    $jQ(this).attr(‘placeholder’, foo);

    });

    });

    /*! jquery.placeholder.js | https://github.com/diy/jquery-placeholder | Apache License (v2) */

    (function(f){var j=”placeholder”in document.createElement(“input”),h=”-moz-box-sizing -webkit-box-sizing box-sizing padding-top padding-right padding-bottom padding-left margin-top margin-right margin-bottom margin-left border-top-width border-right-width border-bottom-width border-left-width line-height font-size font-family width height top left right bottom”.split(” “);f.fn.placeholder=function(g){var k=this;g=g||{};if(j&&!g.force)return this;window.setTimeout(function(){k.each(function(){var e=

    this.tagName.toLowerCase();if(“input”===e||”textarea”===e)a:{var b,d,a=f(this),c;try{b=a[0].getAttributeNode(“placeholder”);if(!b)break a;d=a[0].getAttribute(“placeholder”);if(!d||!d.length)break a;a[0].setAttribute(“placeholder”,””);a.data(“placeholder”,d)}catch(g){break a}e={};for(b=0;b<h.length;b++)e[h[b]]=a.css(h[b]);b=parseInt(a.css(“z-index”),10);if(isNaN(b)||!b)b=1;c=f(“”).addClass(“placeholder”).html(d);c.css(e);c.css({cursor:a.css(“cursor”)||”text”,display:”block”,position:”absolute”,

    overflow:”hidden”,”z-index”:b+1,background:”none”,”border-top-style”:”solid”,”border-right-style”:”solid”,”border-bottom-style”:”solid”,”border-left-style”:”solid”,”border-top-color”:”transparent”,”border-right-color”:”transparent”,”border-bottom-color”:”transparent”,”border-left-color”:”transparent”});c.insertBefore(a);e=a.offset().top-c.offset().top;d=parseInt(c.css(“margin-top”));isNaN(d)&&(d=0);c.css(“margin-top”,d+e);c.on(“mousedown”,function(){a.is(“:enabled”)&&window.setTimeout(function(){a.trigger(“focus”)},

    0)});a.on(“focus.placeholder”,function(){c.hide()});a.on(“blur.placeholder”,function(){c.toggle(!f.trim(a.val()).length)});a[0].onpropertychange=function(){“value”===event.propertyName&&a.trigger(“focus.placeholder”)};a.trigger(“blur.placeholder”)}})},0);return this}})(jQuery);

    • James Boye-Doe

      Does this code work for IE 9 and earlier? I tried this code on my landing pages and did a test in Litmus. Older browsers showed me empty fields. I’d really like to use this on forms but we have a lot of IE traffic that I need to account for.

      • Edward Unthank

        Hi James, the code above (CJ’s—thanks, CJ!) is only half of the equation. The other half is a bit of Javascript to make it backward-compatible. The “placeholder” tag is pretty new, so old browsers don’t natively support it. The additional script you need is called a “placeholder polyfill” I included one as an example in the article, but you can Google it and choose any script you like.

  • James Boye-Doe

    How do you make the labels disappear selectively? Let’s say in addition to the fields in the example above, you had a check box and you’d like the label for that field to be the only one that shows?

    • Edward Unthank

      Hi James:

      This method above doesn’t actually delete/hide any labels—if the labels exist, they’ll still be shown. The labels are hidden through CSS. On our forms (e.g., http://resources.yesler.com/how-to-create-and-use-buyer-personas.html), we have right-aligned labels.

      This is the CSS that hides/shows the labels appropriately for right-aligned labels:
      #form form.lpeRegForm label {display: none;}
      #form form.lpeRegForm ul li.mktLblRight label {float: none;display: block;}

      The key is that Marketo changes some of the HTML structure from normal fields to checkbox fields, so you can manipulate the display with some CSS that is a little bit more specific for checkboxes, so it shows appropriately.

      Thanks for reading, James!

      – Edward

      • James Boye-Doe

        Worked like a charm! Much appreciated.

  • Shay

    This is a great solution! Thanks!

    I am having one issue with it. It does not seem to work on Textarea fields. Any suggestions on how I can fix that?

    Thanks

    • Shay

      Found the fix. Just added this to the jQuery:

      $(‘textarea’).each(function() {

      $(this).attr(“placeholder”, ($(this).prop(‘title’)) );

      });

  • John

    Great article! One quick question though, I’m using both the placeholder snippet in addition to the polyfill snippet above and it still doesn’t seem to work with IE8/IE9? Any idea why by chance? I have both javascript snippets inserted just before the …

  • peter kuhn

    This is really great, thanks Edward!

    I had to find a little workaround for Select fields, but this is perfect otherwise.

  • Guest

    If you are embedding the forms into a website, the jQuery needs to be called after the form is loaded on the page otherwise this won’t work! (hint: call the placeholder script after 6 or so seconds after page load using setInterval)