Kaizen #99 - Render Widgets Using Client Script

Kaizen #99 - Render Widgets Using Client Script

Hello everyone!
Welcome back to another interesting post. In this post, let us see how you can render Widgets using Client Script.

Widgets are embeddable UI components that you can create and add to your Zoho CRM. You can use widgets to perform functions that utilize data from third-party applications. You can build widgets for Zoho CRM using our JS SDK.

You can render a Widget through Client Script and pass data from the Widget to the Client Script.

Use Case:
At Zylker, a manufacturing company, the Service Agent places orders using the Orders module.  There is a sub-form named Product list. The user should add the products by clicking the "Add row" button every time. 



To avoid this, Zylker wants the users to select multiple products from a single pop-up. Once the user selects the products from that pop-up , the sub-form "Product list" should get updated with all those products(one product in one sub-form row).

Solution:

Whenever the user picks the Product Category, you can create a Client Script to render the widget. The Products selected by the user on the widget , will be passed to the Client Script and will be added as separate rows in  Product list subform.
 
1. Install Zoho CLI and add code to the app folder.
2. Upload the zip file as a Widget.
3. Create a Client Script to render the Widget and to add data to the Sub-form.


1.  Install Zoho CLI and add code to the app folder 

Follow the steps given in this post and add the html code, javascript file and css file.

Index.html



<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Choose products</title>
  <link href="styles/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="wgt_cp_popupContent">
    <section class="wgt_cp_contentWrap">
      <div hidden="true" id="noProductDiv">
        <pre>No products associated to the selected deal</pre>
      </div>
      <table width="100%" cellspacing="0" id="pTable">
        <thead>
          <tr class="wgt_productTblHead">
            <th><input type="checkbox" id="selectAll"     onclick="selectAllProducts(this)"></th>
            <th>Product Name</th>
            <th>Product Category</th>
            <th>Unit Price</th>
            <th>Quantity in Stock</th>
          </tr>
        </thead>
        <tbody id="tbody"></tbody>
      </table>
    </section>
  </div>
  <script src="./script/script.js"></script>
</body>
</html>


Script.js

var count = 0;
var productData, maxRows = 0;
ZOHO.embeddedApp.on("PageLoad", async function (data) {
 console.log("data from Client Script", data);
 maxRows = data.max_rows;
 const search_response = await ZOHO.CRM.API.searchRecord({ Entity: "Products", Type: "criteria", Query: "(Product_Category:equals:" + data.product_category + ")" })
 if (search_response && search_response.data && search_response.data.length) {
  productData = search_response.data;
  var htmlString = "";
  productData.forEach(({ id, Product_Category, Product_Name, Unit_Price, Qty_in_Stock }) => {
   htmlString = htmlString.concat(
    `<tr>
     <td><input type='checkbox' onclick='selected(this)' id='${id}' class='products'></td>
     <td>${Product_Name}</td>
     <td>${Product_Category}</td>
     <td>${Unit_Price}</td>
     <td>${Qty_in_Stock}</td>
    </tr>`
   );
  });
  document.getElementById("tbody").innerHTML = htmlString;
 } else {
  document.getElementById("pTable").hidden = true;
  document.getElementById("noProductDiv").hidden = false;}
});
ZOHO.embeddedApp.init();
function selected(element) {
 element.checked ? count++ : count-- ;
 document.getElementById("selectedCount").innerHTML = `${count} Products selected`;
}
function closewidget() {
 if (count > maxRows) {
  alert("Selected product is greater than the maximum subform rows.");
 } else {
  var selected_products = [];
  for (product_element of document.getElementsByClassName('products')) {
   product_element.checked && selected_products.push(productData.find(product => product.id === product_element.id));}
  console.log("returning to Client Script ...", JSON.stringify(selected_products));
  $Client.close(selected_products);}
}


As per the above script, the products are fetched from the "Products" module based on the "Product Category" selected by the user. This information is captured in "search_response" and is added to the body of  widget.html
Here,  the code $Client.close(selected_products); will pass the selected products from Widget to the Client Script and close the widget rendered from Client Script. Click here for more details about the variable $Client.
Next step is to upload the zip file of the app folder.
Click here to view the complete code.

2. Upload the zip file as a Widget
  • Go to Setup > Developer Space > Widgets.
  • Click Create New Widget.

  • The Hosting should be "Zoho" and mention the html page of the app folder that you uploaded.
Note: The widget should be of "button" type in order to render through a Client Script.

3. Create a Client Script to render Widget and to add data to the subform
  • Go to Setup > Developer Space > Client Script. Click +New Script.
  • Specify the details to create a script and click Next.
  • The Client Script should render the Widget when the user selects Product Category. So Client Script should have field event on the field "Product Category".
  • On the Client Script IDE, you can see the below details.

  • Enter the following script in the Client Script IDE and click save.

var products_list = ZDK.Page.getField('Product_list').getValue();
if (products_list.length === 1) { // Clear subform if empty row
    !Object.values(products_list[0]).every(value => !!value) && products_list.pop();
}
// Open widget with product category & max. allowed rows based on existing subform data
var selected_products = ZDK.Client.openPopup({
    api_name: 'choose_products', type: 'widget', header: 'Choose Products', animation_type: 1, height: '570px', width: '1359px', left: '150px'
}, {
    product_category: value, max_rows: 25 - products_list.length
});
// Update subform with Selected Products from the widget Popup
if (selected_products.length) {
    selected_products.forEach(product => {
        products_list.push({ Product_Name: { id: product.id, name: product.Product_Name }, Quantity: 1, Unit_Price: product.Unit_Price });
    });
  ZDK.Page.getField('Product_list').setValue(products_list);
}


  • To render a widget from Client Script, use openPopup(config, data)  ZDK. You can specify the configuration details like api name of the widget, title, size, animation type as parameters and specify the data to be passed as 'PageLoad' event data in the Widget. 
  • The response from the widget (i.e user selection) is captured by the variable "selected_products". Then each product (id,name,product_name,quantity and unit_price) is pushed to the list products_list. Finally, the product list value  is updated to the Product Category sub-form using setValue(value) ZDK. 
  • Here is how the Widget gets rendered through Client Script.



We hope you found this post useful. We will meet you next week with another interesting topic! If you have any questions let us know in the comment section.

Click here for more details on Client Script in Zoho CRM.


As we approach the 100th post in our Kaizen series next week, we invite you to share your queries and concerns with us.  We are always looking for ways to improve our content and make it more relevant to our readers.

Please fill out this form to share your thoughts.




Happy Coding!




    • Sticky Posts

    • 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.
    • Kaizen #226: Using ZRC in Client Script

      Hello everyone! Welcome to another week of Kaizen. In today's post, lets see what is ZRC (Zoho Request Client) and how we can use ZRC methods in Client Script to get inputs from a Salesperson and update the Lead status with a single button click. In this
    • Kaizen #222 - Client Script Support for Notes Related List

      Hello everyone! Welcome to another week of Kaizen. The final Kaizen post of the year 2025 is here! With the new Client Script support for the Notes Related List, you can validate, enrich, and manage notes across modules. In this post, we’ll explore how
    • Kaizen #217 - Actions APIs : Tasks

      Welcome to another week of Kaizen! In last week's post we discussed Email Notifications APIs which act as the link between your Workflow automations and you. We have discussed how Zylker Cloud Services uses Email Notifications API in their custom dashboard.
    • Kaizen #216 - Actions APIs : Email Notifications

      Welcome to another week of Kaizen! For the last three weeks, we have been discussing Zylker's workflows. We successfully updated a dormant workflow, built a new one from the ground up and more. But our work is not finished—these automated processes are
      • Recent Topics

      • Creating meetings from an email

        Hi. Similar to Outlook, it would be helpful if a meeting can be scheduled from an email so that the attendees need not be manually entered every time it's created.
      • Zoho Social API for generating draft posts from a third-party app ?

        Hello everyone, I hope you are all well. I have a question regarding Zoho Social. I am developing an application that generates social media posts, and I would like to be able to incorporate a feature that allows saving these posts as drafts in Zoho Social.
      • CRM Percent custom fields: When will it show the % symbol and behave like %?

        1. Actually Percent custom fields fail to show the % symbol. 2. When in formulas Percent fields work like number: 100 x 5% = 5 ideal world 100 x 5% = 500 what happens actually 3. When importing Percent fields the % symbol has to be removed and the data
      • Deprecation of the Zoho OAuth connector

        Hello everyone, At Zoho, we continuously evaluate our integrations to ensure they meet the highest standards of security, reliability, and compliance. As part of these ongoing efforts, we've made the decision to deprecate the Zoho OAuth default connector
      • RouteIQ for Zoho FSM

        Beste, Zou wel top zijn dat we een RouteIQ hebben voor FSM aangezien we constant moeten zien wat de beste route is voor onze monteurs. Nu moeten we een speciale aparte programma hebben om de beste route te berrekenen voor onze monteurs aangezien de planning
      • Let us view and export the full price books data from CRM

        I quote out of CRM, some of my clients have specialised pricing for specific products - therefore we use Price Books to manage these special prices. I can only see the breakdown of the products listed in the price book and the specialised pricing for
      • Changes to the send mail Deluge task in Zoho CRM

        Hello everyone, At Zoho, we continuously enhance our security measures to ensure a safer experience for all users. As part of our ongoing security enhancements, we're making an important update on using the send mail Deluge task in Zoho CRM. What's changing?
      • How to Invoice Based on Timesheet Hours Logged on a Zoho FSM Work Order

        Hi everyone, We’re working on optimizing our invoicing process in Zoho FSM, and we’ve run into a bit of a roadblock. Here’s our goal: We want to invoice based on the actual number of hours logged by our technicians on a job, specifically using the timesheets
      • Inclusion is the new engagement

        When in a very challenging situation, you may have peers or friends around you saying, “Everything will be okay.” They speak to you in a way that they are connected or in a language or tone that feels close. But your inner voice comes to you in a truly
      • DKIM verification for Squarespace website - Corrections to instructions

        Zoho Campaigns DKIM TXT record instructions for Squarespace show that Host field should show: 22111._domainkey.[domain name, e.g. mywebsite.com] However, after 72hrs, I had to reach out to Squarespace tech support, and they confirmed that the domain name
      • Passing the image/file uploaded in form to openai api

        I'm trying to use the OpenAI's new vision feature where we can send image through Api. What I want is the user to upload an image in the form and send this image to OpenAI. But I can't access this image properly in deluge script. There are also some constraints
      • My client requires me to have custom pdf file names to except payment for invoices, how can I customize this before emailing.

        Hello! I love the program so far but there are a few things that are standing in the way. I hope you guys can code them in so I can keep the program for years to come. My client requires I customize the pdf file names I send in for billing. Can you please
      • Disable All

        I want to disable all the fields on the form when it loads.  I know there is a way to do this by listing all the fields as follows: disable Name; disable Address; disable City;  ... I have over 50 fields on my form and i am wondering if there is a single command or way to just disable all fields on load.   On load = disable All Thank you for any help.  
      • Migrating my email from GMAIL to ZOHO MAIL..........

        I am a long time GMAIL user and I really only understand how they operate, but after reviewing your tutorials and forums online, it is quite unbelievable how much more and how much more streamlined ZOHO mail is, not to mention ZOHO's wonderful, more advanced capabilities. I do have several questions about transitioning over to ZOHO.  Primarily, where is the best place to start, what do I do first? And how hard is it actually to move all my business and personal accounts over here?  When I sign up
      • iOS Zoho Mail App Crashesruni

        Whenever I trying to search emails via the Zoho Mail app on my iPhone the app crashes, I am running the latest version of the app and the latest iOS version. I have all set reset the app and deleted the app and still have the same issue. Thank you in
      • Assessment Answered - Automation (Related List)

        Hello everyone, We have linked a candidate assessment to our job posting. When someone applies, they are required to answer all the assessment questions. However, some candidates submit their applications without completing the questions. In such cases,
      • Paid Support Plans with Automated Billing

        We (like many others, I'm sure) are designing or have paid support plans. Our design involves a given number of support hours in each plan. Here are my questions: 1) Are there any plans to add time-based plans in the Zoho Desk Support Plans feature? The
      • Can't change form's original name in URL

        Hi all, I have been duplicating + editing forms for jobs regarding the same department to maintain formatting + styling. The issue I've not run into is because I've duplicated it from an existing form, the URL doesn't seem to want to update with the new
      • Calendar report with order options and more quick view templates

        I think many of us regularly work with calendar-style reports. It would be great to be able to customize the quick view with new templates and have options to sort the entries for each day of the calendar by different criteria. I think this is an interesting
      • Shared Views

        Hello, is there a way to prevent an agent from changing a shared table view? I have no issues with agents being able to create and customize their own view, but when I create a view and share it to my team -- the expectation is that they are viewing it
      • Using Zoho answer bot across departments (help center articles from another department)

        Hi Zoho Community, I’ve run into a major issue and hope someone here has experience with this setup. We currently have a Help Center in the department A where all of our knowledge base articles are maintained. However, we would like to use a Zoho Answer
      • Zoho Desk Partners with Microsoft's M365 Copilot for seamless customer service experiences

        Hello Zoho Desk users, We are happy to announce that Zoho Desk has partnered with Microsoft's M365 to empower customer service teams with enhanced capabilities and seamless experiences for agents. Microsoft announced their partnership during their keynote
      • The Social Wall: January 2026

        Hello everyone, We’re back with the first edition of The Social Wall of 2026. There’s a lot planned for the year ahead, and we’re starting with a few useful features and improvements released in January to help you get started. Create a GBP in Social
      • Pipeline: Copying rulesets from one data source to another

        When creating and editing data pipelines, it would be really helpful to be able to copy the ruleset from one data source and 'paste' it to another. This would save time and reduce manual mistakes.
      • Doubt about maximum email reach

        Good morning, greetings. This is Bramdon García from EDULABS S.A.S ESP, located in Colombia. I'm writing to inquire about the possibility of sending an email to 35,000 people simultaneously. Our company has a Zoho account, but we'd like to know if there's
      • Zoho calendar not working in browser

        Hello, I am new to Zoho. I have two accounts for two separate businesses. In one of them, calendar loads in a browser no problem. However, if I use this account (sairfeetmusic.co.uk) calendar does not load. I also cannot add it to my Thunderbird Lightening
      • Authentication Failure when adding POP3 accounts

        Hi everyone, I am a new user currently migrating from Gmail to Zoho Mail. I decided to make the switch following Google's decision to discontinue POP3 fetching. I previously used Gmail as my primary mail hub, and Zoho seems like the perfect alternative
      • Trident Application Folder

        Hi, How to choose installation folder for Trident, by default it gets installed in C drive. How to change drive?
      • Email disappeared to specific contact

        Good afternoon, this morning I emailed somebody. This email isn’t showing up in my sent folder. They sent me a response which I clicked on and it disappeared immediately. Why could this be?
      • Create an Eye-Catching Announcement Widget for Your Help Center

        Hello Everyone! In this week’s edition, let’s explore how to keep your customers updated with exciting news in the Help Center. See how ZylkerMobile wowed their customers by bringing updates right to their portal. ZylkerMobile, the renowned brand for
      • Enable Free External Collaboration on Notecards in Zoho Notebook

        Hi Zoho Notebook Team, I would like to suggest a feature enhancement regarding external collaboration in Zoho Notebook. Currently, we can share notes with external users, and they are able to view the content without any issue. However, when these external
      • Updating records through Zoho Sheets View doesn't update timeline or trigger workflow rules

        I have noticed that when i update a series of record with the zoho sheets view (see here http://d.pr/i/ahnR) it doesn't update timeline history or trigger workflow rules. I am using it in the Deals module. Looking forward for some more info. Denis
      • How do I change the account bank charges are charged to?

        I want bank charges charged to my Credit Card Fees account. Is there a way to do this?
      • Mail Search should allow grouping by conversation like Gmail.

        Having switched from gmail I have found the search function hard to use. Mostly because mail is not grouped by conversation in search. If I search for a word when looking for a conversation had with someone then sometimes 10 emails will come up from the
      • Ability to CC on a mass email

        Ability to CC someone on a mass email.
      • Updation of Old Browsers Versions for Zoho CRM

        We have upgraded the default browser version for CRM to facilitate features like widgets and scripts that are often implemented aside from advanced functionalities for various business requirements. The latest version is aimed to provide better performance
      • Project-Based Inventory Consumption and Proforma Invoice in Zoho ERP

        While working with customers across different industries, we have identified a few functional questions and gaps that commonly arise—especially for project-based and service-oriented businesses. Many organizations, such as those in shipping, construction,
      • Zoho Desk domain Mapping not Working Showing CNAME Error

        I have created the subdomain and created the Cname as well as its instracted on the Zoho website  but when i try add the domain on help desk its showing error msg : Make sure you've mapped the CNAME entry and linked it to desk.cs.zohohost.com.au on your
      • Founders using Zoho — are you leveraging Zoho Campaigns + Zoho Social for thought leadership… or just sending emails?

        I’ve noticed something interesting in the Zoho ecosystem. Many founders use Zoho Campaigns and Zoho Social for basic marketing—newsletters, scheduled posts, and announcements. But very few are using these tools strategically to: • Position themselves
      • IMAP stopped working after enabling 2 factor authentication

        IMAP stopped working after enabling 2 factor authentication. Is there any solution for this?
      • Next Page