This post is an experiment: can a cool technical hack be communicated without extra prose... that is, can I shut up for once? If it doesn’t make sense, ask in the comments! 😉
In Form Editor, just add the field with type Select — options don’t need to be listed there. <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta class="mktoString" mktoName="Job Title Option" id="Title-0" default="Select...|">
<meta class="mktoString" mktoName="Job Title Option" id="Title-1" default="Choice 1">
<meta class="mktoString" mktoName="Job Title Option" id="Title-2" default="Choice 2">
<meta class="mktoString" mktoName="Job Title Option" id="Title-3" default="Choice 3">
<meta class="mktoString" mktoName="Job Title Option" id="Title-4" default="">
<meta class="mktoString" mktoName="Job Title Option" id="Title-5" default="">
<title>Test Page</title>
</head>
<body>
<div class="mktoForm" id="exampleForm" mktoName="Example Form">
</div>
<datalist id="mktoFormSelectOptions">
<option label="Title">${Title-0}</option>
<option label="Title">${Title-1}</option>
<option label="Title">${Title-2}</option>
<option label="Title">${Title-3}</option>
<option label="Title">${Title-4}</option>
<option label="Title">${Title-5}</option>
</datalist>
</body>
</html>
An example Marketo LP template. Note the use of a <datalist>
element, which is the perfect choice for storing offline options, while — importantly — correctly encoding values. mktoString
values at the page level become your options. Empty values are skipped. <friendly name>|<server value>
syntax (like in Form Editor) is supported./**
* Dynamic <select> options eleement from <datalist>
* @author Sanford Whiteman
* @version v1.0 2022-08-21
* @copyright © 2022 Sanford Whiteman
* @license Hippocratic 3.0: This license must appear with all reproductions of this software.
*
* Prereq: <datalist> structured like:
* <datalist id="mktoFormSelectOptions">
* <option label="fieldName">Select Fruit...|</option>
* <option label="fieldName">Apple|apple</option>
* <option label="fieldName">Orange|orange</option>
* <option label="fieldName">Pear|pear</option>
* <option label="anotherFieldName">Select Sport...|</option>
* <option label="anotherFieldName">Basketball|bball</option>
* etc.
*/
MktoForms2.whenRendered(function(mktoForm){
const arrayify = getSelection.call.bind([].slice);
let formEl = mktoForm.getFormElem()[0];
let allDynamicSelectOptions = document.querySelector("#mktoFormSelectOptions");
let optionsByField = arrayify(allDynamicSelectOptions.options)
.reduce(function(acc,option){
if( !(option.label in acc )){
acc[option.label] = [];
}
if( option.textContent ) {
acc[option.label].push(option.textContent);
}
return acc;
}, {});
Object.keys(optionsByField)
.forEach(function(fieldName){
let mktoVariableOptions = optionsByField[fieldName];
let selectEl = formEl.querySelector("select[name='" + fieldName + "']");
if(selectEl.getAttribute("data-options-managed") != "true" && mktoVariableOptions.length > 0){
selectEl.setAttribute("data-options-managed","true");
arrayify(selectEl.options)
.forEach(function(originalOption){
selectEl.removeChild(originalOption);
});
mktoVariableOptions
.map(function(mktoVariableOption){
let newOption = document.createElement("option");
let optionDescriptor = mktoVariableOption.split("|");
newOption.textContent = optionDescriptor[0];
newOption.value = optionDescriptor[optionDescriptor.length == 1 ? 0 : 1];
return newOption;
})
.forEach(function(newOption){
selectEl.appendChild(newOption);
});
}
})
});
The Forms 2.0 JS to add to your template (recommend a separate <script>
tag). Note you don’t configure any fields in the JS, they’re picked up automatically from the <datalist>
. Voilà! Different form variations per LP.