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


    Nederlandse Hulpbronnen


      • Recent Topics

      • Este domínio já está associado a esta conta

        Fui fazer meu cadastro na zoho e quando digitei meu domínio recebi essa mensagem que meu domínio estava associado a uma conta que eu nem faço idéia de quem seja. Como que faço pra resolver isso? Atenciosamente, Anderson Souza.
      • USA Military addresses

        When we have a client with a US military address adding them to the CRM, or having them fill in a form is a problem. Zoho Forms and CRM doesn't seem accommodate them correctly. It doesn't make sense for me to have to create a secondary data model for
      • Canvas View Change History

        We are trying to setup Canvas Views and it is really not a pleasant experience. It bugs a lot, some pages are just not accessible anymore and it shows that a view is just not editable because it shows a blank page, although when we open an actual record,
      • Office 365 is marking us as "bulk"

        All of a sudden (like a couple of days ago) all of our customers who are on Office 365 are getting our mails in their junk email. This is not the case with Gmail or other random mail servers, nor between us. We got a 10/10 score on mail-tester.com. Also,
      • Zoho CRM's V8 APIs are here!

        Hello everyone!!! We hope you are all doing well. Announcing Zoho CRM's V8 APIs! Packed with powerful new features to supercharge your developer experience. Let us take a look at what's new in V8 APIs: Get Related Records Count of a Record API: Ever wondered
      • Leadchain BUG

        Hello i have a problem with Facebook Leadchain. All of the information is populated correctly in the CRM, except the campaign. I want to add new leads to an existing campaign, but the lead is not added to the campaign even tough i have selected the campaign
      • What is the use of the stage environment ?

        Salut, I am woundering what is the use of the stage environment. Usually, I do all the testing in developpement, and then go straight to production. The only thing I cannot test in developpement, is the result for portal users. Could the stage environment
      • Workflow Automation Instant Action

        Hello All I need help to resolve this. I have created a few workflow 1. When Deal Stage is Submitted to Onboarding, it will create a record in my Onboarding Module 2. When Deal Stage is Live, It will copy $Deal.GOliveDate to $Onboarding.GoLiveDate For
      • Live webinar: Transitioning from MS PowerPoint to Zoho Show

        What’s the first word that comes to mind when you think of presentations? For many, it’s PowerPoint. This has been the default for so many years that “PPT” has become a stand-in for “presentation.” But presentation needs are changing. And if you’re looking
      • Short Custom Order

        Hi Everyone, I have question, i create some report use custom short order like below. But this is just show in development mode.... when i publish to production, it is not showing. And this is just showing in full admin mode. Can setting to show roles
      • Introducing Keyboard Shortcuts for Zoho CRM

        Dear Customers, We're happy to introduce keyboard shortcuts for Zoho CRM features! Until now, you might have been navigating to modules manually using the mouse, and at times, it could be tedious, especially when you had to search for specific modules
      • Assistance with Bulk Contact Import in Zoho Email Campaign

        I’m currently in the process of importing the Supermarkets customer list from Zoho Accounts into Zoho Email Campaigns. During the import, I’m being prompted to complete the "field mapping" section, but I’m unsure how to properly configure it to ensure
      • Introducing Zoho CRM for Everyone: A reimagined UI, next-gen Ask Zia, timeline view, and more

        Hello Everyone, Your customers may not directly observe your processes or tools, but they can perceive the gaps, missed hand-offs, and frustration that negatively impact their experience. While it is possible to achieve a great customer experience by
      • Variables in Zoho Mail Signatures defined by Administrator

        Good afternoon, I'm looking at the Admin component of Zoho Mail, and I see we have the capability to define signatures for end users. We also have the ability to associate with multiple email addresses. Are we able to use any variables such as [FirstName}
      • 533 Relaying disallowed

        When I try to send an email from my Zoho account, it gives me that error 533: relaying disallowed. What should I do? Please help.
      • Custom view placeholders

        Hi all, On some occasions it would be great to have placeholders setting up a custom view. Example in our case we have a field for a year. We would like to have a placeholder like $.{CurrentYear} that will insert the current year 2025 e.g. Now we have
      • Article Numbers for KB articles

        Hello, I was wondering if it's possible to turn on article numbers/ part numbering for KB articles. If this is not already a feature, we'd like to request it. Frequently a solution will require multiple articles so tracking which articles are referenced
      • Add Subform Field based on Record Field

        Hi All, I am struggling with finding a solution that can populate a subform field based on an existing field on the record. Use case is I have added Current Exchange Rate on a quote as a custom field, I then have a subform with Quoted items that include
      • Sales Order automatic Convert to Invoice using boolean True or false

        It is possible to convert the Sales order to an invoice using a boolean field, true or false Example: I create a field in my Sales Order, I name it QBO Invoice, and the field type is Boolean, true or false. Let's say the default is false, so when I change
      • Leadchain into a custom module

        Hello ZOHO Community ! is it possible to put the leads collected by leadchain into a custom module instaed of leads module ? Best wishes Niels
      • Should I save dead quotes

        I work in vehicle transport, specializing in transporting vehicles for dealerships. My role involves collaborating with individuals at each dealership to facilitate the transport of their vehicles to customers and from auctions. My question is whether
      • 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
      • MULTI-SELECT LOOKUP - MAIL TEMPLATE

        Dear all how are you? We need to insert data from MULTI-SELECT LOOKUP in a email template, but I can't do that, when I'm creating the template I can't find the field to insert it. is there any solution? PVU
      • Canvas translation

        We want to offer our CRM system to our users in English and Dutch. However, it seems that text in our deal Canvas isn't available for translation through the translation file. The same applies to the field tooltips. They don't appear in the translation
      • Create Full-data sandbox now in ZOHO CRM

        Full-data Sandbox feature is being released in a phased manner, and is currently accessible to users of the CN data center (China Region). Hello everyone, We're thrilled to introduce the full-data sandbox for Zoho CRM's Ultimate Edition—the ultimate testing
      • How to normalize CRM module when integrating with Survey?

        This question is about the problem with many-to-many relationships and Survey. One of the things our organization does is track people in our program and their jobs. We get new information from the people three times annually through Zoho Surveys. Survey
      • MS Teams for daily call operations

        Hello all, Our most anticipated and crucial update is finally here! Organizations using Microsoft Teams phone system can now integrate it effectively with Zoho CRM for tasks like dialling numbers and logging calls. We are enhancing our MS Teams functionality
      • Introducing Rollup summary in Zoho CRM

        ------------------------------------------Moderated on 5th July'23---------------------------------------------- Rollup summary is now available for all organizations in all the DCs. Hello All, We hope you're well! We're here with an exciting update that
      • 553 relaying disallowed invalid domain

        Hi, I have read the previous article but i am still facing issue , I have added all these in my domain manager under dns settings. type : cname host: zb14521202 value / points to : validate.zoho.com Can you please tell me why i am still facing same issue
      • For security reasons your account has been blocked as you have exceeded the maximum number of requests per minute that can originate from one account.

        Hello Zoho Even if we open 10-15 windows in still we are getting our accounts locked with error " For security reasons your account has been blocked as you have exceeded the maximum number of requests per minute that can originate from one account. "
      • Try CRM for everyone button in the way of workflow

        Please consider using the bottom bar for offers. Using the top bar for offers like "Try CRM for everyone" really gets in the way of my day to day workflow.
      • Free live online training from Zoho Bookings

        Hi everyone! Whether you’re just getting started or have been using Zoho Bookings for a while, there’s always something new to learn. That’s why our product experts are hosting a free live training session to help you optimize appointment scheduling for
      • CRM HAS BEEN SOOO SLOW For Days 05/15/25

        I have fantastic Wifi speed and have zero issues with other websites, apps, or programs. It takes an excruciatingly amount of time to simply load a record, open an email, compose an email, draft a new template, etc. Am I in a subset/region of subscribers
      • Zoho Desk Validation Rule Using Custom Function

        Hi all, I tried to find the way to validate fields using custom function just like in Zoho CRM but to no avail. Is there a way to do this?
      • Invalid URL error when embedded sending url into iframe for my website when using in another region

        Hi team, My site is currently working on integrating your signature feature as part of the system functionality, it's working great but recently there's been a problem like this: After successfully creating the document, i will embed a sending url into
      • Validation Rules Trigger on Untouched Fields

        In Zoho Desk, validation rules trigger for ALL fields during an update—even fields that weren't modified in the current edit. This behavior is fundamentally different from Zoho CRM and other Zoho products, where validation rules only apply to fields actually
      • One notebook is on my Android phone app, but not on Web or PC app.

        This problem started in stages. At first my phone was occasionally failing to sync. Then I noticed two things added to my Phone App. One was an existing notebook had a new cover, and the other was a new Note Card with an odd text in it. These were only
      • Holding Shift to keep selected tickets

        It is annoying trying to change the category of tickets and then closing them. You have to select them one by one, no way to 'hold down left click and drag your mouse down to select multiple'. Once you have selected them and you change the category, you
      • Custom module history is useless

        Hi I am evaluating ZOHO DESK as my support platform. As such I created a few custom modules for devices assigned to employees. I want to be able to see the whole picture when a device was reassigned to someone, but the history shows nothing Is there any
      • Removed email address - can't access account

        Hi Zoho Support Team, I recently removed my email address from my Zoho Desk account (which is part of our organization's Desk setup) and then signed out. Now, I’m unable to log back in because there is no email address associated with the account, even
      • Next Page