Javascript library for real-time marketing form in Customer Insights

There’s no getting around Javascript in the real-time marketing form in Customer Insights. And I’ve already written a few articles with examples, but I still have to search for the right scripts every time. That costs time and nerves. That’s why I’m putting together a library of scripts and use cases for marketing forms in the hope that it will make everyday life a little easier for all of us.

If you have any other ideas or use cases that we can add, please get in touch with me 🙂

I added all scripts to a repository, feel free to contribute: Github Link

Content

Difference between marketing form and preference center

The preference center and the real-time marketing form in Customer Insights trigger javascript differently. What works in Preference Centers does not necessarily work in marketing forms!

To make the Javascript work in the Preference Center, you can see two ways to initiate the function in the code below.

				
					<script style="display: none;">
document.addEventListener('DOMContentLoaded', function() { 
***add script here***});
</safe-script>

OR

<script data-minify="1" src="https://paulinekolde.info/wp-content/cache/min/1/jquery-1.9.1.min.js?ver=1728405885" data-rocket-defer defer></script>
<script>window.addEventListener('DOMContentLoaded', function() {
$( document ).ready(function() {
***add script here***
});
});</script>
				
			

For real-time marketing forms, we can use the Javascript as described in the Microsoft documentation: Documentation

Depending on when the Javascript should run, you can use different EventListeners:

  • d365mkt-beforeformload
  • d365mkt-afterformload
  • d365mkt-formrender
  • d365mkt-formsubmit
  • d365mkt-afterformsubmit
				
					<script style="display: none;">
document.addEventListener('d365mkt-afterformload', function () { ***add script here***});
</script>
				
			

Where does the Javascript belong?

From version 1.1.38813.80 or newer, you can insert the Javascript code into the <body> section of the HTML. If you insert the Javascript into the <head> section, it is automatically moved to the beginning of the <body> section.

The HTML form therefore has the following structure:

				
					<html>
<head>
    ***meta tags***
<style>
    ***css styles*** 
</style>
</head>
<body>
    <form>
        <script>
            ***add your script here***
        </script>
    </form>
</body>
</html>
				
			

Select All Checkboxes

I have already written a blog article about the Select all function. To have this library complete, I’ll also add this Javascript here.

First I build a Select All checkbox with HTML. This does not have to be a “real” field from the contact. When you check the Select All checkbox, the two purpose fields are checked as well.

				
					<div class="styled-checkbox">
    <div>
     <label class="lp-ellipsis container" id="label_selectall" style="font-weight: bold;display: inline-  block;padding-top: 0px;padding-right: 0px;padding-bottom: 0px; padding-left: 0px; font-size: 16px;">
Select all:
     <input name="selectall" id="selectall" value="1" type="checkbox" style="top: 5px; left: 0px; height: 20px; width: 20px; background-color: rgb(255, 255, 255); border-width: 0.5px; border-style: solid; border-color: rgb(186, 186, 188);">
     <span class="checkmark" id="span_selectall"></span>
     </label>
    </div>
</div>
				
			
				
					<script>
        document.addEventListener('d365mkt-afterformload', function () {
    const selectAllCheckbox = document.getElementById("selectall");
    const consentCheckboxes = document.querySelectorAll('[id^="consent"]');
var l = consentCheckboxes.length;
debugger;
selectAllCheckbox.addEventListener('change', selectAll);

function selectAll() {
    if (selectAllCheckbox.checked === true) {
    for (var i = 0; i < l; i++) {
     consentCheckboxes[i].checked = true;
    }
    } else {
    for (var i = 0; i < l; i++) {
      consentCheckboxes[i].checked = false;
    }}}

        });
    </script>
				
			

Show and hide a field

As one of my first articles, I also had an example of how to show and hide a field. By default, the field is hidden and only shown when a checkbox is checked.

In this Javascript I define the variable customer, which I can find via the technical name of my custom yes/no field. And when the field is checked, the script searches for the customer number field, also using the technical name.

				
					<script style="display: none;">
   document.addEventListener('d365mkt-afterformload', function () {
        let customer = document.querySelector('input[name="pk_existingcustomer"]');
        document.querySelector('input[name="pk_customernumber"]').style.display = 'none';
        customer.addEventListener('change', showCustomerNumber);

        function showCustomerNumber() {
        if (customer.checked === true) {
        document.querySelector('input[name="pk_customernumber"]').style.display = 'block';
        }
        else {
        document.querySelector('input[name="pk_customernumber"]').style.display = 'none';
        }
        }});
    </script>
				
			

Show and hide multiple fields (topics)

In this example, I only want to display the topics when the user selects the corresponding purpose. I have several purposes, each with several topics.

In this Javascript, I first define the variables for the purpose and topic checkboxes. This makes the function clearer afterwards. Whenever one of the purpose checkboxes is checked, a forEach loop runs, which shows or hides the topics of the respective purpose.

				
					<script style="display: none;">
document.addEventListener('d365mkt-afterformload', function () {
    const purpose1 = document.getElementById('consentCheckbox-1718980818012');
    const purpose2 = document.getElementById('consentCheckbox-1718980833715');
    const topicCheckboxes1 = document.querySelectorAll('.topicCheckbox1');
    const topicCheckboxes2 = document.querySelectorAll('.topicCheckbox2');

// Function to handle the display of topic checkboxes based on purpose1's state
    function handleTopicCheckboxes1() {
        topicCheckboxes1.forEach(function (checkbox) {
                checkbox.style.display = purpose1.checked ? 'block' : 'none';
            });
        }

// Function to handle the display of topic checkboxes based on purpose2's state
    function handleTopicCheckboxes2() {
        topicCheckboxes2.forEach(function (checkbox) {
                checkbox.style.display = purpose2.checked ? 'block' : 'none';
            });
        }

        // Attach event listeners
        purpose1.addEventListener('change', function(event) {
            handleTopicCheckboxes1();
        });

        purpose2.addEventListener('change', function(event) {
            handleTopicCheckboxes2();
        });

        // Initial hiding of all topic checkboxes
        handleTopicCheckboxes1();
        handleTopicCheckboxes2();
    });
</script>
				
			

Activate / deactivate button (gray out)

Instead of mandatory fields that prevent you from submitting a form, you can also gray out the submit button until the user fills in all required fields.

To do this, you must first give the button a suitable id and gray it out or deactivate it by default. The javascript then includes the conditions that reactivate the button.

				
					<script style="display: none;">
document.addEventListener('d365mkt-afterformload', function () {
    const purpose1 = document.getElementById('consentCheckbox-1718980818012');
    const submit = document.getElementById("submitButton");
    purpose1.addEventListener('change', enableButton);
    function enableButton() {
        if (purpose1.checked === true) {
        submit.disabled = false;
        submit.style.backgroundColor = 'green';
        }
        else {
        submit.disabled = true;
        submit.style.backgroundColor = 'red';
        }}});
</script>
				
			

Activate / deactivate fields (gray out)

The following Javascript defines how to gray out a field under certain conditions or make it writable again. In my example, only one of the purpose checkboxes may be ticked.

				
					<script style="display: none;">
document.addEventListener('d365mkt-afterformload', function() {
    const purpose1 = document.getElementById('consentCheckbox-1718980818012');
    const purpose2 = document.getElementById('consentCheckbox-1718980833715');
purpose1.addEventListener('change', handleCheckboxChange);
purpose2.addEventListener('change', handleCheckboxChange);

function handleCheckboxChange(event) {
     if (purpose1.checked) {
            purpose2.disabled = true;
    } else {
            purpose2.disabled = false;}
    if (purpose2.checked) {
            purpose1.disabled = true;
    } else {
            purpose1.disabled = false;}
    }
});</script>
				
			

Option set in Javascript

Option sets occur more frequently than lookups in the marketing form. This Javascript shows fields when the user selects a certain value in the option set.

P.S. Thanks to Jean-Paul and his colleague Rob for the impulse and the basic framework for the script 🙂

				
					<script style="display: none;">
document.addEventListener("d365mkt-afterformload", function() { 
    var feedbackRating = document.querySelector('[data-targetproperty="pk_feedbackrating"] select');
    var feedbackReason = document.querySelector('[data-targetproperty="pk_feedbackreason"]');
        feedbackReason.style.display = 'none';
//function to hide or show the reason field
    function toggleFeedbackReason(display) {
    feedbackReason.style.display = display ? 'block' : 'none';
}
//Show reason field only when feedback is satisfied
    feedbackRating.addEventListener('change', function() {
        toggleFeedbackReason(this.value === '125550000');
    })});
</script>
				
			

Fill in option set value in Javascript

Instead of reacting to the change of an option set and showing and hiding fields, it may also be necessary to fill in an option set automatically. In my example, I want to automatically change the priority of the contact based on their feedback. If the feedback is negative, the priority should be high, whereas positive feedback does not require a quick action.

				
					<script style="display: none;">
document.addEventListener("d365mkt-afterformload", function() {
// Get the feedback rating and priority select elements
    var feedbackRatingSelect = document.getElementById("pk_feedbackrating-1719156066672");
    var prioritySelect = document.getElementById("pk_priority-1719157920040");

// Function to update the priority based on the feedback rating
    function updatePriority() {
        var feedbackRating = feedbackRatingSelect.value;
        if (feedbackRating === "125550000") { // Satisfied
            prioritySelect.value = "0"; // Low
        } else if (feedbackRating === "125550001") { // Neutral
            prioritySelect.value = "1"; // Medium (Normal)
        } else if (feedbackRating === "125550002") { // Dissatisfied
            prioritySelect.value = "2"; // High
        } else {
            prioritySelect.value = ""; // Default
        }
    }

// Add event listener to feedback rating select element
    feedbackRatingSelect.addEventListener("change", updatePriority);
});
    </script>
				
			

Redirect after form submission

We currently only need this script for Preference Center. Fortunately, there is a field in the marketing form where you can simply enter the URL. Megan Walker has written a better and more detailed article on redirect. You can find it here.

The most important thing is the timeframe when someone is redirected. In my code it is 1000 milliseconds. However, I have noticed that Iphone or Safari, for example, need a longer waiting time for the form to be submitted correctly. So it’s best to test well!

				
					<script style="display: none;">
document.addEventListener("DOMContentLoaded", function() {
            var form = document.querySelector("form");
            form.addEventListener("submit", function() {
                // Replace the URL with your desired redirect URL
                setTimeout(function() {
                    window.location.href = "https://paulinekolde.info";
                }, 1000);
            });
    });
</script>
				
			

Validate field and display error message

This Javascript checks the input of a field. If it does not match, an error message is displayed.

There is of course also the custom validation for fields, which works in a similar way.

Please note: The JavaScript only indicates that there is an error. It does not prevent the user from actually submitting the form. For this, it is best to add the function that deactivates or reactivates the submit button.

				
					Add <div> somewhere to your HTML: 
 <div id="bonuscode-error" style="color: red; display: none;">Bonus Code must be exactly 5 digits long.</div>


<script style="display: none;">
document.getElementById('pk_bonuscode-1719160391752').addEventListener('input', function() {
    const bonusCodeInput = document.getElementById('pk_bonuscode-1719160391752');
    const errorDiv = document.getElementById('bonuscode-error');
    const bonusCodeValue = bonusCodeInput.value;

// Remove any non-numeric characters
    const numericBonusCodeValue = bonusCodeValue.replace(/\D/g, '');

// Update the input field value to only numeric characters
        bonusCodeInput.value = numericBonusCodeValue;

// Check if the input is exactly 5 digits long
    if (numericBonusCodeValue.length === 5) {
        errorDiv.style.display = 'none';
    } else {
        errorDiv.style.display = 'block';
    }
});
</script>
				
			

Dynamically change country code for phone number

The default functionalitiy for the country code simplifies the entry of the phone number. But: The country code value is static. However, each country has its own country code. And for international customers in particular, it must be possible for the values to change depending on the customer’s country.

This Javascript changes the country code – depending on the country the customer selects. The country field in my example is an option set. 

In the HTML of the Business Phones field you can see that there are two attributes that contain the country code. If I only change the class phoneCountryCodeLabel via the javascript, I run into the problem that the contact record that is created or updated still contains +49 in the phone field. So just changing the label is just a change in the frontend, it looks correct but it doesn’t transfer the value correctly. This is why the Javascript must also adapt the data-countrycode based on the country.

				
					<script style="display: none;">
document.addEventListener("d365mkt-afterformload", function() {
    const countrySelect = document.getElementById('pk_countrycode-1719506023770');
    const phonePrefixSpan = document.querySelector('.phoneCountryCodeLabel');
    const phoneInputDiv = document.querySelector('.phoneFormFieldBlock');

    const countryPhonePrefixes = {
        '125550000': '+376', // Andorra
        '125550001': '+32',  // Belgium
        '125550002': '+358', // Finland
        '125550005': '+33',  // France
        '125550003': '+49',  // Germany
        '125550008': '+39',  // Italy
        '125550010': '+47',  // Norway
        '125550007': '+351', // Portugal
        '125550006': '+34',  // Spain
        '125550009': '+46',  // Sweden
        '125550004': '+44'   // UK
    };

    countrySelect.addEventListener('change', function () {
        const selectedValue = countrySelect.value;
        if (countryPhonePrefixes.hasOwnProperty(selectedValue)) {
            const newPrefix = countryPhonePrefixes[selectedValue];
            phonePrefixSpan.textContent = newPrefix;
            phoneInputDiv.setAttribute('data-countrycode', newPrefix);
        } else {
            phonePrefixSpan.textContent = ''; // Default to empty if no match found
            phoneInputDiv.removeAttribute('data-countrycode');
        }
    });
});

    </script>
				
			

3 Option Set Dependencies

In a previous chapter we saw how to show different values based on one option set. Now this is a bit more complex. We have three option sets. And their values are dependend from each other. So when in option set 1 a value is chosen, we need to filter the values in option set 2. And depending on the chosen value in option set 2, we filter the values in option set 3.

In the javascript we need to specify the dependencies and how the option set values are related to each other. The script also includes the function to reset the values in the option set when e.g. option set 1 is changed.

				
					<script style="display: none;">
         document.addEventListener("d365mkt-afterformload", function() {
            //specify the 3 option sets
    var country = document.querySelector('[data-targetproperty="pk_option1"] select');
    var industry = document.querySelector('[data-targetproperty="pk_option2"] select');
    var product = document.querySelector('[data-targetproperty="pk_option3"] select');

    // Store the options for the first option plus their related second options 
    var industryOptions = {
        '125550000': ['125550000', '125550001'], // Germany: Retail, Manufacturing
        '125550001': ['125550002', '125550003'], // Belgium: Telecommunication, Books
        '125550002': ['125550004', '125550005']  // Finland: Service, IT
    };

    var productOptions = {
        //Store the relations between the second and the third options
        '125550000': ['125550000', '125550001'], // Retail, Manufacturing: Product 1, Product 2
        '125550001': ['125550000', '125550001'], // Retail, Manufacturing: Product 1, Product 2
        '125550002': ['125550002', '125550003'], // Telecommunication, IT: Product 3, Product 4
        '125550005': ['125550002', '125550003'], // Telecommunication, IT: Product 3, Product 4
        '125550004': ['125550004', '125550005'], // Service, Books: Product 5, Product 6
        '125550003': ['125550004', '125550005']  // Service, Books: Product 5, Product 6
    };

    // Function to update industry options (second option set) based on selected country (first option set)
    function updateIndustryOptions(countryValue) {
        var allowedIndustries = industryOptions[countryValue] || [];
        Array.from(industry.options).forEach(option => {
            option.style.display = allowedIndustries.includes(option.value) ? 'block' : 'none';
        });

        // Reset industry selection (option set 2)
        industry.value = '';
    }

    // Function to update product options (third option set) based on selected industry (second option set)
    function updateProductOptions(industryValue) {
        var allowedProducts = productOptions[industryValue] || [];
        Array.from(product.options).forEach(option => {
            option.style.display = allowedProducts.includes(option.value) ? 'block' : 'none';
        });

        // Reset product selection (third option set)
        product.value = '';
    }

    // Event listeners for changing country and industry (first and second option set)
    country.addEventListener('change', function() {
        updateIndustryOptions(this.value);
        updateProductOptions(''); // Reset products on country change
    });

    industry.addEventListener('change', function() {
        updateProductOptions(this.value);
    });
});
</script>
    
				
			

***Please be aware: The content is accurate at the time of creation. It may be that Microsoft has made changes in the meantime.***

Check out the FAQ section of my blog as well: Short questions with quick answers! Go to FAQs

You think the post can also help others? Share it on LinkedIn:

5 Responses

  1. Hi Pauline,

    What a great resource! I’ve bookmarked the page.
    I hoped the field relationships (show and hide a field) would get baked into RTM as in Outbound. Now I don’t have to wait.

    Thanks.

    1. Hi Byron, thanks for the great feedback, glad it helps! If you have any ideas or needs for further script, let me know 🙂

  2. Thank you this is so helpful. I had another case recently where I was asked to add a text field that a user can use to submit comments through the form, like a notes field. Is this something that is possible with a JS as well?

    1. Hi Yulya, thanks for your feedback! In case the contact would add notes, you can add a simple multiline text field to the form. In case the user needs comments, maybe a hidden, prefilled field on the form would help? You could use javascript to automatically populate the hiddenfield. But I am not sure if i 100% understand your requirement and i cannot think of a different solution how your user can add a comment in the marketing form on the website, while a contact is submitting the form.

  3. Hi Pauline,

    Thank you very much, the scripts helped a lot in making marketing forms. I have one question regarding the hide/show fields on the marketing form. I have the function working when a checkbox is filled to show a field, but I am wondering if it also possible to apply to whether a normal field or lookup is filled.

    I have tried to create the javascript for this myself, but i got stuck on getting the change function to work. Do you know if this is possible?

Leave a Reply

Your email address will not be published. Required fields are marked *

WordPress Cookie Notice by Real Cookie Banner