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

      • Please add custom sort in Windows ver. of Notebook!

        Dear Zoho, I love the custom sort (drag and order notes) in the Android version of Notebook, but when I sync onto the Notebook on Windows, the note orders all get messed up because it doesn't support custom sorting yet. This makes it impossible to do
      • Unveiling Zoho CRM's New User Interface - The NextGen UI

        Hello Everyone, Last Wednesday, May 14th,2025, we announced the public release of Zoho CRM For Everyone, our most significant update yet. This release brings a modernized CRM experience with a redesigned user interface, new capabilities for cross-functional
      • 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,
      • How to get custom estimate field to display on existing or new services?

        I am using FSM. I recently added a new custom field to Service Details to help categorize my services. I can see the newly added field as a column on the service list view. However, when attempting to update an existing or create a new service, I don't
      • Unable to add estimate field to estimate template

        I have the field "SKU" as part of my service data. I can also see it as a column when displaying the list of services. However, I have no way to include it on my estimate template because the field is not showing as a column field to include for the service/part
      • Pivot Table - Zoho Analytics

        I'm creating a Profit and Loss chart in Zoho Analytics using the Pivot Chart feature. While Net Profit can be calculated using the total value, I also need to calculate and display the Gross Profit/Loss directly within the chart. To do this, I need to
      • Including attachments with estimates

        How can attachments be included when an estimate is sent/emailed and when downloaded as a .pdf? Generally speaking, attachments should be included as part of an estimate package. Ultimately, this is also true for work orders and invoices.
      • Add Hebrew Support for Calendar Language in Zoho Forms

        Dear Zoho Forms Team, Greetings! We are using Zoho Forms extensively and appreciate its versatility and ease of use. However, we’ve noticed that the Calendar Language settings currently do not include Hebrew as an option. We would like to request the
      • Ask the Experts 20: Level up your Business with Zia

        Hello everyone! We're excited to reconnect with you again. The recent sessions of our Ask the Experts series have contributed to valuable conversations, beginning at the live sessions and evolving into one-on-one conversations and sessions where we've
      • 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
      • Ability to Remove/Change Zoho Creator Admins via Zoho One Interface

        Dear Zoho One Team, Greetings, We would like to request a feature enhancement in Zoho One. Currently, it is not possible to remove or downgrade a user with the Admin role in Zoho Creator from the Zoho One admin interface. Unlike other Zoho apps where
      • Zoho CRM Developer Series - Queries

        Hey everyone! We’re excited to invite you to our next Zoho CRM Developer Series focused on Zoho CRM Queries, happening on June 5, 2025 and June 26, 2025. Whether you're working on CRM customizations, integrating with third-party services, or just curious
      • Announcing Zoho Community Developer Bootcamps in India – Extensions

        Hey everyone! We're back with another line-up of Zoho Community Developer Bootcamps in India! Following the success of the first leg of bootcamps on Extensions, we're now ready with the second leg. These bootcamps focus on empowering developers of all
      • Company centric layout

        Hey everyone, I want to have an "account-centric" Zoho, where the main part is the "Account" and other parts like "Contacts", "Deals", "Projects" are linked to this "Account". Tricky part is, that I have different layouts for different departments, and
      • 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
      • Announcing Zoho Community Developer Bootcamps in India – Catalyst by Zoho

        Hey everyone! Following the success of the first set of bootcamps on SalesIQ Zobot and Extensions last year, we're ready for the next set of bootcamps—this one dedicated to Catalyst by Zoho! These bootcamps are aimed to empower developers to build, scale,
      • Global Fields

        Just like Global Sets for Picklists, we would like to have global fields for any kind of field. Three things that should be saved globally: 1. The Existence of the field 2. The Name and 3. Association with a module should be set up in a respective place
      • Introducing the Zoho Show Windows app

        Hello everyone! We’re excited to announce the launch of the Zoho Show app for Windows! You can now create, access, collaborate on, and deliver presentations right from your desktop. The Windows app brings you all the powerful features you’re familiar
      • Renew an expired subscription

        Hey Zoho officer, My subscription was expired yesterday, but I did not notice until just now. How can I renew the subscription even it is expired? The website is really important for our publicity. So I hope I can still review the domain and website. Thanks!
      • New Action Requests

        Hi, Is there any chances to get the new actions requested at all? I have made a few requests but never heard back from Zoho about them. I assume that developing them take time but is there any support that can provide some update? Thanks
      • Pre-fill webforms in Recruit

        I don't want to use the career site portal (as I have my own already), but I would like to direct users to the application forms for each role, from my website job pages. Is there a way to pre-fill fields in Recruit application forms, so that I only have
      • [Webinar] Deluge Learning Series - AI-Powered Automation using Zoho Deluge and Gemini

        We’re excited to invite you to an exclusive 1-hour webinar where we’ll demonstrate how to bring the power of Google’s Gemini AI into your Zoho ecosystem using Deluge scripting. Whether you're looking to automate data extraction from PDFs or dynamically
      • Does Thrive work with Zoho Billing (Subscriptions)?

        I would like to use Thrive with Zoho Billing Subscriptions but don't see a way to do so. Can someone point me in the right direction? Thank you
      • Workdrive - copy permissions

        I am trying to customize sub folder, which I understand fully from below https://help.zoho.com/portal/en/kb/workdrive/team-folders/manage/articles/customize-folder-permissions-in-a-team-folder#Customize_permissions_during_folder_creation However I want
      • Latência

        Estou com bastante latência 200ms em São Paulo Brasil para o endereço mail.zoho.com, e email demora para carregar as vezes trava como está por ai ? segue print sabem se é normal ? ping
      • US military addresses

        When we have a client with a US military address having them fill in a form is a problem Zoho forms doesnt acommodate them correctly. It doesn't make sense for me to have to create a secondary data model for military addresses. I have placed some links
      • US military addresses

        When we have a client with a US military address having them fill in a form is a problem Zoho forms doesnt acommodate them correctly. It doesn't make sense for me to have to create a secondary data model for military addresses. I have placed some links
      • BANK FEED - MAYBANK , provider from YODLEE IS NOT WORKING

        As per topic, the provider YODLEE is not working for the BANK FEED. It have been reported since 2023 Q3, and second report on 2023 Q4. now almost end of 2024 Q1, and coming to 2024 Q2. Malaysia Bank Maybank is NOT working. can anyone check on this issue?
      • Introducing 'Previous' and 'Next' operators for enhanced date-based filtering

        Hi everyone, We are excited to introduce to you two new operators - Previous and Next - for your date and date time fields in filters as well as in custom view. For starters, let’s say you want to filter records based on Created Time: Previous 6 months:
      • Same users on different accounts

        I have an issue I need help with. Whilst trialing ZOHO CRM I created the following: Account1 using myname@myorganisation.com.au and 2 personal emails Account2 using a personal email and 2 users sales1@myorganisation.com.au and sales2@myorganisation.com.au
      • Rich-text fields in Zoho CRM

        Hello everyone, We're thrilled to announce an important enhancement that will significantly enhance the readability and formatting capabilities of your information: rich text options for multi-line fields. With this update, you can now enjoy a more versatile
      • Multi-Sort Functionality, Projects List

        It is proving so hard for us to manage any kind of decent view into our Active list of projects (which now hovers between 150 and 225 at a time).  In addition to my other suggestion here (which hasn't had any activity in a year), I'd like to suggest that
      • Subform dynamic fields on Edit, Load of Main form.

        Main Form: Time_Entry Sub Form (separate form): Time_Entries Time_Entries.Time_Entry_No is lookup to - Time_Entry.Time_Sheet_ID (auto number). I would like to disable some of the subform fields upon load (when edited) of the Time_Entry main form. What
      • Power of Automation :: Automatically update the Work hours of a task based on Custom field Value

        Hello Everyone, A custom function is a software code that can be used to automate a process and this allows you to automate a notification, call a webhook, or perform logic immediately after a workflow rule is triggered. This feature helps to automate
      • Is it possible to set create deal checked by default when converting a lead?

        In our company whenever a lead is converted we make a deal. It is a pain to have to check the box every time. I would prefer if it was just a default behavior and the box wasn't even there. But it would be fine if the box could be checked by default.
      • Important! ZipRecruiter Sponsored Posting Plan Changes in Zoho Recruit

        Greetings, We’re reaching out to inform you about an important upcoming change to the ZipRecruiter Sponsored job board integration within Zoho Recruit. What’s Changing? Starting June 1, 2025, Zoho Recruit will be updated with ZipRecruiter's latest pricing
      • Zoho Sites is unusable

        What a terrible user experience sites is buggy and incredibly slow with creating site.  it hangs with please wait with spinning circle A LOT.  can't add blog page  can't add logo (yes it's not larger than 500 pixels) can't even add a new page It either does nothing (with no error message as to what is wrong) or you get the darkened screen with the please wait with the spinning circle that never goes away...I've even left it for 5minutes or more just to see if it was slow or just doesn't work...and
      • What's New in Zoho Inventory | January - March 2025

        Hello users, We are back with exciting new enhancements in Zoho Inventory to make managing your inventory smoother than ever! Check out the latest features for the first quarter of 2025. Watch out for this space for even more updates. Email Insights for
      • Why the home page "Income and Expense" graph only shows some Expense Accounts but not all

        I see that the graph only shows expenses from some Expense Accounts. Why and how can I change that? I'm new to Zoho Books and accounting. Thank you!
      • Introducing Seamless Communication with WhatsApp Integration in Zoho Recruit

        Hello everyone, We are thrilled to announce that we have just launched an incredible new feature in Zoho Recruit that will revolutionize your recruitment process. With the integration of WhatsApp into Zoho Recruit, you can now seamlessly connect with
      • Next Page