Kaizen #187 - Building a Timer and Worklog Widget (Part 1)

Kaizen #187 - Building a Timer and Worklog Widget (Part 1)



Howdy Tech Wizards!

Welcome back to a fresh week of Kaizen! 

This time, we are diving into a two-part series where you will learn how to build a Timer and Worklog Widget for Zoho CRM. This widget helps track active work time and log multitasking sessions using Zoho CRM APIs, Client Script, Functions, and Workflows.

Why It Matters?

Zoho CRM effectively captures stage/status transitions, like tracking when a case moves from Open to In Progress or On Hold. However, in dynamic work environments, employees juggle multiple work items and engage in impromptu tasks or conversations. 

Let’s take the On Hold status as an example. 

While it can be used to indicate pauses in progress, it does not always align with real-world workflows. Consider these scenarios:

Not all interruptions justify a status change 

Moving the case to On Hold for every minor detour (to clarify something with a colleague or respond to another emergency work item) would be impractical and could lead to under reporting actual work hours. Over time, this untracked effort adds up, creating a gap in visibility.

Frequent status changes may dilute their meaning 

In many teams, On Hold signifies a legitimate blocker like waiting on customer input or an external dependency. Using it frequently to reflect quick shifts in attention could compromise that clarity. 

A timer widget solves this by:
  • Capturing hands-on work items.
  • Logging context switches (unrelated tasks) with descriptive entries.
  • Feeding structured entries into a custom module for reporting and subform sync.

Business Scenario: IT Service Desk & Ticket Resolution

A tech support team uses the Cases module to resolve customer issues. Some tickets are straightforward; others require follow-ups, escalations, or cross-team coordination. While CRM timestamps (like stage transitions or picklist tracking) track when changes happen, they do not reflect how long someone actively worked on a case.

This Timer Widget can be the ultimate solution to track down the active time spent on each case through out the day.

What are we Building?

By the end of this two-part guide, you will know how to:
  • Build a timer widget to track time per task or any CRM record.
  • Log work sessions into a custom module every time the timer is started/stopped.
  • Automatically populate a subform in the corresponding record module using workflows and Deluge functions.
  • Leverage the Reports module to analyze work patterns, SLA adherence, and productivity trends.
 In Part I, we will focus on:
-> Building and configuring the Timer Widget.
-> Capturing each timed session as a record in a custom module.

Prerequisites

1. Create a Custom Module

Create a custom module named Timer Entries to log work details and generate reports from the Reports module. A new record will be added to this module each time a timer is started.

Set up the following custom fields in the Timer Entries module:

Custom Fields
Data Type
Start Time
DateTime
End Time
DateTime
Total Duration (in mins.)
Formula 
DateBetween(${Timer Entries.Start Time},${Timer Entries.End Time},'Minutes')
Related to Case
Lookup to Cases module
Work Description
Multi Line


2. Add a custom picklist option

Add a custom picklist option called In Progress to the Status picklist field in the Cases module for precisely identifying the status of the cases. 

Follow this Add/Remove Picklist Values help section for more details. 

3. Setup Custom Views for Contextual Filtering

To streamline the widget experience and ensure users only see relevant records to associate while tracking time, set up two smart custom views—one in the Cases module and another in the Timer Entries module. 

Active Cases View (Cases Module)

Create a custom view in the Cases module to list only the active tickets the logged-in user is working on. Use the following criteria tips:
  • Use the Status field to filter records with values like In Progress, On Hold, or Escalated.
  • Use the Case Owner field to show records that are assigned only to the currently logged-in user.
This view powers the drop-down inside the widget where users select the case they want to start the timer for.
Active Timers View (Timer Entries Module)

Set up a second custom view in the Timer Entries module to track entries where the timer has been started but not yet stopped. These represent active timers. Use the following logic for criteria:
  • The End Time field is empty (i.e., timer still running).
  • Timer Entry owner field matches the logged-in user.
This view is used internally by the widget to detect if a timer is already running and update the same entry once the timer is stopped.
Follow the Managing List View help page and use the specifications shown in the following image.

Building the Timer 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 the Widget

After initializing your widget project using CLI, implement the timer logic:

Fetching Active Cases

On page load, the populateRecordsDropdown function initiates a Get Records API call to the Cases module, using the Active Cases custom view ID. This fetches all active case records assigned to the logged-in user. 

These records are then listed in a dropdown, allowing users to quickly select the relevant case they are about to work on.

async function populateRecordsDropdown() {
            const recordsDropdown = document.getElementById("moduleRecords");
            recordsDropdown.innerHTML = ""; 

            try {
                const recordsResponse = await ZOHO.CRM.API.getAllRecords({
                    Entity: casesModule,
                    cvid: casesCVID,
                    per_page: 10
                });

                if (recordsResponse.data && recordsResponse.data.length > 0) {
                    recordsResponse.data.forEach(record => {
                        const option = document.createElement("option");
                        option.value = record.id;
                        option.textContent = record.Subject || "Unnamed Record"; 
                        recordsDropdown.appendChild(option);
                    });
                } else {
                    const placeholderOption = document.createElement("option");
                    placeholderOption.value = "";
                    placeholderOption.textContent = "No records found";
                    placeholderOption.disabled = true;
                    placeholderOption.selected = true;
                    recordsDropdown.appendChild(placeholderOption);
                }
            } catch (error) {
                console.error("Error fetching records:", error);
            }
        }

Starting the Timer and Creating an Entry

Once the user starts the timer, The createRecord function triggers a Create Record API call to log the session in the Timer Entries custom module. The record captures the start time and the related case and description (if provided).

Even if no details are entered or case is selected, a timer entry is still created with the start time. This ensures that spontaneous work sessions are tracked and not lost.

async function createRecord(startTime) {
            try {
                const workDescription = document.getElementById("workDescription").value;
                const selectedRecordId = document.getElementById("moduleRecords").value;
                const selectedRecordText = document.getElementById("moduleRecords").options[
                    document.getElementById("moduleRecords").selectedIndex
                ].text;

                const data = {
                    Start_Time: startTime,
                    Owner: currentUserId,
                    Work_Description: workDescription,
                    Related_to_Case: selectedRecordId, 
                    Name: selectedRecordText 
                };

                const response = await ZOHO.CRM.API.insertRecord({
                    Entity: timerModule,
                    APIData: data
                });

                console.log("Start time recorded successfully");
            } catch (error) {
                console.error("Error creating record:", error);
            }
        }


Stopping the Timer and Updating the Entry

When the timer is stopped, the widget uses the Active Timer Entry custom view to locate the most recent Timer Entry record created by the logged-in user that does not have an end time. 

The updateRecord is then triggered to update that active entry using the Update Record API call. It updates the End time of the session and the related case, descriptions, if it was not already provided when the timer was started.

async function updateRecord(endTime) {
            try {
                const workDescription = document.getElementById("workDescription").value;
                const selectedRecordId = document.getElementById("moduleRecords").value;

                const response = await ZOHO.CRM.API.getAllRecords({
                    Entity: timerModule,
                    cvid: timerEntriesCVID,
                    per_page: 1
                });

                const latestRecord = response.data[0];
                if (latestRecord) {
                    const recordId = latestRecord.id;
                    const data = {
                        id: recordId,
                        End_Time: endTime,
                        Work_Description: workDescription,
                        Related_to_Case: selectedRecordId 
                    };

                    await ZOHO.CRM.API.updateRecord({
                        Entity: timerModule,
                        APIData: data,
                        RecordID: recordId
                    });
                    console.log("End time updated successfully");
                }
            } catch (error) {
                console.error("Error updating record:", error);
            }
        }

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 Button as the widget type.

Step 4 - Associate it with Flyout

  • Go to Setup > Developer Space > Client Script. Click New Script.
  • Enter a name and description for the script. Choose Command type in Category

  • Create a Flyout and render a widget within it using its details like the API name of the widget, title, size, and animation type. You can get the Widget API name from the widget's detail page. 
let allowedUserEmails = [];
allowedUserEmails.push('user1_email_address');
allowedUserEmails.push('user2_email_address');
allowedUserEmails.push('user3_email_address');
let currentUserEmail = $Crm.user.email;
if (allowedUserEmails.indexOf(currentUserEmail) == -1) {
    ZDK.Client.showMessage('Command access resticted', { type: 'error' });
    return false;
}
ZDK.Client.createFlyout('myFlyout', {header: 'Timer', animation_type: 4, height: '600px', width: '500px', top: '10px', left: '10px', bottom: '10px', right: '10px' });
ZDK.Client.getFlyout('myFlyout').open({ api_name: 'Timer', type: 'widget' });
return true;

Refer to Creating a Client Script help page for more details. 

Try It Out!

A complete working code sample of this widget is attached to this post.

Now, let us see how this Timer widget works:

1. Start the Timer 

Open the widget and select an active case from the dropdown. As soon as you start the timer, a new record will be automatically created in the Timer Entries module to capture the session.

2. Stop the Timer 

When the task is complete, provide a description of the work you have done and stop the timer. The same Timer Entry record (created when the timer was started) will be updated automatically with the end time and your work description.

This forms the foundation for accurate time tracking at the record level. 

In Part 2, we will show how to:

-> Use a workflow and Deluge function to transfer these entries into the Work Log subform inside the relevant Cases record.
-> Use CRM Reports to slice and dice work time for better SLA and productivity insights.

In the meantime, 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! 

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

Related Reading

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

Idea
Previous Kaizen: Client Script Support for Subforms | Kaizen Collection: Directory


    • Recent Topics

    • New in CPQ: Create dynamic actions in Product Configurator (PC), clone PCs and Price Rules (PRs)

      Configuring product combinations just got enhanced. Zoho CRM's CPQ system now supports dynamic actions based on multiple base products. Additionally, you can now clone configurations for both Product Configurator (PC) and price rules (PRs). Dynamic actions
    • Beyond Email: #2 Connect better with Contacts

      After successfully creating a 'Welcome & Setup' event using the Calendar, Sarah is eager to invite her team members to participate. For a smoother communication experience and easy access, Sarah wants to store their information, ensuring quick reference
    • Integrate MS Teams with Zoho CRM for faster collaboration

      Availability Editions: Standard and above DCs: All Release status: This feature has been released for all users in all DCs. Help resource: Microsoft Teams integration Hello everyone, We're adding MS Teams to our lineup of CRM chat integrations—Cliq, Slack,
    • What is New in CRM Functions?

      What is New in CRM Functions? Hello everyone! We're delighted to share that Functions in Zoho CRM have had a few upgrades that would happen in phases. Phase 1 An all new built-in editor for better user experience and ease of use. ETA: In a couple of days.
    • Subforms and Reports

      I am trying to do a report that shows various data from subforms. eg I want a report that shows what Bill Status are Approved Required. Or show the status of all bills. It doesn't look like Zoho Reports picks up information within reports. Is there another
    • Pass variables to Zoho Desk via URL to create a fast new ticket landing page

      We are integrating our phone system into Zoho Desk. Currently when a helpdesk agent answers the phone, a soft client opens a new tab with zoho desk at the new case page. https://desk.zoho.com/support/companyname/ShowHomePage.do#Cases/new We would like
    • 【Zoho CRM】アナリティクス機能のアップデート:ウォーターフォールの導入

      ユーザーの皆さま、こんにちは。コミュニティチームの藤澤です。 今回は「Zoho CRM アップデート情報」の中からアナリティクス機能のアップデートをご紹介します。 本記事は、以前紹介された機能に新たに追加された機能です。 以前の記事:https://support.zoho.co.jp/portal/ja/kb/articles/zoho-crm-visualize-your-data-with-a-new-set-of-charts-treemap-butterfly-sankey-and-cluster-charts
    • [Free Webinar] Learning Table Series - Creator for the Finance Industry

      Hello Everyone! The Learning Table Series is a free monthly webinar that runs for around 45 minutes. It's offered to our Community users and aims to provide a dynamic learning experience by demonstrating how Creator can be used as a solution for various
    • Webhook - Configuration failed: 200 response not received for POST request

      Hello, I am trying to set up a webhook to connect with an automation software but I receive the following error from Zoho: Configuration failed: 200 response not received for POST request I have tried testing it on webhook.site as well and receive the
    • Automated Shopify adjustment problem. "An inventory adjustment has been created by the system to set the initial stock from Shopify"

      Has anyone noticed issues since the Shopify Sync has been updated recently? If you sync with Shopify, check to see if there are automated adjustments for old products that keep recurring. We have this problem for 6 SKU's that Zoho is doubling the stock
    • Best website platform to sync to Zoho Inventory

      Anyone like to suggest the best website platform for syncing to Zoho Inventory? We DO NOT want to sync stock, only orders. Shopify - not an option as we have more than one website and Shopify requires 2 accounts and Zoho will not sync with 2 different accounts. Magento and WooCommerce both sync via Kloudconnectors - does anyone have any experience with this? I have trialled it and there are flaws - eg purchase order numbers are not populated. Discussion welcome!
    • Include product images in data sync between Zoho CRM and Zoho Inventory

      Currently the item image does not sync between Zoho CRM and Zoho Inventory when using the internal Zoho sync functionality. This requires users to manually update the item image in Zoho Inventory for products created in CRM and vice versa. Including the
    • Show ordered quantity on packing slips and invoices

      Hello Is there any way possible to show the original ordered quantity of an item (as recorded in the sales order) on subsequent package slips and sales invoices, so that these documents can show the customer the ordered qty vs the qty being currently
    • Search Zoho Inventory Items module via API

      How can I search Zoho Inventory Items by custom fields, categories, etc using the API? This is not documented. Is there an advanced search function like CRM's COQL search available via the Zoho API? If there is an undocumented way to search Items via
    • How can I get my images to display correctly on mobile site?

      I have just created a site and uploaded images, which look perfect on the desktop version. However when I view the site on my mobile device some of the images are not displaying correctly. They are all blurry. Anyone else experience this?
    • Does Creator support HTMX?

      I love the Zoho ecosystem and Zoho Creator does a lot of things really well. However, I'm needing more real-time interactivity in my forms. Is the only option to create a JS widget? How about HTMX?
    • My fix for "This report is not accessible" in published pages

      Hi Community, after having the same issue as many others here and going through the community's posts, i found a solution on my own. Again, the quality of support from Zoho is pretty awful: if you cannot help yourself, you're lost. I really like Zoho,
    • Tip of the Week #59– Enhance team collaboration with multichannel shared inboxes!

      Struggling with scattered customer conversations and missed follow-ups across your team? When messages are everywhere, it's easy for them to fall through the cracks—leading to delays, duplicate replies, and miscommunication among team members. Zoho TeamInbox
    • Subforms in stateless forms

      I think the title says it all. We need to be able to add subforms to stateless forms. Currently the only workaround is to create a Form and delete each record upon submission of the form. I need to build an interface to update our inventory. Basically
    • Delete standard e-mailtemplate

      Hello, Is it possible to delete or hide a standard e-mailtemplate? I would only like to show my own created e-mailtemplates to my staff. I only find a 'delete' option at my custom made e-mailtemplates, but the standard e-mailtemplates do not show this
    • Add values to Countdown Mode

      Is it possible to add values to the countdown mode drop down? The longest is 2 days. I would like values for 5 days, 10 days, 15 days...
    • RSS feed from a Zoho site blog?

      Does the Zoho Site blog have an RSS feed associated with it? I would like to have this picked up on a business Facebook page. thanks
    • Refresh token not appearing

      Hello, I was wondering if there is another way of obtaining a refresh token, as following the usual 60-second-code procedure generates a new access token, but not the refresh token, and so i have to repeat everything to get a new token every hour or so,
    • How would I collect a signature in person on Zoho sign?

      Suppose I have a customer show up at my office and we close a deal. I have an iPad ready to go, and I need to have the customer sign the document right there. How would I do it?
    • What's New in Zoho Analytics - June 2025

      Hello Users, We're delighted to bring you new features and enhancements designed to make your analytics experience smarter and more powerful than ever. AutoML Enhancements We’re thrilled to introduce powerful new AutoML enhancements, making machine learning
    • CRM Client scripts via extension?

      I've made a lot of industry specific customization to zoho CRM, using custom modules, workflows/automations, deluge scripts, api calls, and client scripting. I have had organic interest explaining what i've done to other small business owners in my industry.
    • How to import data via Excel for a multi-select lookup field?

      In the Accounts module, I have a multi-select lookup field to the Contacts module. When I import Accounts data via Excel, I want to enter the contact email address (which is used as the identifier) under the column name for the multi-select lookup field.
    • Need better way to tie Undeposited Funds to Invoice Payments to make it easy to reconcile Undeposited Funds account

      Hello, Request to have Zoho create tighter integration between Undeposited Funds and Invoice Payments.  Currently reconciling the undeposited funds account is a fairly tedious process for us.  Since the deposits and payments are just thrown into a "bucket"
    • Customized folder permissions in web Zoho WorkDrive won't apply to Sync

      Hi, within the 'Deals' macro-folder I created a folder for each Sales person (att. 1). Within each Sales person's folder a subfolder is automatically generated via function every time a new deal record is created in Zoho CRM, i.e. 1 deal record = 1 deal
    • What happens after trial period

      Dear Support, We are planning to use ZOHO CRM for our organization. We are now registered for a 15 days trial version. I would like to know what happens with our account and our data after these 15 days. Will it automatically change into a 'free' account
    • Forte's Extra Costs

      Hello everyone in the Zoho community, I wanted to share some information about Forte in case anyone wanted to look into them as a processor.  I currently use Stripe, but wanted to use Forte's ACH to pay vendors and take ACH payments for our products.  This is one of the only ACH processors that Zoho accepts. They state their cost is $25/month plus their transaction fees for ACH.  However, after signing up and going through their approval process, I found this out they work with a PCI compliance service
    • SEPA stripe vs gocardless

      Hi, we want to use Zoho Books - but as we are a company that is based in Germany we are using SEPA mandates. I know that its possible to use GoCardless - but the fees are extremly high (15 EUR fee for a 5000 EUR transaction). Is there any other way to
    • Zoho Commerce - Zoho Shop (Multilanguage)

      hi there we have a shop in zoho commerce, can I change the language in the shop, i mean, can I create a German and a French version, as an instance or something? If yes, how it works? thanks for your answers greetings prisca
    • French Tutorials

      Is there any Zoho projects tutorials, ebook, video or else in french? If so, where can I fin it please? Thx
    • My zoho mail has been disabled and cannot send email

      I’m the super admin for my company’s email accounts, but my own email address has been unexpectedly locked. I’m seeing the following error message: Could you please assist in unlocking my account so I can resume sending emails?
    • SMTP error

      I am using SMTP from Zoho the account is accounts@khlaklaeeb.com it was working fine then started to have Error and unable to delivery messages SMTP host SMTP.zoho,com SMTP user: accounts@khlaklaeeb.com SMTP port 465 PAssword: App Password it was working
    • Zoho Books Roadshows are back in the UAE!

      Hello there, Business owners and accounting professionals of the UAE, we’re coming to your cities! FTA accredited Zoho Books is now officially one of the Digital Tax Integrators in the UAE. With the newly launched direct VAT filing capabilities, we're
    • Automatically creating a ticket in Zoho Desk when an invoice is created in Zoho Books

      I need to find a way to create a ticket automatically (i.e. using workflow) in Zoho Desk whenever an invoice is created in Zoho Books. Please advise if there is a way of doing that?
    • Been getting this error, every now and then "Get count limit exceeded, please try again after 3 mins"

      it is really annoying.
    • Co-existing with Google Workspace

      We currently use GWS and due to legacy practices, we cannot migrate away from it. Not easily anyway. The issue we have is that while we have Zoho Mail, we get duplicate copies of emails. Our setup is that GWS is our primary. We have Zoho MX records in
    • Next Page