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 #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
    • Kaizen #152 - Client Script Support for the new Canvas Record Forms

      Hello everyone! Have you ever wanted to trigger actions on click of a canvas button, icon, or text mandatory forms in Create/Edit and Clone Pages? Have you ever wanted to control how elements behave on the new Canvas Record Forms? This can be achieved
    • Kaizen #142: How to Navigate to Another Page in Zoho CRM using Client Script

      Hello everyone! Welcome back to another exciting Kaizen post. In this post, let us see how you can you navigate to different Pages using Client Script. In this Kaizen post, Need to Navigate to different Pages Client Script ZDKs related to navigation A.
    • Kaizen #210 - Answering your Questions | Event Management System using ZDK CLI

      Hello Everyone, Welcome back to yet another post in the Kaizen Series! As you already may know, for the Kaizen #200 milestone, we asked for your feedback and many of you suggested topics for us to discuss. We have been writing on these topics over the
    • Recent Topics

    • Blocked: Reason 554 5.1.8 email outgoing blocked

      Hello, we have an issue while sending e-mails; whole organization with about 150 users is blocked "Unable to send message reason 554 5.1.8 email outgoing blocked", our domain is "ancient.global" Please help.
    • Error remote server is misconfigured

      Recently migrated the server to a new one. Updated MX records, SPF and DKIM values. DNS Lookup shows updated values. Still the email is getting bounced with the error: 553 Relaying disallowed
    • want to remove www

      I am trying to create my account but it doesn't let me erase the WWW . I don't need it for my email
    • Changer le lieu d'hébergement zohomail

      Est-il possible de faire héberger mon compte ailleurs qu'aux USA ? Compte-tenu de la situation de ce pays, un hébergement en Europe ou en Inde serait plus sûr.
    • Migration from Asana

      I see a lot of migration options for Zoho Projects, but don't seem to see Asana. Is there no clear migration path without going manual or custom?
    • NO RECIBO MAILS

      Hace más de 10 días no puedo recibir mails en mi correo. Si puedo enviar correos. Pueden ayudarme? Saludos, Christian Zegarra
    • I am not able to check in and checkout in zoho people even location access allowed

      This issue i am facing in mackbook air m1, I allowed location in chrome browser and i also tried in safari but getting similar issue. Please have a look ASAP.
    • Unable to receive emails

      Hi I am unable to receive emails but I am able to send externally
    • How to show User Full Name, not record id in a User Filter in analytics

      Please see screen recording: https://workdrive.zohoexternal.com/external/21a9e0c39c4595c255a62791fdf3655d3df933114a8f1598bc852d0ff7e56ce3
    • MTA-STS

      请激活对 MTA-STS 的支持,谢谢。
    • All my sent emails from KOMMO CRM System are redirected to one of a subfolder from my Ibox

      Hello, all of the sent emails from my KOMMO CRM System are placed in a sub-sub-folders in my INBOX. Why is that? And how can i change this?
    • Facebook emails aren't coming through

      Hi How can I get my business Facebook account emails coming through to Zoho mails? Every time they send me a verify email it's not coming through to my hosted email on Zoho... I've sent support and email but no reply so far. Any help appreciated please.
    • Query in Analytics for tracking Physical Available For Sale from Books

      Need: a query in Analytics on which we can build reports related to Physical Stock from Books items.  In Books, each item has an Accounting Stock and a Physical Stock. In the settings you can toggle the 'Mode of Stock tracking' option and we have selected
    • how to capitalize first letter of every word in a string using deluge?

      "diego armando maradona" to be "Diego Armando Maradona" "diego maradona" to be "Diego Maradona" "maradona" to be "Maradona" how to do that using deluge?
    • Data Discrepancy Between Zoho Books and Zoho Analytics

      We have connected our Zoho Books account to Zoho Analytics, but we are noticing that the data being imported is not accurate or consistent between the two platforms. Despite the integration, there are discrepancies in the data values. Could you please
    • Data Discrepancy Between Zoho Books and Zoho Analytics

      We have connected our Zoho Books account to Zoho Analytics, but we are noticing that the data being imported is not accurate or consistent between the two platforms. Despite the integration, there are discrepancies in the data values. Could you please
    • Option to Upload Employee Picture During User Creation in Zoho One

      Hi Zoho Team, We would like to request the addition of a new feature in Zoho One's employee creation process. At the moment, we can only upload a profile picture for an employee after the employee has already been created in Zoho One. Request: Please
    • Automatically Create Mailboxes for Existing Zoho One Users in Zoho Mail

      Hi Zoho Mail Team, I hope you're doing well. I understand that email assignment is automatic when adding users with an email address that has email hosting enabled in Zoho One Directory. However, when we initially created our users, email hosting was
    • Google Ads Data is Publicly available in Zoho CRM

      We recently discovered that ALL of the following Google Ads fields are visible to all users in our CRM that have access to either Leads or Contacts modules. Not only is this troubling and inconvenient, it should be unacceptable. It also creates a mess
    • Power of Automation :: Streamline Task Sync from Zoho Projects to Zoho Mail.

      Hello Everyone, A Custom function is a user-written set of code to achieve a specific requirement. Set the required conditions needed as when to trigger using the Workflow rules (be it Tasks / Project) and associate the custom function to it. Requirement:-
    • Digest Avril - Un résumé de ce qui s'est passé le mois dernier sur Community

      Bonjour chers utilisateurs, Un nouveau mois se termine au sein de Zoho Community France. Faisons le point sur cette période. Le mois dernier, nous avons abordé deux approches clés du marketing : l’e-mail, outil traditionnel et sûr, et les réseaux sociaux,
    • The corresponding module is currently disabled in Zoho CRM.

      getting this error message when trying to set up sync between crm and invoice The corresponding module is currently disabled in Zoho CRM.
    • Estimated Time for releasing in Australia?

      wondering if theres any timelines for when this feature might be availible to use in Australia?? would be very helpful sooner rather than later! Thank you :)
    • Zoho Books | Product Updates | April 2025

      Hello partners, We’ve rolled out new features and enhancements to elevate your accounting experience. From FEC report to BillPay Add-on, these updates are designed to help you stay on top of your finances with ease. Export Transactions in Factur-X Format
    • Please cancel my trial / subscription

      I’m doing a free trial of the Enterprise version. I’m trying to cancel it and make sure I won’t be charged a subscription. I can’t follow your help pages for this because I don’t get a sidebar with the details. I’ve wasted a lot of time trying to do this.
    • 日付別メール送信リストの作成

      日々顧客に個別にメールを送信しています 日付別に送信先リストを作成することは可能でしょうか?
    • 【Zoho CRM】キオスク機能のアップデート

      ユーザーの皆さま、こんにちは。コミュニティチームの中野です。 今回は「Zoho CRM アップデート情報」の中から、キオスク機能のアップデートについて、 一部を抜粋してご紹介します。 キオスク機能とは? 特定の処理を行うための専用画面(キオスク)をノーコードで作成できる機能です。 自社の業務プロセスにあわせた画面の表示、タブをまたいだ処理などが可能です。 本アップデートにより、キオスクの柔軟性と操作性が大きく向上しました。 詳細について以下より確認しましょう。 <目次> データ取得機能:「データ選択不要」のデータ表示
    • Ability to Add Custom Favicon to Zoho Desk Survey Window

      Dear Zoho Desk Team, Greetings! We would like to request the addition of a feature that allows users to add a favicon displayed in the Zoho Desk Survey window. Currently, there is no option to set a favicon. Customizing the favicon would allow businesses
    • Campaigns Place-holder $ tags

      Hi there I’ve just started using Campaigns and I’ve been making use of the placeholder inserts available when constructing the email. However, in my contacts in CRM rather than have a first name and last name field I put their full name into the last
    • Setting Up Automated Lead Nurturing Campaign in Zoho CRM

      I want to create an automated lead nurturing campaign within Zoho CRM and Zoho Campaigns with the following requirements: Leads should receive a sequence of 5 emails, spaced 3 days apart. If a lead clicks a link in any email: A notification should be
    • Books Not Matching Transactions from Feed - "The total amount does not match with that of the transaction"

      Recently, transactions that are transfers from a foreign currency (FCY) account to a base currency (BCY) account are not allowing for matches with transactions from the bank feed. Please see the screenshots below: As one can see, the amount is in the
    • Inline and background image with from scratch contract type

      When using the "Create From Scratch" option to build a new contract type is it possible to add inline images as well as a background image? We want our company logo on the cover page as well as each page header and also have a background image that we
    • Is it possible to display a graph of data within a contact record

      I’ve had someone create deluge code to import data from another SaaS platform into Zoho CRM for my swimming pool company. This data is stored within each customer’s contact record under a custom module called "Chemicals" and is updated weekly with new
    • Adding the date of an expense to an invoice

      Hi there, I have uploaded a whole load of expenses. I have prepared an invoice, and want to add the expenses. However I need to show the date which the expenses were incurred - how can I do this in the template? Thanks Michael
    • How to Link WooCommerce Orders to Contacts in Zoho CRM for Better Customer Segmentation?

      I’m running a fashion e-commerce website using WordPress. My sales staff usually rely on customers’ past orders to segment and re-approach them for sales. However, I’m not sure how to apply Zoho CRM for this purpose, since I can’t link the orders from
    • [WEBINAR] - Importing PDF bank statements into Zoho Books [ Indian and GCC editions ]

      Hey everyone! Manually entering the bank statements into your accounting software for reconciliation purpose is a tedious and error-prone task that can compromise the accuracy of your accounts. The banking module in Zoho Books helps you solve this problem
    • Let’s Talk: What’s a Good Engagement Rate in 2025?

      What engagement rates are you seeing as healthy for Instagram, Facebook, & LinkedIn (higher education focused?) My top posts on the university alumni pages I manage typically see a 4-9 % engagement rate. What is industry average? Is this measured by the
    • Mandatory DEFAULT for Billable and markup percentage

      Hello. So we have been using books and process bills from vendors that are to be invoiced to customers. When we convert from a PO to a bill we can enter the customer name on the line items and that is great. However, we would like to know if the default
    • why is zoho assist server so slow

      Hello why is zoho assist server so slow, i use it every and and have fast speed at either end of the connection but zoho assist take upto 10 seconds per click, I connect on the chat they we will have a look and come back saying they have done a reset
    • Nested notebooks

      Dear Sir/Madam, I would like to know if it is possible to nest notebooks. It would be very helpful when there are too many, as it would improve organization. Thank you for your response. Best regards.
    • Next Page