The CPQ Blog

How to Dynamically Populate an External Form in Tacton CPQ

Written by Magnus Fasth | Apr 7, 2025 6:00:00 AM

Tacton CPQ is a powerful tool for managing complex product configurations, but sometimes a standard UI isn't enough. What if you need an advanced calculation tool or a customized data entry form?

Instead of manually building a static form, you can dynamically generate one based on parameters received from CPQ.

In this post, we’ll walk through how to create an external HTML form that dynamically adapts to the configuration, sends data to an external API, and commits results back to CPQ—all using window.postMessage.

Why Use a Dynamically Populated Form?

From a business perspective, a dynamically populated form offers:

  • Flexibility: The form adapts to different configurations without hardcoded inputs.
  • Automation: No manual field creation—CPQ dictates what needs to be displayed.
  • Consistency: Ensures that user input follows structured parameters sent from CPQ.

For example, if a customer is configuring an industrial crane, the form might display weight limits and dimensions, but if they switch to an elevator system, it might show load capacity and motor specifications. With a dynamic form, these changes happen automatically.

 

Step 1: Receiving Parameters from Tacton CPQ

To populate the form dynamically, we first need to listen for incoming data from CPQ:

function handlePostMessage(event) {
    try {
        const parsedData = JSON.parse(event.data);
        if (parsedData.type === "parameters" && Array.isArray(parsedData.parameters)) {
            parameters = parsedData.parameters.reduce((acc, param) => {
                acc[param.name] = param.value;
                return acc;
            }, {});
            generateForm(); // Create form dynamically
        }
    } catch (error) {
        console.error("Invalid message format", error);
    }
}

window.addEventListener("message", handlePostMessage, false);

What’s happening?

  • We listen for messages sent from CPQ using window.postMessage.
  • When CPQ sends parameter data, we store it in a parameters object.
  • Finally, we call generateForm() to dynamically create input fields based on the received parameters.

 

Step 2: Generating the Form Dynamically

Once we have the parameters, we need to create corresponding input fields on the page.

function generateForm() {
    const parametersContainer = document.getElementById("parametersContainer");
    parametersContainer.innerHTML = ""; // Clear any previous inputs

    for (const [key, value] of Object.entries(parameters)) {
        const label = document.createElement("label");
        label.textContent = key;

        const input = document.createElement("input");
        input.type = "text";
        input.id = key;
        input.value = value;

        parametersContainer.appendChild(label);
        parametersContainer.appendChild(input);
    }
}

Key takeaways:

  • The form is not hardcoded; instead, it is created dynamically based on parameters sent by CPQ.
  • Each parameter from CPQ is turned into an <input> field with a corresponding label.
  • Whenever new parameters arrive, the form updates automatically.

 

Step 3: Sending Data to an External API

Once the user fills in the form, we need to send the updated values to an external service, such as a pricing or validation engine.

async function sendData() {
    const requestBody = {};
    Object.keys(parameters).forEach(key => {
        requestBody[key] = document.getElementById(key).value;
    });

    const endpoint = "https://example.com/api"; // Replace with actual API URL

    try {
        const response = await fetch(endpoint, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(requestBody)
        });
        const data = await response.json();
        displayResponse(data);
    } catch (error) {
        console.error('Error:', error);
    }
}

This step enables complex calculations to be performed outside of Tacton CPQ before committing the results back.

 

Step 4: Sending Values Back to Tacton CPQ

Once we receive a response from the external API, we need to return the data to CPQ and update the configuration.

function commitToCPQ() {
    const payload = { fields: {} };

    document.querySelectorAll("#responseContainer input").forEach(input => {
        const key = input.id.replace("response_", "");
        payload.fields[key] = input.value;
    });

    const message = {
        namespace: "configuration_actions",
        action: "commit",
        payload: payload
    };

    window.top.postMessage(message, "*");
}

Final step: Clicking "Commit" sends the updated values back to CPQ.

 

A Smarter CPQ Experience

By integrating an external, dynamically generated form with Tacton CPQ, businesses can achieve:

  • Greater flexibility – The form adapts to different configurations in real-time.
  • Improved efficiency – No need for manual updates or hardcoded inputs.
  • Seamless automation – Data flows between CPQ and external tools without interruptions.

Whether you need a pricing calculator, a validation tool, or an advanced UI, this approach can significantly enhance the configurator experience.

Interested in learning more? Our CPQ experts can help you implement custom integrations for your business.