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

    • I'm looking for a Microsoft List alternative in Zoho One to manage large lists of repetitive tasks

      I've used Microsoft Lists to manage lots of tasks that need to be completed several times for different users. We started with a large spreadsheet and then discovered lists, which worked pretty well. I was wondering if there is a similar products in Zoho,
    • Zoholics Europe and UK Awards 2025: Honouring our loyal customers!

      We're excited to announce that at this year's Zoholics events across Europe, we're holding customer awards for the first time ever! This is your chance to shout about the amazing things you've created, connected, or achieved with Bigin! And if you win,
    • Fillable template with dynamic tables?

      Is there a way to build a fillable template so that users can add rows to a table? To describe what I'm trying to accomplish the table has 3 sections; a header row, some number of rows with custom information, and a summary row with totals. I can't figure
    • How to store API keys in zoho?

      Hi everyone, I'm currently building an integration using Zoho Flow and I need to securely store several API keys that will be used to make external service calls from my flows. I would not like to hardcode the values in the code of custom function. What's
    • Zoho RPA is now available in your Zoho One bundle!

      Hello All! Of late, it's been quite a stint of new app integrations in Zoho One. This announcement pertains to the addition of another Zoho application, the most sought-after Zoho RPA - Robotic Process Automation, to the bundle. What is Zoho RPA? Zoho
    • is there an easy way to embed a zoho analytics report into a widget (or inside the "account" page) of Zoho CRM

      Hi, I have built a report that is specific to an account in Zoho CRM but I would like this to be built into the Zoho CRM front-end. I have looked at the widget concept but it seems quite complicated (see attached screenshot but I need to filter this view
    • Bigin iOS app update - Introducing Card Scanner and initiating WhatsApp conversations using pre-approved templates.

      Hello everyone! In the latest iOS (v1.11.3) version of the Bigin app, we have introduced the following features: Card Scanner Initiating WhatsApp conversations. Card Scanner: Our new Card Scanner feature extracts contact information from business cards.
    • Introducing card scanner in Bigin Android app

      Hello everyone! We are excited to introduce the card scanner feature on the latest Android version(1.7.26) of the Bigin app as well. Card scanner extracts contact information from business cards and allows you to save them as contacts in Bigin. You can
    • Full RTL and Hebrew Translation Support for Zoho Creator User Portal (Including All System Pages, Templates, and MFA Screens)

      Dear Zoho Creator Team, We kindly request comprehensive support for right-to-left (RTL) languages, particularly Hebrew, across the entire Zoho Creator user portal. This includes system-generated pages, templates, and multi-factor authentication (MFA)
    • ZUG real estate virtual meetup 2025: Sign documents, collect payments, and automate workflows with Zoho Sign

      Hi there! Are you in real estate and looking for a secure, compliant way to manage all your paperwork? In such a fast-paced industry, timing, compliance, and client trust are everything. Handling paperwork has always been a challenge, whether you're finalizing
    • OCR (Optical Character Recognition), automatisation des PDF et autres améliorations de Zoho RPA

      Zoho RPA est une plateforme d'automatisation des processus robotiques conçue pour accélérer et simplifier vos workflows. Elle permet de connecter facilement vos applications cloud à vos systèmes existants, même ceux qui ne disposent pas d’API, afin d’automatiser
    • 📞 Call + 💬 WhatsApp + 📲 SMS in Zoho CRM – All in One Place!

      We’re excited to introduce HelloSend, a powerful communication extension for Zoho CRM that brings SMS, WhatsApp, and Voice Calling directly into your CRM workspace. Whether you're in sales, support, or service delivery, HelloSend helps you connect with
    • Automation#24: Auto-Update custom field from Accounts to Tickets

      Hello Everyone! Welcome back to the Community Learning Series! This episode dives into how Zylker Techfix streamlines account-related ticket references. Previously, employees had to manually check account details to retrieve specific customer information,
    • Product Updates in Zoho Workplace applications | May 2025

      Hello Workplace Community, Let’s take a look at the new features and enhancements that went live across all Workplace applications this May. Zoho Mail Increased Preset Limit for Reminder and Snooze Options Preset limits for the Reminder and Snooze options
    • Outlook 365 ('classic') won't connect to Zoho email

      New computer, fresh install of Office desktop. On the old computer Outlook was working fine with Zoho, retrieving/sending mail, etc. On the new one I can't connect the accounts in Outlook--Outlook just keeps popping up the box asking for a password. All
    • login email

      Never logged into email says last log in never loged into
    • Installment plans

      Hi I am looking for a way to allow my customer to make equal monthly payments. For instance if I create an invoice for customer Y for $1000 I want to allow them to make equal monthly payments for the next 6 months. I need those payments to be auto charged
    • Search Mail with URL parameters

      Is it possible to search Zoho Mail by passing URL params like we can in Gmail? eg. mail.google.com/mail/u/0/#search/from:(jane@doe.com)
    • Need Help Fetching Latest Conversion Rate by Date

      Hi Team, I’m currently working on building a Balance Sheet in Zoho Analytics across different entities, with a common base currency of USD. I receive USD conversion values on a daily basis, and my requirement is to always capture the most recent available
    • Enhance Zoho One Conditional Assignment to Fully Reassign App Settings When Changing Departments

      Hi Zoho Team, We’d like to submit a feature request regarding the current behavior of Zoho One’s conditional assignment logic when moving a user between departments. 🔧 Current Limitation As it stands, Zoho One’s conditional assignment does not remove
    • Category to Alert

      Hi I am looking for help on how to solve an issue. We use the Category field for all items. We also use Composite Items. We would like to create an email alert when a Sales Order is created, however it would need to look at the Item to identify the category
    • Validation Rule (Date)

      Hi There,  Can any anyone help me with the validation rule? I'm trying to fire a rule whereby the End Date cannot be before Start Date.  Any takers?  Manoj Nair
    • Beyond Email: #3 Organize effortlessly with Bookmarks

      With her team’s details now neatly saved under Contacts, Sarah is feeling more settled in Zoho Mail. As she begins exploring her new workspace, she remembers the collection of useful links she has saved on her browser—project trackers, client portals,
    • Notification based on created/updated sales order that contain certain line items.

      Hi, I am finding the workflows within Books somewhat difficult to setup, so I am thinking that a custom function may be the best way to go about this. I want to be able to send a notification to a team member that any sales order that has been created
    • Drawings in forms

      I do a lot of drawings during my consultations and I’d like to add  body maps or stencils that I can draw on in different colours and add explanations etc. I need to be able to erase mistakes etc. Ideally in a form that I can prepopulate with client details and a few questions/ client signature and then save as a form. is this currently possible? if not, is it in the pipeline? thanks, Dennis
    • How can I populate dropdown data with information from another source or app?

      I want to maintain a list of items in another app (say in excel or another database) and sync those as items in a drop down menu, instead of copy pasting to import. Is this kind of a feature available?
    • Workplace - Zoholics Europe Customer Awards

      Dear Zoho Mail Community! 📣 We're excited to announce that at this year's Zoholics events across Europe, we're holding customer awards for the first time ever! Workplace - Zoholics Europe Customer Awards This is your chance to shout about the amazing
    • Zoholics Europe Customer Awards

      Dear Zoho Workplace Community! 📣 We're excited to announce that at this year's Zoholics events across Europe, we're holding customer awards for the first time ever! Workplace - Zoholics Europe Customer Awards This is your chance to shout about the amazing
    • Change Default Currency in Zoho Reports

      Is it possible to default all currency fields in my Reports and Tables to my local currency without having to reformat them every time?
    • [Webinar] Deluge Learning Series - Master Conditional & Operational Logic in Zoho Deluge

      We’re excited to bring you the next session in our Deluge Learning Series—a focused one-hour webinar where you’ll level up your skills in conditional and operational logic using Deluge scripting. From writing clean if-else conditions to implementing powerful
    • UPI QR Code in Invoices

      Hi, It would be easier to make payment, if UPI Qr code is generated by Zoho Books and shown in the invoice itself.  This will promote digital payments and also makes it easier for customers to pay. It would be even helpful, if QR code contains the invoice
    • WebDAV support

      I need WebDAV support so that I can upload/download (and modify) documents from my local file system. Is anything planned in his direction?
    • Recurring Events Not Appearing in "My Events" and therefore not syncing with Google Apps

      We use the Google Sync functionality for our events, and it appears to have been working fine except: I've created a set of recurring events that I noticed were missing from my Google Apps calendar. Upon further research, it appears this is occurring
    • Zoho Inventory Item History

      Hi Zoho Inventory Team, I 've been testing the History feature on Inventory Items in a demo system and I noticed that when I changed the value of a field to a new value, the history just says "updated by - user1", it doesn't say what what field was changed
    • Filter Images in Work Drive

      Hi, what is the best way to be able to filter files by multiple descriptions, for example, the name of a person in the photo as well as, an item in the photo and other descriptions? With labels it looks like you can only select one label at once but this
    • Flow not working when trying to Create a Merged Doc with info from a custom CRM module w/ subform

      I am having a problem creating a flow that gets its info from a webhook connected to a button in a custom module in Zoho CRM. I have made a template in Writer that follows: This is a clone of  the template in the CRM mail merge which works perfectly if i do it manually through there. My flow gets the custom module entry id through a webhook, then fetches the module entry data, and creates a merge document from that data. I know the webhook and the fetch work because if i replace the "create merge
    • Smart Scheduling via Agent Confirmation

      We’re excited to introduce a smarter and more streamlined way to manage dispatched service appointments in Zoho FSM! Feature Highlights Field agents can now approve or reject service appointments assigned to them—helping reduce unnecessary workload and
    • How to delete Inactive users?

      We want to delete inactive users from our system, but went you deactivate still the names are shown at the inactive section. How to get really rid off these names? Thanks for your response! Fabian van den Barselaar
    • Help me format my signature in zoho mail

      I need to set up my signature in zoho mail then send the format to other colegues to set it up by themselves. I have isues setting up my 5 logos one after another as I am not able to give sapce between logos. After setting up my signature with logos there
    • Can i integrate bigin with google voice?

       I make all my calling through google voice to seprate my personal line from business. I want to log my calls with customers automatically but i domt see anywhere where i can do that. Any help? Im pretty sure i wont be able to. Sad
    • Next Page