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

      • How do you do ticket add ons in Backstage?

        Hi Everyone, If you wanted to have general admin tickets and allow for add ons, like camping, or car or Carbon offset. What would you do? Peace Robin
      • From Zoho CRM to Paper : Design & Print Data Directly using Canvas Print View

        Hello Everyone, We are excited to announce a new addition to your Canvas in Zoho CRM - Print View. Canvas print view helps you transform your custom CRM layouts into print-ready documents, so you can bring your digital data to the physical world with
      • validation rules doesn't work in Blueprint when it is validated using function?

        I have tried to create a validation rule in the deal module. it works if I try to create a deal manually or if I try to update the empty field inside a deal. but when I try to update the field via the blueprint mandatory field, it seems the validation
      • Pull cells from one sheet onto another

        Hello all! I have created an ingredients database where i have pricing and information and i want to pull from that database into a recipe calculator. I want it to pull based on what ingredient I choose. The ingredients database has an idea and i want
      • Emails Failing with “Relaying Issues – Mail Sending Blocked” in ZeptoMail

        Hello ZeptoMail Support Team, We are facing an email delivery issue in our ZeptoMail account where emails are failing with the status “Process failed” and the reason “Relaying issues – Mail sending blocked.” Issue Details Agent Name: mail_agent_iwwa From
      • How does Zoho handle support operations for our EU users?

        Dear Zoho users, We have some news and reminders about how we handle support operations for Zoho users in the EU Data Center. This is part of our broader commitment to ensuring GDPR compliance and providing secure data handling for all users. We'd like
      • Layout Adjustment.

        Hello Latha, Hope you are doing well. I wanted to check with you about adjusting the layout columns in the Service Report from the backend, as currently there is no capability for us to customize the layout from our end. Below is the output that I am
      • Anyone in Australia using Zoho Books AND has their account with NAB?

        Hi I have an account with both NAB and Suncorp. Suncorp transaction come in the next day however NAB transactions take 4-5 business days to appear. eg: A deposit made today in my Suncorp will be imported into Zoho tomorrow. A deposit made today to the NAB account will be imported maybe Saturday (Friday overnight). I have contacted both Zoho and NAB but noone seems to know why. I was just wondering if anyone else in Australia uses NAB and has this issue (or doesn't) maybe we could compare notes and
      • Zoho Often Lag

        Desk Team, We've noticed that Desk, Creator & other apps seems to lag more these days. We often refresh multiple times.
      • Importing into the 'file upload' field

        Can you import attachments into the file upload field. I would expect it to work the same way as attachments do, But can't seem to get it to work. Moderation Update: The option to import into File Upload and Image Upload fields has been supported. Read
      • Layout Rules Don't Apply To Blueprints

        Hi Zoho the conditional layout rules for fields and making fields required don't work well with with Blueprints if those same fields are called DURING a Blueprint. Example. I have field A that is used in layout rule. If value of field A is "1" it is supposed to show and make required field B. If the value to field A is "2" it is supposed to show and make required field C. Now I have a Blueprint that says when last stage moves to "Closed," during the transition, the agent must fill out field A. Now
      • Zoho Desk blank screen

        opened a ticket from my email, zoho desk comes up blank, nothing loads. our receptionist also gets the same thing under her login on her computer. our sales rep also gets same thing on zoho desk at his home on a different computer. I tried clearing cache/history/cookies,
      • Optimum CRM setup for new B2B business

        Can some advise the most common way to setup Zoho CRM to handle sales for a B2B company? Specifically in how to handle inbound/outbound emails. I have spent hours researching online and can't seem to find an accepted approach, or even a tutorial. I have
      • filter on sheets mobile (iOS, iPadOS) does not work

        I have this issue on every spreadsheet, whether imported or created natively in Zoho Sheets. I can use on desktop without issue: desktop screenshot on iOS the filter dropdowns are not there and there is no way to add them mobile iPadOS looks the same
      • Canva Integration

        Hello! As many marketing departments are streamlining their teams, many have begun utilizing Canva for all design mockups and approvals prior to its integration into Marketing automation software. While Zoho Social has this integration already accomplished,
      • Can't edit Segments

        Happening with 2 different Zoho One environments, in different browsers. Please fix.
      • Error 554 Email Outgoing Error

        Our email address (info@tvbhouston) was recently migrated to a new domain host on WordPress, and our SSL certificate is still pending. We would like to continue using your service, but we are currently unable to send emails. Could you please re-enable
      • Transfer ownership of files and folders in My Folders

        People work together as a team to achieve organizational goals and objectives. In an organization, there may be situations when someone leaves unexpectedly or is no longer available. This can put their team in a difficult position, especially if there
      • Consumer Financing

        Does Zoho currently have a payment gateway (such as Stripe, Square, etc) which offers financing for customers? So, let's say the estimate we give the customer is greater than what they can afford at the time, but we can sell the service now, letting them
      • Subform edits don't appear in parent record timeline?

        Is it possible to have subform edits (like add row/delete row) appear in the Timeline for parent records? A user can edit a record, only edit the subform, and it doesn't appear in the timeline. Is there a workaround or way that we can show when a user
      • Zoho CRM - Option to create Follow-Up Task

        When completing a Zoho CRM Task, it would be very helpful if there was an option to "Complete and Create Follow-Up Task" in the pop-up which appears. It could clone the task you are closing and then show it on the screen in edit mode, all the user would
      • Deluge function to copy parent record file upload field to child record file upload field

        I'm stuck trying to write a deluge function that is triggered via automation in child record "Appointments," confirms if a file is in file upload "Report" field of parent "Contacts" record via Contacts lookup field "Contact_Name". If no file is in parent
      • Make panel configuration interface wider

        Hi there, The same way you changed the custom function editor's interface wider, it would be nice to be able to edit panels in pages using the full width of the screen rather than the currently max-width: 1368px. Is there a reason for having the configuration panel not taking the full width? Its impossible at this width to edit panels that have a lot of elements. Please change it to 100% so we can better edit the layouts. Thanks! B.
      • Image Compression Options

        Much better if we have level of options to compress the image [20%, 40%...] We are dealing with service reports daily that has before and after photos (image field)- the file size too large and one thing, the current limit is 10mb or 15mb for report
      • How to hide or archive a blog post temporarily in Zoho commerce website builder?

        I would like to temporarily hide or archive a blog post in zoho commerce website builder so that it doesnt appear on my website till I enable it again. I tried to look for this option but could not find it.  It only allows me to permanently delete a blog
      • How to mix different types of inputs (such as dropdown list and textbox)

        Hi, I'm creating a form called "Room Reservations" for a company. I created a "table" using "Matrix Choice". I created "Room 1", "Room 2" and "Room 3" with the "Questions". I would then like to create two columns with the "Answers", one called "Department"
      • How to Convert NSF to PST Format Effortlessly? - SYSessential

        It is highly recommended to obtain the error-free solution of the SYSessential NSF to PST converter to convert NSF files from Lotus Notes. Using this professional software, it becomes easier to convert all NSF database items, including emails, journals,
      • Zoho Commerce - Poor Features Set for Blogging

        Hi Zoho Commerce team, I'm sure you will have noticed that I have been asking many questions about the Blogs feature in Commerce. I thought that it would be useful if I share my feedback in a constructive way, to highlight the areas which I feel need
      • Pass shipping info to payment gateway Zoho Books to Authorize.net

        For some reason the integration from Zoho books to Authorize.net does not pass the shipping address. Authorize.net is ready to receive it, but zoho books does not send it
      • Massive Zoho Books failure

        We have not received any communication or notification from Zoho, but we have detected that Zoho Books is not working for all our users. We cannot access or use Zoho Books. This is critical. We are trying to contact Zoho on the Spain telephone number,
      • Does the Customer “Company Name” field appear anywhere in the Zoho Books UI outside of PDFs?

        Hi everyone, I’m trying to understand how the Company Name field is actually used in Zoho Books. There is a Company Name field on the customer record, but when viewing transactions like a Sales Order in the normal UI (non-PDF view), that field doesn’t
      • Email outbox is now available in the sandbox

        Hello all! Testing emails without visibility has always been a blind spot in the sandbox. With the new Outbox, that gap is closed. You can now view and verify every email triggered from your sandbox, whether it’s through workflows, approvals, or mass
      • Looking For Recruit Developer

        Hi everyone, I am looking for a Zoho Certified Developer to assist with a development project for MetalXpert. We are building a software system designed to bridge the gap between a candidate mobile app and an employer web portal using Zoho Recruit as
      • sales IQ issue on website

        i integrated the zoho sales IQ code on the website but it is comming in distroted form i am sharing the screenshot below the website is bulit in wix platform
      • I need to know the IP address of ZOHO CRM.

        The link below is the IP address for Analytics, do you have CRM's? IP address for Analytics I would like to know the IP address of ZOHO CRM to allow communication as the API server I am developing is also run from CRM. Moderation Update: The post below
      • Important Update: Google Ads & YouTube Ads API Migration

        To maintain platform performance and align with Google's newest requirements, we are updating the Google Ads and YouTube Ads integrations by migrating from API v19 to the newer v22, before the official deprecation of v19 on February 11, 2026. Reference:
      • Blocklist candidates in Zoho Recruit

        We’re introducing Block Candidate, which helps recruiters to permanently restrict a candidate from applying to current/future job openings. Once the candidate is blocked, they will no longer be able to participate in the recruitment process. This will
      • Admin asked me for Backend Details when I wanted to verify my ZeptoMail Account

        Please provide the backend details where you will be adding the SMTP/API information of ZeptoMail Who knows what this means?
      • Zoho Desk - Upsert Ticket

        Hi Desk Team, It is common to request more information from end-users. Using forms is a great way to ensure all the required information is collected. It would be great if there were an "upsert" option on the Zoho Form -> Zoho Desk integration which would
      • Client Side Scripts for Meetings Module

        Will zoho please add client side scripting support to the meetings module? Our workflow requires most meeting details have a specific format to work with other software we have. So we rely on a custom function to auto fill certain things. We currently
      • Next Page