Requirement Overview
A Zoho CRM user wants to have a customized validation pop-up based on changes made in the record by any user.
Use-case
A Car Company that has multiple warehouses located in different locations (i.e., India, USA, UAE, etc.). It would be difficult to provide the product shipping price for each location. Hence, user can dynamically select the required warehouse, and prices will be automatically updated in the record's respective field.
Here, The Company wants a validation alert based on the Shipping address which gives users an option to choose another location dynamically on the widget popup.
Challenges to achieve this directly:
=> As of now, we do not have a direct option to show the pop-up. Though, we have an option "i.e., method - getInput()" using Client Script to show the pop-up with the required fields and button. However, a user cannot have a required modification or customization on the pop-up based on business requirement.
=> Hence, the user can create a widget (using HTML, JavaScript, CSS, etc.) in Zoho CRM and invoke it using Client Script.
Refer to following Help Link to know more about getInput() method in Client Script. Why It is Important:
- Validation with customized pop-up, improves User Experience
- Error Prevention
- Data Quality & Accuracy
- Speed up internal process of Business
Permissions & Availability
-> Users with the Manage Extensibility can configure & setup Client Script and Widget.
-> Users with the Manage Sandbox permission can manage the sandbox and test this use-case.
Configuration
Since business use cases vary based on each company's requirements. To help you with basic understanding, we will develop a easier customized pop-up using Widget and learn how it can be invoked within a record on any page (i.e. Create/Edit/Detail/etc.).
-> If you are creating a widget for the first time, then let us explore how exactly a user can create a sample widget from scratch with initial understanding.
Refer to the following Help Link to install the necessary components in your system to create a first project. -> Once installed, the user can follow the instructions and create a first project.
Refer to the following Help Link which explains in detail about creating a sample widget. -> Now that you have created your first project, you could find the HTML file for the widget in the app folder, named "widget.html" by default. Users can copy paste the below sample HTML script for the widget.
- Widget HTML Sample Script:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <link rel="stylesheet" href="./stylee.css" />
- <title>Simple Calculator</title>
- <style>
- body {
- font-family: Arial, sans-serif;
- background-color: #f43c15;
- color: #721c24;
- text-align: center;
- padding: 50px;
- }
- .p1 {
- font-weight: bold;
- }
- .error-container {
- border: 1px solid #f5c6cb;
- background-color: #f8d7da;
- padding: 20px;
- border-radius: 5px;
- display: inline-block;
- width: 300px;
- margin-left: -25px;
- margin-top: -50px
-
- }
- h1 {
- margin: 0;
- }
- p {
- margin: 10px 0;
- }
- select {
- margin: 10px 0;
- padding: 10px;
- width: 100%;
- }
- button {
- padding: 10px 20px;
- margin: 5px;
- border: none;
- border-radius: 5px;
- cursor: pointer;
- }
- .cancel {
- background-color: #f5c6cb;
- color: #721c24;
- }
- .proceed {
- background-color: #28a745;
- color: white;
- }
- </style>
- </head>
- <body>
- <div class="error-container">
- <h1>Delivery Error</h1>
- <p>We're sorry, but there was an issue with your delivery.</p>
- <p>Please select the correct warehouse:</p>
- <input type="text" class="text" id="result">
- <br />
- <div class="buttons">
- <p class="p1">Available Warehouses</p>
- <button class="number" onclick="appendToResult('USA')">USA</button>
- <button class="number" onclick="appendToResult('UAE')">UAE</button>
- <button class="number" onclick="appendToResult('Pakistan')">Pakistan</button>
- <button class="number" onclick="appendToResult('Russia')">Russia</button>
-
- </div>
- <button class="proceed" id="flyout">Proceed</button>
- </div>
- </div>
- <script src="https://live.zwidgets.com/js-sdk/1.2/ZohoEmbededAppSDK.min.js"></script>
- <script>
- var result = document.getElementById("result");
- var sendData = document.getElementById("flyout");
- var FLYOUT_ID = null;
- function transportData() {
- ZDK.Client.sendResponse(FLYOUT_ID, {
- incrementedNumber: result.value,
- });
- }
- sendData.addEventListener("click", transportData);
- function appendToResult(value) {
- result.value += value;
- }
- function clearResult() {
- result.value = "";
- }
- function calculateResult() {
- try {
- result.value = eval(result.value);
- console.log("result.value", eval(result.value));
- } catch (error) {
- //result.value = "Error";
- }
- }
- /*
- * Subscribe to the EmbeddedApp onPageLoad event before initializing
- */
- ZOHO.embeddedApp.on("PageLoad", function (data) {
- console.log(data);
- //Custom Bussiness logic goes here
- });
- ZOHO.embeddedApp.on("Notify", function (data) {
- console.log("Client Script flyout notification", data);
- ZDK.Client.sendResponse(data.id, {
- choice: "mail",
- value: "example@zoho.com",
- });
- });
- ZOHO.embeddedApp.on("NotifyAndWait", function (data) {
- console.log("Client Script synchronous flyout notification", data);
- console.log(data.data);
- result.value = data.data.data;
- FLYOUT_ID = data.id;
- });
- /*
- * initializing the widget.
- */
- ZOHO.embeddedApp.init();
- </script>
- </body>
- </html>
- HTML Script Explanation
-> Under Style tag, we have simple css line of codes to show a required pop-up with customized colors and format.
-> Under Body tag, we have added all headers, paragraph and buttons by assigning class. We have also passed 'id' tag to "Result" text field & "Proceed" button to use it in Flyout code within HTML script.
-> Under Script tag, we have a code which communicate back to Client Script via Flyout.
-> Firstly, fetching both result text & proceed button. Then, sending result data back by using addEventListener("click", transportData). Here, 'transportData' is a function which sends response to Flyout.
- Creating Widget in Zoho CRM
Now, user can create a Widget in CRM as Button type to be invoked via Client Script.
Navigate to Setup (⚙️) in Zoho CRM >> Developer Hub >> Widgets.
Create New Widget and choose the options as per below screenshot:
Notes:
-> Ensure to select Type as - Button
-> Select Hosting as Zoho and Get the complete widget file as Zip to upload.
-> Pass the Index Page with html file name. For example: When you create a first project, html file name is "widget.html", user can pass index as "/widget.html".
Step2 - Creation of Client Script
Now, let us create a Client Script on Edit Page of a 'Sales Order' Module for a Page Event based onSave trigger. As an example, whenever the user clicks on "Save" button in Edit Page, script will be triggered and throw a pop-up to end user based on validation.
Follow the steps below to configure the Client Script for this use case:
1) Provide the basic information, like Name and Description based on script purpose.
2) In the Category Details section, please choose the following:
* Category as Module.
* Page as Edit.
* Module as Sales Order.
* Choose the required Layout.
3) In the Event Details section, please choose the following:
* Type as a Page Event.
* Event as onSave
The Code
- console.clear();
- var field_obj = ZDK.Page.getField('Warehouse');
- var warehouse = field_obj.getValue();
- if (warehouse == "India") {
- console.log("entered");
- var WIDGET_API_NAME = "Popup1";
- ZDK.Client.createFlyout('myFlyout', { header: "Delivery Error Alert", animation_type: 1, close_icon: false, height: '385px', width: '240px', left: 'center' });
-
- ZDK.Client.getFlyout('myFlyout').open({ api_name: WIDGET_API_NAME, type: 'widget' });
- console.log("Flyoutcreated");
- var response = ZDK.Client.getFlyout('myFlyout').notify({ data: ZDK.Page.getField('Warehouse').getValue() }, { wait: true });
- ZDK.Client.getFlyout('myFlyout').close();
- console.log('??? ', response);
- console.log(response.incrementedNumber)
- ZDK.Page.getField('Warehouse').setValue(response.incrementedNumber);
- ZDK.Client.showMessage('Warehouse has been sucessfully updated', { type: 'info' });
- }
-> Initially, we will fetch the warehouse field value and store it in variable (i.e., warehouse).
-> As a basic validation, whenever user selects "India" as warehouse and click on Save button, validation error pop-up will be thrown to select the different warehouse. Hence, if user selects "India", we are performing below actions:
Flyout method
-> Flyouts are floating User Interface that can be controlled using Client Script. User could invoke a widget as popup or component in any place on page.
-> Flyouts will be useful to communicate between Widget and Client Script.
-> It can wait for the input from widget and collect it by populating to respective fields in CRM.
-> As explained above, we will create a flyout (i.e. component in web page) and place it accordingly by adjusting height, widget, etc.
-> Then, we will pass the Widget to the created Flyout component.
-> Here, Flyout will wait and widget code (explained above) will be executed then, Flyout will get the data back from widget result text (where selected warehouse will be stored).
-> Then, Flyout will be closed and populate the data into CRM field.
-> It will also show a message pop-up at last by stating "Warehouse has been successfully updated", if the CRM field data was updated via widget.
Working Demo - Screencast
-> User can configure the same setup for other pages (i.e., List View/Create/Detail, etc.) as well.
-> Also, user can make an advanced customization using HTML & CSS in the widget and throw it to end user.
To ensure a smooth implementation, we recommend configuring and testing the setup in the sandbox environment before deploying it to production.