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

    • How do I associate pricebooks to a customer?

      I setup a few pricebooks, that worked fine. But now the only thing I can do with it, when I enter a quote or sales order, I can select which pricebook to use, but I have to do this product by product every time I add one. Is there a way to connect a pricebook
    • Zoho mail stopped receiving emails

      Our email are stopped to receive outsider email. i have checked the DSN, it's pointed to ZOho mail. Can anyone help me to fix this issue urgently? Thanks
    • send email from web application

      Hello, I'm experiencing an issue with sending emails from my web application. Here are the configuration parameters currently in use: ini Copia Modifica quarkus.mailer.from=noreply.sedis@mondonovo.net quarkus.mailer.host=smtp.zoho.com quarkus.mailer.port=465
    • Custom CSS in Zoho Form

      Hi, Please let me know, how we can add custom css in Zoho Form.  Thanks
    • Zoho Recruit

      Getting this issue
    • Missing Email

      We recently started using ZohoMail we migrated our users from google workspaces. The migration process seemed to have gone smoothly however not all emails are showing in the inbox folder. For example: If I sort the inbox folder from old to new. (Oldest
    • Client Script Quality of Life Improvements #1

      Since I'm doing quite a bit of client scripting, I wanted to advise the Zoho Dev teams about some items I have found in client script that could be improved upon. A lot of these are minor, but I feel are important none-the-less. Show Error on Subform
    • Account blocked after accessing via VPN

      All my accounts are blocked after using a VPN. I have submitted multiple support tickets without response. It’s critical that my email be restored asap Can you please provide a way to unblock my accounts
    • Exchange Rate Updates

      Hi, It would be great that when you work with multiple currencies, the exchange rate updates automagically every day (as seen on Zoho Books) or at least that when you create/update an opportunity the exchange rate could be manually updated, or maybe both!
    • Courses without signup

      Can I create "real" public courses where no signup is needed?
    • Espace Sandbox – Votre environnement de test sécurisé dans Zoho Projects

      Zoho Projects propose un sandbox sécurisé pour tester des configurations, des personnalisations et des modifications sans compromettre les données en production. Note : Disponible avec le plan Enterprise le plus récent basé sur les utilisateurs (y compris
    • Descargas en learn

      Buenos dias, yo en mis cursos para no tener que cargar los archivos que utilizare en las lecciones decidi utilizar la opcion de bloques para añadir un enlace de mi workdrive con el video que deseo para que sea todo mas organizado, pero hay un problema.
    • Mail delivery

      I initially had a problem sending any outgoing mail and was able to fix it on my own, given Zoho support never got back to me. However, despite being able to send emails now, none of my mail to different Gmail addresses are arriving, and they are not
    • Mermaid Support & Zoho Learn

      Hi Zoho Team, I’m currently working with Zoho Learn and was wondering if there’s any way to add support for Mermaid syntax to create flowcharts, sequence diagrams, and other visual elements within articles or lessons. Mermaid is widely used in technical
    • Blocked due to VPN

      Hi My account outgoing mails and IMAP access have been blocked due to using a vpn being interpreted as suspicious logins. I’ve tried to mail support but not sure if this is also blocked. This is extremely frustrating as I’m using a vpn because I’m travelling
    • reset admin access.

      I am a user under the domain @lanutraceuticals.com. I do not have admin access. Kindly let me know the administrator contact or help me reset admin access.”
    • Unsubscripation booked domin

      Kindly Un subscription booked domain
    • How to change Super Admin

      Good Day, Can someone kindly guide me on how to change the super Administrator. I have tried many times but could not succeed.
    • Events disappearing in Calendar

      To reproduce the bug: 1.- Add a new event in Calendar 2.- Type any name for the Event 3.- Click "Create" 4.- The event appears 5.- Click on the event to open it 6.- Optional: Edit the event 7.- Click OK 8.- After two seconds, the event disappears Now, click on another day and then come back to the inserted event's day. The event appears.
    • Mail transfer to a contact with multiple accounts

      Hi, Since we can only associate one email for a Contact across Zoho, would it be a problem if we want to merge our mailbox in the future? For example, Mr. Jones is the main POC for 5 accounts, once we merge our mail where would the messages go-- is it
    • @mention not working in Mail

      Am I missing something? When trying to forward a message there is a hint you could do this also by "@mention" at the end of the message. When typing (for example) "@s.." there should appear addresses from my contacts, shouldn´t it? But nothing happens! So what can I do? Best regards and thanks for any help in advance! JH P.S.: Sorry for my bad English.
    • Enable Zia-Powered Deluge Assistance and AI Agent Without Mandatory OpenAI Integration

      Hi Zoho Creator Team, Hope you're doing well. We’d like to request a feature enhancement related to Zia's AI capabilities in Zoho Creator, particularly regarding Deluge Assistance and the AI Agent. Currently, as shown in your documentation (Generate Deluge
    • Zoho Sign community meetup series - India

      Hello everyone! Zoho Sign is a comprehensive digital signature application tailor-made for Indian businesses with unique features like Aadhaar eSign, eStamping, USB/PFX signing. We are now excited to announce our first meetup series for Zoho Sign in India,
    • Product Updates in Zoho Workplace applications | June 2025

      Hello Workplace Community, Let’s take a look at the new features and enhancements that went live across all Workplace applications this June. Zoho Mail Slideshow view for inline images in Notes View all your inline images added in a notes in a effortlessly
    • Assign multiple vendors to the same product

      Guys, My business often purchase the same product from several vendors (based on price and availability). Is it possible to assign more than one vendor to the same product? I saw this same question in this forum, from some time ago. Is this feature available or, at least, in Zoho's roadmap? If not, is there any trick to solve my problem? Without this feature, I simply cannot manage my company's inventory, limiting very much the use of Zoho CRM. Waiting for your reply. Leonardo Kuba Sao Paulo / Brazil
    • Is there as way to shut off the invitation when you set up a new user?

      Is there as way to shut off the invitation when you set up a new user?  I would like to get all my users in the system, my org structure set up and tested, etc, BEFORE I invite the users.  I did not see a way to shut of the automatic invitation email.  The only way to get around it is to set up the users with no Email ID.  However, when you do that - you get into the problem of not being able to update a user's Email ID (which makes NO sense whatsoever).  If I set up a user with an incorrect email
    • Manage Engine login issue

      App not available The app you're trying to access isn't yet available in the in data center region, where your account is present. To use ManageEngine, you can sign up for a new account in another data center region. Learn How Go to Zoho accounts Please
    • Zoho Creator - users "Name" Column

      Hi, When you add user to an application inside Zoho Creator, the system generate an account name for it. We don't have the  ability to change this name. According to Zoho creator Support (Case:11523656) : "The values displayed under 'Name' column of 'Users & permissions' section, is actually the respective account's username and not the actual name specified on the account. Usernames are system designated based on the account email address and cannot be modified from your end." We need to have the
    • Zoho Assist Unattended - devices disappearing

      Hello, I've recently introduced a new model of laptops into our environment (Lenovo Legion). We are experiencing an issue where only the latest installed agent - laptop is visible in Assist. This issue does not appear with our Dell inventory. Example:
    • Searchable email tab in Bigin

      Hi team, Could I please request a feature update, to be able to search emails within the email tab of Bigin. We have large correspondence with some agents and it would be very helpful if we are able to search from this section:
    • The silent force behind great customer service

      Customer service is known to be a demanding role. Customer service agents are expected to bring empathy, clarity, and human connection to every voice call, chat, and remote session, even if the situation requires some time for customers facing stressful,
    • New From Email in Zoho Desk

      Dear ZohoSupport, We are trying to establish a new From Address in Zoho Desk but we are facing difficulties. When trying to use the smtp.office365.com SMTP Server, after clicking the Save and Verify button, the Authentication Failed error pops up although,
    • Option in pipeline deal to select which hotel or branch or store if client has more than one local store

      Hi, I would like to know if there is an option in the deal pipeline to select which hotel, branch, or store a deal is related to—if the company has more than one location. For example, I have a client that owns several hotels under the same company, and
    • Aggregate SalesIQ Knowledge Base Interactions into Zoho Desk Knowledge Base Dashboard

      Hello Zoho Desk Team, We hope you're doing well. We’d like to request a feature enhancement related to the Zoho Desk Knowledge Base dashboard and its integration with Zoho SalesIQ. 🎯 Current Limitation When customers interact with knowledge base articles
    • Add Prebuilt "Partner Finder" Template with Native Zoho CRM Integration in Zoho Sites To: Zoho Sites Product Team

      Hi Zoho Team, We hope you're doing well. We would like to request a prebuilt "Partner Finder" template for Zoho Sites, modeled after your excellent implementation here: 🔗 https://www.zoho.com/partners/find-partner-results.html ✅ Use Case: Our organization
    • Admin Visibility and Control Over Group Chats in Zoho Cliq

      Hello Zoho Cliq Team, We hope you're doing well. While we appreciate the current capabilities in Zoho Cliq — including the ability to restrict who can create group chats and configure user permissions — we would like to request several enhancements to
    • Update Regarding Zoho Finance Applications' Domains For API Users

      Hi users, Until now, both the Zoho Finance apps and their APIs shared a common domain. We've recently introduced separate domains for APIs. You can now start using the new domains for API calls. The old domains will not work for API users starting April
    • Ability for Agents to Initiate Voice Calls With Site Visitors Without Active Chat Session

      Dear Zoho SalesIQ Team, Greetings, We would like to request a feature enhancement related to the voice call functionality in Zoho SalesIQ. Current Limitation: At the moment, voice calls can only be initiated by agents after a chat session has been started
    • Add new Card

      How do you add a new credit card to a contact with Zoho API as can be done on web.  I am not able to find way to do this with Books API, CRM API or Subscriptions API.  This is an issue for our company as we do migration from a different system.  I can add card to a subscription through Subscriptions API, but some of our customers may not have a subscription, but only invoices set up in Zoho Books.  Is there any way in Zoho API to add new credit card to contact/customer?
    • Benchmark for Using Mail Merge in Service Order Scopes

      Hello, I was wondering if Zoho CRM has a benchmark or best practices for utilizing Mail Merge in service order scopes. Specifically, I'm looking for guidance on how to effectively integrate this feature for creating and managing service orders, especially
    • Next Page