
Author Name
Emtiaz Hossain
Ninja Forms is the easiest of the major form plugins to track accurately, because it fires its own custom jQuery event with the full structured field response already attached, no polling for a success message, no manual FormData wrangling required.
<script>
(function() {
function convertNinjaFieldsToInputs(fields) {
var inputs = {};
for (var key in fields) {
if (fields.hasOwnProperty(key)) {
var label = fields[key].label;
var slug = label.toLowerCase().replace(/ /g, "_");
var value = fields[key].value;
if(slug === 'phone') {
value = value.replace(/[\(\)\s-]/g, '');
}
inputs[slug] = value;
}
}
return inputs;
}
jQuery(document).on('nfFormSubmitResponse', function(event, responseData, id) {
dataLayer.push({
event: 'ninja_form_submit',
form_id: responseData.id,
inputs: convertNinjaFieldsToInputs(responseData.response.data.fields),
});
});
})()
</script>nfFormSubmitResponse only fires after Ninja Forms has already validated and processed the submission. Unlike CF7 or non-AJAX WPForms, there's no need to build separate success-detection or validation logic, Ninja Forms' own event only fires on an actual successful submission, so anything listening to it is inherently already filtered to real conversions.
Field labels become the dataLayer keys automatically. convertNinjaFieldsToInputs walks the response's fields object and converts each field's human-readable label (like "First Name" or "Phone Number") into a slug (first_name, phone_number) used as the object key. This means adding or removing fields in the Ninja Forms builder doesn't require touching the tracking script, the conversion function picks up whatever fields are actually present in the response.
Phone numbers get light normalization inline. The one piece of field-specific logic here strips parentheses, spaces, and dashes from any field slugged phone, useful since raw phone-number formatting varies by how the visitor typed it and most CRMs or CAPI implementations want a cleaner string.
Because the key-to-slug conversion is driven by the field's visible label text, renaming a field's label in the Ninja Forms builder changes its dataLayer key too. If a downstream GTM variable references inputs.email, and someone later renames the field's label from "Email" to "Email Address," the key becomes email_address and the variable silently stops matching. Worth a note in the client-facing documentation if anyone besides the tracking implementer has edit access to the form.
ninja_form_submit, mapping fields off inputs.* (e.g. inputs.email, inputs.phone) as needed.inputs object contains every expected field with the correct slugged key.nfFormSubmitResponse jQuery event already guarantees a successful, validated submission, no extra success-detection logic neededDiscussed this on LinkedIn
Found this helpful?
Drop a comment on the LinkedIn post – I read every reply and love connecting with tracking folks.
Book a free 30-minute call. I will review your current tracking setup, show you where conversions are leaking, and tell you exactly what I would fix.
WPForms has two submission modes, AJAX and non-AJAX, that need completely different GTM tracking patterns. Here's the real code for both, plus the validation logic non-AJAX forms need.
How to track Contact Form 7 submissions accurately in GTM by confirming CF7's own success message instead of trusting a click event that fires even on failed validation.
A universal dataLayer pattern for tracking any form (name, email, phone, date, country, message) in GTM, the foundation every plugin-specific guide in this series builds on.