Hello everyone,
We have a web page with a third party form.
Is there a best way to capture information from a regular HTML5 form?
I know this is a pretty general/nebulous question so I appreciate any attempts to help.
Thanks ahead of time.
You could pass the form fill information with a webook or API.
We were trying to do something like this, but abandoned it and decided to use marketo forms.
Sanford Whiteman could probably give you some direction.
Yep, easy as pie with a vanilla HTML form (i.e. a static form that doesn't come from another forms library -- dynamic forms generated by other libs are much trickier).
Simply catch the HTML submit event, pass the fields to a hidden Marketo form (which is already waiting), and call the Marketo form's submit.
If you have control over the form fields on the HTML side then you don't even have to worry about field name mapping (which is easy, but easier still is to skip it). Just set them to exactly the same as the Marketo field names.
A new quick-and-dirty example is here: MktoForms2 :: HTML form to Mkto form
The above sets the Marketo form to opacity:.2 so you can better see what's going on; in production you set it to display:none and it's totally behind the scenes. Also, the demo code is deliberately "lite" : it takes into account text, checkbox, and radio fields. Other types would have to be added. There are lots of other variations I've posted over the years (including ones to sync <select> fields) if you search the Nation.
Definitely neither webhook nor REST should be used (DoS vulnerability).
Hi Sanford Whiteman,
I am trying to use the sample code that you provided above to capture information from a non-Marketo form and I'm having some issues. Simply collecting the information works but I am trying to make the form "progressive" as I am only displaying one question at a time and using the "onclick" function to hide/display questions. The issue is that every time the first question is answered it triggers the form submit action. Below is the code that I'm currently using - I'm hoping you could help me out with this. Thanks ahead of time.
<script>
var notes, phone, company, Email;
function _(x){
return document.getElementById(x);
}
function processPhase1(){
notes = _("html_MktoCompanyNotes").value;
if(notes.length > 0){
_("phase1").style.display = "none";
_("phase2").style.display = "block";
} else {
alert("Please answer all questions");
}
}
function processPhase2(){
Email = _("html_Email").value;
if(Email.length > 5){
_("phase2").style.display = "none";
_("phase3").style.display = "block";
} else {
alert("Please answer all questions");
}
}
</script>
<form id="htmlForm">
<div id="phase1">
I hire roughly ___________ people annually.
<br />
<br>
<div align="left" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="0-49 employees">0-49</button></div><div align="center" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="50-99 employees">50-99</button></div><div align="right" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="100+ employees">100+</button></div>
</div>
<div id="phase2">
<input name="Email" id="html_Email" maxlength="255" type="email" placeholder="Email">
<button type="submit" class="eld">Submit</button>
</div>
</form>
<form id="mktoForm_1245" class="mktoForm"></form>
<script src="//app-sj01.marketo.com/js/forms2/js/forms2.min.js"></script>
<script>var config = {
mktoForm: {
instanceURL: "//app-ab10.marketo.com",
munchkinId: "xxx-xxx-xxx",
formId: xxx
},
htmlForm: {
cssSelector: "#htmlForm"
}
};
/* ---- NO NEED TO EDIT BELOW THIS LINE! ---- */
(function(config) {
MktoForms2.loadForm(
config.mktoForm.instanceURL,
config.mktoForm.munchkinId,
config.mktoForm.formId
);
MktoForms2.whenReady(function(mktoForm) {
/* naive Array.from ponyfill */
var _from = Function.prototype.call.bind(Array.prototype.slice);
document
.querySelector(config.htmlForm.cssSelector)
.addEventListener("submit", function(htmlSubmitEvent) {
var htmlFormEl = this,
fields = {
textLike: htmlFormEl.querySelectorAll(
'input:not([type="radio"]):not([type="checkbox"]),textarea'
),
checkable: htmlFormEl.querySelectorAll(
'input[type="radio"],input[type="checkbox"]'
)
},
mktoObj = {};
// text-like fields: just copy value
_from(fields.textLike).forEach(function(fieldEl) {
mktoObj[fieldEl.name] = fieldEl.value;
});
// checkbox, checkboxes, and radios
// if single input w/current name, treat as Marketo checkbox type (yes/no)
// if multiple inputs, create value array and only append if currently checked
_from(fields.checkable).forEach(function(fieldEl) {
var hasSiblingFields =
_from(fields.checkable).some(function(siblingEl) {
return (siblingEl != fieldEl) && (siblingEl.name == fieldEl.name);
});
if (!hasSiblingFields) {
mktoObj[fieldEl.name] = fieldEl.checked ? "yes" : "no";
} else if (fieldEl.checked) {
mktoObj[fieldEl.name] = mktoObj[fieldEl.name] || [];
mktoObj[fieldEl.name].push(fieldEl.value);
} else {
mktoObj[fieldEl.name] = mktoObj[fieldEl.name] || null;
}
});
// join any arrays with semicolons
Object.keys(mktoObj).forEach(function(fieldName) {
if (Array.isArray(mktoObj[fieldName])) {
mktoObj[fieldName] = mktoObj[fieldName].join(";");
}
});
// stop native HTML submit, switch to Marketo submit
htmlSubmitEvent.preventDefault();
mktoForm.addHiddenFields(mktoObj);
mktoForm.submit();
});
});
})(config);</script>
Can you link to your page please?
And also, when posting code, you have to use the syntax highlighter or it's nigh unreadable...
Sorry about that - haven't posted on here before and don't have a ton of experience with coding.
Here is the link to the page: Code Test
I've also posted the code again in the syntax highlighter just in case.
<script>
var notes, phone, company, Email;
function _(x){
return document.getElementById(x);
}
function processPhase1(){
notes = _("html_MktoCompanyNotes").value;
if(notes.length > 0){
_("phase1").style.display = "none";
_("phase2").style.display = "block";
} else {
alert("Please answer all questions");
}
}
function processPhase2(){
Email = _("html_Email").value;
if(Email.length > 5){
_("phase2").style.display = "none";
_("phase3").style.display = "block";
} else {
alert("Please answer all questions");
}
}
</script>
<form id="htmlForm">
<div id="phase1">
I hire roughly ___________ people annually.
<br />
<br>
<div align="left" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="0-49 employees">0-49</button></div><div align="center" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="50-99 employees">50-99</button></div><div align="right" style="margin:15px;"><button onclick="processPhase1()" class="eld" id="html_MktoCompanyNotes" value="100+ employees">100+</button></div>
</div>
<div id="phase2">
<input name="Email" id="html_Email" maxlength="255" type="email" placeholder="Email">
<button type="submit" class="eld">Submit</button>
</div>
</form>
<form id="mktoForm_1245" class="mktoForm"></form>
<script src="//app-sj01.marketo.com/js/forms2/js/forms2.min.js"></script>
<script>var config = {
mktoForm: {
instanceURL: "//app-ab10.marketo.com",
munchkinId: "024-MWD-629",
formId: 1245
},
htmlForm: {
cssSelector: "#htmlForm"
}
};
/* ---- NO NEED TO EDIT BELOW THIS LINE! ---- */
(function(config) {
MktoForms2.loadForm(
config.mktoForm.instanceURL,
config.mktoForm.munchkinId,
config.mktoForm.formId
);
MktoForms2.whenReady(function(mktoForm) {
/* naive Array.from ponyfill */
var _from = Function.prototype.call.bind(Array.prototype.slice);
document
.querySelector(config.htmlForm.cssSelector)
.addEventListener("submit", function(htmlSubmitEvent) {
var htmlFormEl = this,
fields = {
textLike: htmlFormEl.querySelectorAll(
'input:not([type="radio"]):not([type="checkbox"]),textarea'
),
checkable: htmlFormEl.querySelectorAll(
'input[type="radio"],input[type="checkbox"]'
)
},
mktoObj = {};
// text-like fields: just copy value
_from(fields.textLike).forEach(function(fieldEl) {
mktoObj[fieldEl.name] = fieldEl.value;
});
// checkbox, checkboxes, and radios
// if single input w/current name, treat as Marketo checkbox type (yes/no)
// if multiple inputs, create value array and only append if currently checked
_from(fields.checkable).forEach(function(fieldEl) {
var hasSiblingFields =
_from(fields.checkable).some(function(siblingEl) {
return (siblingEl != fieldEl) && (siblingEl.name == fieldEl.name);
});
if (!hasSiblingFields) {
mktoObj[fieldEl.name] = fieldEl.checked ? "yes" : "no";
} else if (fieldEl.checked) {
mktoObj[fieldEl.name] = mktoObj[fieldEl.name] || [];
mktoObj[fieldEl.name].push(fieldEl.value);
} else {
mktoObj[fieldEl.name] = mktoObj[fieldEl.name] || null;
}
});
// join any arrays with semicolons
Object.keys(mktoObj).forEach(function(fieldName) {
if (Array.isArray(mktoObj[fieldName])) {
mktoObj[fieldName] = mktoObj[fieldName].join(";");
}
});
// stop native HTML submit, switch to Marketo submit
htmlSubmitEvent.preventDefault();
mktoForm.addHiddenFields(mktoObj);
mktoForm.submit();
});
});
})(config);</script>
Right now, the code has a syntax error which stops it from running at all, so the raw HTML form submits. It looks like the bulk of the code above has been chopped out and isn't even in the page. You'll have to fix this before we look further.
Both of those errors should be fixed now. Thanks, James
A <button> element within a form is considered a submit button unless it has a specific other type set. (This is a standard HTML rule from way back.)
So this is a submit button, regardless of what else you do in processPhase1().
<button onclick="processPhase1()" class="eld" id="MktoCompanyNotes" value="0-49 employees" type="button">0-49</button>
This is not a submitter and will only do processPhase1().
<button type="button" onclick="processPhase1()" class="eld" id="MktoCompanyNotes" value="0-49 employees" type="button">0-49</button>
Thanks Sanford! That fixed my issue. Do you know of any way for the form to be submitted and instead of it reloading the page it simply changes what is displayed i.e. "phase 3"?
Also, do you know if there is any way to simply post a form submission similar to the way Eloqua does if you have any experience with that platform?