Kaizen #181 - Mandating Subform Data for Blueprint Transitions using Widget

Kaizen #181 - Mandating Subform Data for Blueprint Transitions using Widget



Hello Developers!

Welcome back to another week of Kaizen! 

This time, we are tackling a common challenge on how to enforce subform data from a different module before allowing a blueprint transition in Zoho CRM Deals module.

Many CRM workflows require checking and collecting related records' data across modules before advancing a deal, case, or order to the next stage. Zoho CRM Blueprint natively support subforms from Quotes, Sales Orders, and Invoices for the Deals module with the help of Associated Items in the transition settings. 

Let us explore how to mandate custom subforms' data from a different module for a blueprint transition.

Why Mandate Subform Data from a Different Module?

In Zoho CRM, subforms manage multiple data entries under a single parent record. However, certain blueprint transitions may depend on subform data from related modules, such as:  
  • A Deal's transition may depend on the document data stored in the associated Contact’s subform.
  • A Service Request requiring validation against a subform in the related Account before processing.  
  • A Loan Application requiring income proof from the Customer’s subform before approval.  
Since blueprint transition rules only validate fields within the same module, you can use a custom widget to check and update subform data across modules before proceeding.

Business Scenario: Insurance Deals Qualification

Consider Zylker, an insurance company, using Zoho CRM to manage customers and streamline processes. Their sales process follows this blueprint when a deal reaches the Qualification stage:
Insurance Sales Blueprint

Steps to Build a Blueprint Widget

Step 1 - Review Basics

Refer to our earlier Kaizen on CLI Installation, Creating a Widget Project, and Internal hosting of the same.

Step 2 - Develop your Widget

After setting up the widget project using CLI, implement the logic based on your business case.

Here’s the logic for the sample use case we are discussing:

Widget Execution During Transition
  • When the user clicks the Collect Requirements transition, the widget loads.
  • Using the PageLoad event listener, retrieve the current record's ID and module name.
  • Use the GET Records API via its JS SDK to fetch the Contact ID linked to the Deal. 
ZOHO.embeddedApp.on("PageLoad", function(data) {
      // Fetch the current page's record details
      const recordId = data.EntityId;
      const moduleName = data.Entity;
      ZOHO.CRM.API.getRecord({Entity: moduleName, RecordID: recordId})
        .then(function(response) {
          const record = response.data[0];
          console.log("Current Record Details:", record);
          // Fetch the associated contact ID
 contactId = record.Contact_Name.id;

Check and Collect Required Document Details
  • Using the Contact ID, run a COQL query using Connection JS SDK to check if each Document Category has at least one entry in the Document Details subform.
Notes
Notes
In invoke connection JS SDK, use param type 2 for the API request payload inside the parameter key and param type 1 for regular parameters.

Explore the Working with Connections help page and create a connection with the necessary scopes to invoke the COQL API.
  • If all four categories (Address Proof, ID Proof, Income Proof, Medical Report) have at least one entry, the widget allows the transition immediately.
  • If any category is missing, the widget prompts the user to enter the details in a table that mirrors the Document Details subform in the Contacts module.
// Make a query API call 
          const query = {
            "select_query": `select Document_Category,COUNT(id) from Document_Details where id is not null and Parent_Id='${contactId}' group by Document_Category`
          };
          ZOHO.CRM.CONNECTION.invoke("crm_oauth_connection", {
            method: "POST",
            url: "https://www.zohoapis.com/crm/v7/coql",
            parameters: query,
            param_type: 2,
            headers: {
              "Content-Type": "application/json"
            }
 }).then(function(response) {
     const data = response.details.statusMessage.data;
            if (response.details.statusMessage === "" || (data && data.length < 4)) {
              createSubformUI();
              document.getElementById('contentContainer').style.display = 'block';
            } else if (data && data.length === 4) {
              document.getElementById('messageContainer').style.display = 'block';
              // Enable the "Move to Next State" button if all files are already updated
              const nextStateButton = document.querySelector('.nextStateButton');
              nextStateButton.disabled = false;
              nextStateButton.style.backgroundColor = ''; 
            }
 })

Update the Contact's Subform
  • The user enters the document details and clicks the Save button in the widget. 
  • Since subform updates act like a PATCH request, any existing record IDs must be included in the update payload to retain them. To get the existing subform record IDs make a  GET Records API call via its JS SDK
async function getExisitingSubFormRecords(contactId) {
let exisitingRecords = [];
awaitasync function getExisitingSubFormRecords(contactId) {
let exisitingRecords = [];
await ZOHO.CRM.API.getRecord({ Entity: "Contacts", RecordID: contactId })
.then(function (response) {
const record = response.data[0];
console.log("Current Record Details:", record);

if (record.Document_Details)
{
record.Document_Details.forEach(function (document) {
exisitingRecords.push({id: document.id});
});
}
})
.catch(function (error) {
console.error("Error fetching records:", error);
});
return exisitingRecords;
} ZOHO.CRM.API.getRecord({ Entity: "Contacts", RecordID: contactId })
.then(function (response) {
const record = response.data[0];
console.log("Current Record Details:", record);
record.Document_Details.forEach(function (document) {
exisitingRecords.push({id: document.id});
});
})
.catch(function (error) {
console.error("Error fetching records:", error);
});
return exisitingRecords;
}
  • Clicking the Save button executes the following actions:
    -> Uploads the selected file to Zoho File System (ZFS) using the Upload File API through its JS SDK.
    -> Updates the Document Details subform in the associated Contact record by adding the file ID from the upload response and each row's entry using the Update Records API (via the Update Record JS SDK).
  • Once the subform is successfully updated, the widget allows the transition to next Blueprint state.
async function updateRecord(event) {
event.preventDefault();
// Collect user entries from each row
const rows = document.querySelectorAll('#documentsTable tbody tr');
const documentDetails = await Promise.all(Array.from(rows).map(async (row, index) => {
const documentCategory = row.querySelector('select[name="documentCategory"]').value;
const documentNumber = row.querySelector('input[name="documentNumber"]').value;
const documentName = row.querySelector('input[name="documentName"]').value;
const documentFile = row.querySelector('input[name="upload"]').files[0];
const fileId = await uploadFile(documentFile);
return {
Document_Category: documentCategory,
Document_Number: documentNumber,
Document_Name: documentName,
Upload: [
{
file_id: fileId
}
]
};
}));
// Get the existing subform records
const existingRecords = await getExisitingSubFormRecords(contactId);
// Merge the existing records with the new records
existingRecords.forEach(record => documentDetails.push(record));
// Prepare the payload for the update API call
const payload = {
id: contactId,
Document_Details: documentDetails
};
// Make the update API call
ZOHO.CRM.API.updateRecord({
Entity: "Contacts",
APIData: payload
}).then(function (updateResponse) {
console.log("Update response:", updateResponse);
const saveButton = document.querySelector('.saveButton');
saveButton.textContent = "Saved";
saveButton.disabled = false;
saveButton.style.backgroundColor = 'grey';
// Enable the "Move to Next State" button after saving
const nextStateButton = document.querySelector('.nextStateButton');
nextStateButton.disabled = false;
nextStateButton.style.backgroundColor = ''; 
})

Step 3 - Validate and Pack the Widget

  • Follow the steps given in the Widget help page to validate and package the widget.
  • Go to Zoho CRM > Setup > Developer Hub > Widgets and click Create New Widget.
  • Fill in the required details as shown in this image and ensure to select Blueprint as the widget type.
    Creating a Blueprint Widget

Step 4 - Associate the Widget with the Blueprint

  • Navigate to Setup > Process Management > Blueprint and open the Deals Blueprint created for this use case.
  • Click on the Collect Requirements transition.
    Associate Widget to a Blueprint Transition
  • In the During tab on the left pane, select Widgets and associate the newly created widget.
  • Publish the Blueprint to activate the changes.

Try it Out! 

A complete working code sample of this widget is attached at the bottom of this post for reference. 
 
Now, let us see how this Blueprint works from the Deals page:  
  1. All required document details are available: The widget validates the Contact’s subform and allows the transition.  



  2. Missing or incomplete document details: The widget prompts the user to enter the missing details, updates the Contact’s subform, and then enables the transition.  



This approach ensures that required subform data from another module is validated and captured before proceeding with a Blueprint transition.  

Would you like us to address any of your pain-points or have a topic to discuss? Let us know in the comments or reach out to us via support@zohocrm.com.

Until next time, Happy Coding! 

---------------------------------------------------------------------------------------------------------------------------------------

Additional Reading

---------------------------------------------------------------------------------------------------------------------------------------


Info
More enhancements in the COQL API are now live in Zoho CRM API Version 7. Check out the V7 Changelog for detailed information on these updates.


      • Sticky Posts

      • Kaizen #197: Frequently Asked Questions on GraphQL APIs

        🎊 Nearing 200th Kaizen Post – We want to hear from you! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
      • Kaizen #198: Using Client Script for Custom Validation in Blueprint

        Nearing 200th Kaizen Post – 1 More to the Big Two-Oh-Oh! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
      • Celebrating 200 posts of Kaizen! Share your ideas for the milestone post

        Hello Developers, We launched the Kaizen series in 2019 to share helpful content to support your Zoho CRM development journey. Staying true to its spirit—Kaizen Series: Continuous Improvement for Developer Experience—we've shared everything from FAQs
      • Kaizen #193: Creating different fields in Zoho CRM through API

        🎊 Nearing 200th Kaizen Post – We want to hear from you! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
      • Client Script | Update - Introducing Commands in Client Script!

        Have you ever wished you could trigger Client Script from contexts other than just the supported pages and events? Have you ever wanted to leverage the advantage of Client Script at your finger tip? Discover the power of Client Script - Commands! Commands

        • Recent Topics

        • Error AS101 when adding new email alias

          Hi, I am trying to add apple@(mydomain).com The error AS101 is shown while I try to add the alias.
        • Unbundle feature for composite items

          We receive composite items from our vendors and sell them either individually or create other composite items out of them. So, there is a lot of bundling and unbundling involved with our composite items. Previously, this feature was supported in form
        • Regarding the integration of Apollo.io with Zoho crm.

          I have been seeing for the last 3 months that your Apollo.io beta version is available in Zoho Flow, and this application has not gone live yet. We requested this 2 months ago, but you guys said that 'we are working on it,' and when we search on Google
        • MTD SA in the UK

          Hello ID 20106048857 The Inland Revenue have confirmed that this tax account is registered as Cash Basis In Settings>Profile I have set ‘Report Basis’ as “Cash" However, I see on Zoho on Settings>Taxes>Income Tax that the ‘Tax Basis’ is marked ‘Accrual'
        • workflow not working in subform

          I have the following code in a subform which works perfectly when i use the form alone but when i use the form as a subform within another main form it does not work. I have read something about using row but i just cant seem to figure out what to change
        • Fetch data from another table into a form field

          I have spent the day trying to work this out so i thought i would use the forum for the first time. I have two forms in the same application and when a user selects a customer name from a drop down field and would like the customer number field in the
        • Record comment filter

          Hi - I have a calendar app that we use to track tasks. I have the calendar view set up so that the logged in user only sees the record if they are assigned to the task. BUT there are instances when someone is @ mentioned in the record when they are not
        • How to View Part Inventory and Warehouse Location When Creating a Work Order in Zoho FSM

          Hi everyone, We’re currently setting up Zoho FSM and would like to improve how our team selects parts when creating a Work Order. Right now, when we add a part or item to a Work Order, we can select it from our Zoho Inventory list but we don’t see any
        • FSM too slow today !!

          Anybody else with problem today to loading FSM (WO, AP etc.)?
        • Not able to Sign In in Zoho OneAuth in Windows 10

          I recently reset my Windows 10 system, after the reset when I downloaded the OAuth app and tried to Sign In It threw an error at me. Error: Token Fetch Error. Message: Object Reference not set to an instance of an object I have attached the screenshot
        • Mapping a custom preferred date field in the estimate with the native field in the workorder

          Hi Zoho, I created a field in the estimate : "Preferred Date 1", to give the ability to my support agent to add a preferred date while viewing the client's estimate. However, in the conversion mapping (Estimate to Workorder), I'm unable to map my custom
        • The sending IP (136.143.188.15) is listed on spamrl.com as a source of spam.

          Hi, it just two day when i am using zoho mail for my business domain, today i was sending email and found that message "The sending IP (136.143.188.15) is listed on https://spamrl.com as a source of spam" I hope to know how this will affect the delivery
        • Delegates - Access to approved reports

          We realized that delegates do not have access to reports after they are approved. Many users ask questions of their delegates about past expense reports and the delegates can't see this information. Please allow delegates see all expense report activity,
        • Split functionality - Admins need ability to do this

          Admins should be able to split an expense at any point of the process prior to approval. The split is very helpful for our account coding, but to have to go back to a user and ask them to split an invoice that they simply want paid is a bit of an in
        • Is there a way to request a password?

          We add customers info into the vaults and I wanted to see if we could do some sort of "file request" like how dropbox offers with files. It would be awesome if a customer could go to a link and input a "title, username, password, url" all securely and it then shows up in our team vault or something. Not sure if that is safe, but it's the best I can think of to be semi scalable and obviously better than sending emails. I am open to another idea, just thought this would be a great feature.  Thanks,
        • Single Task Report

          I'd like a report or a way to print to PDF the task detail page. I'd like at least the Task Information section but I'd also like to see the Activity Stream, Status Timeline and Comments. I'd like to export the record and save it as a PDF. I'd like the
        • Auto-response for closed tickets

          Hi, We sometimes have users that (presumably) search their email inbox for the last correspondence with us and just hit reply - even if it's a 6 month old ticket... - this then re-opens the 6 month old ticket because of the ticket number in the email's subject. Yes, it's easy to 'Split as new Ticket', but I'd like something automated to respond to the user saying "this ticket has already been resolved and closed, please submit a new ticket". What's the best way to achieve this? Thanks, Ed
        • How to Push Zoho Desk time logged to Zoho Projects?

          I am on the last leg of my journey of finally automating time tracking, payments, and invoicing for my minutes based contact center company - I just have one final step to solve - I need time logged in zoho desk to add time a project which is associated
        • Cannot access KB within Help Center

          Im working with my boss to customize our knowledge base, but for some reason I can see the KB tab, and see the KB categories, but I cannot access the articles within the KB. We have been troubleshooting for weeks, and we have all permissions set up, customers
        • Export to excel stored amounts as text instead of numbers or accounting

          Good Afternoon, We have a quarterly billing report that we generate from our Requests. It exports to excel. However if we need to add a formula (something as simple as a sum of the column), it doesn't read the dollar amounts because the export stores
        • why my account is private?

          when i post on zohodesk see only agent only
        • Getting ZOHO Invoice certified in Portugal?

          Hello, We are ZOHO partners in Portugal and here, all the invoice software has to be certified by the government and ZOHO Invoice still isn´t certified. Any plans? Btw, we can help on this process, since we have a client that knows how to get the software certified. Thank you.
        • 500 Internal Server Error

          I have been trying to create my first app in Creator, but have been getting the 500: Internal Server Error. When I used the Create New Application link, it gave me the error after naming the application. After logging out, and back in, the application that I created was in the list, but when I try to open it to start creating my app, it gives me the 500: Internal Server Error. Please help! Also, I tried making my named app public, but I even get the error when trying to do that.
        • Client Script | Update - Client Script Support For Portals

          Dear All! We are excited to announce the highly anticipated feature: Client Script support for Portals. We understand that many of you have been eagerly awaiting this enhancement, and we are pleased to inform you that this support is now live for all
        • Professional Plan not activated after payment

          I purchased the Professional Plan for 11 users (Subscription ID: RPEU2000980748325) on 12 September 2025, and the payment has been successfully processed. However, even after more than 24 hours, my CRM account still shows “Upgrade” and behaves like a
        • how to edit the converted lead records?

          so I can fetch the converted leads records using API (COQL), using this endpoint https://www.zohoapis.com/crm/v5/coql and using COQL filter Converted__s=true for some reasons I need to change the value from a field in a converted lead record. When I try
        • Auto Update Event Field Value on Create/Edit

          Hi there, I know this question has been posted multiple times and I've been trying many of the proposed similar scripts for a while now but nothing seems to work... what might I do wrong? The error I receive is this: Value given for the variable 'meetingId'
        • Pre-orders at Zoho Commerce

          We plan to have regular producs that are avaliable for purchase now and we plan to have products that will be avaliable in 2-4 weeks. How we can take the pre-orders for these products? We need to take the money for the product now, but the delivery will
        • Constant color of a legend value

          It would be nice if we can set a constant color/pattern to a value when creating a chart. We would often use the same value in different graph options and I always have to copy the color that we've set to a certain value from a previous graph to make
        • Zoho Pagesense really this slow??? 5s delay...

          I put the pagesense on my website (hosted by webflow and fast) and it caused a 5s delay to load. do other people face similar delays?
        • Payroll and BAS ( Australian tax report format )

          Hello , I am evaluating Zoho Books and I find the interface very intuitive and straight forward. My company is currently using Quickbooks Premier the Australian version. Before we can consider moving the service we would need to have the following addressed : 1.Payroll 2.BAS ( business activity statement ) for tax purposes 3.Some form of local backup and possible export of data to a widely accepted format. Regards Codrin Mitin
        • Problem with Email an invoice with multiple attachments using API

          I have an invoice with 3 attachments. When I send an email manually using the UI, everything works correctly. I receive an email with three attachments. The problem occurs when I try to initiate sending an email using the API. The email comes with only
        • Page Layouts for Standard Modules like CRM

          For standard modules like quotes, invoices, purchase orders, etc, it would be a great feature to be able to create custom page layouts with custom fields in Zoho Books similar to how you can in Zoho CRM. For example, and my current use case, I have a
        • Non-depreciating fixed asset

          Hi! There are non-depreciable fixed assets (e.g. land). It would be very useful to be able to create a new type of fixed asset (within the fixed assets module) with a ‘No depreciation’ depreciation method. There is always the option of recording land
        • Fixed asset management

          I want to know if there is any individual module for fixed assets management
        • One time sale item in billing automatically detects as service

          if i have some items which i don't want to add in my "item" list because its sold only for one time. but when i type item name in invoice, it (system) automatically takes it as a service and despite of HSN , it shows SAC code to be entered. if its selectable i.e. either item or service , it would be very helpful and a must have feature.
        • Project template after project creation

          How can I apply a project template AFTER the project has been created?
        • convert the project to templet

          i have some deployment ME product for different customer , i need to create a fixed template for use it rather then keeping creating this template every time
        • Seriously - Create multiple contacts for leads, (With Company as lead) Zoho CRM

          In Zoho CRM, considering a comapny as a lead, you need us to allow addition of more than one contact. Currently the Lead Section is missing "Add contact" feature which is available in "Accounts". When you know that a particular lead can have multiple
        • Related Module in Sharing Rules

          Zoho CRM team recently added the feature to filter records by Related Records It will be really beneficial if we can have this feature for Sharing Rules as well
        • Next Page