
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:
| |
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 | |
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.
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
-----------------------------------------------------------------------------------------------------------------
Recent Topics
Users Not Automatically Being Added To WorkDrive Team
I have already created a ticket for this issue, but the support team doesn't seem to understand what's happening. Our organization started with a trial of Zoho Workplace around November 10, 2025. I created 10 users, including myself. I sent out the invites,
Synchronization between Gmail and Zoho Mail
Hello! I am using Zoho Mail within the Zoho One platform. I have completed the basic setup and added all the required DNS records with our domain provider. Our goal is to set up two-way synchronization between our current Gmail inbox and Zoho Mail, but
IMAP login problem
I have my domain hosted with zoho @wilson.ie I have added a new user and have enabled IMAP access to this user account The user can login to zoho mail on the web. When we enter the server settings into Outlook as per below, Outlook cannot login to the
Contact data removes Account data when creating a quote
Hi, Our customer has address fields in their quote layout which should be the address of the Account. They prefill the information, adding the account name - the address data is populated as per what is in the account - great. However when they then add
Changes to subform in Zoho CRM Portal Timeline History Unavailable
Hi Support Team, We have noticed a feature limitation in the Zoho CRM portal. We created a portal for our vendors to edit records directly, but when vendors make updates, the Modified Time and Date fields are not being updated. Additionally, these updates
This mobile number has been marked spam. Please contact support.
Hi Support, Can you tell me why number was marked as spam. I have having difficult to add my number as you keep requesting i must use it. My number is +63....163 Or is Zoho company excluding Philippines from their services?
Zoho CRM Portal Field Level Permission Issue
Hi Support Team, I am using the Zoho CRM Portal and configuring field-level editing permissions. However, we are unable to restrict portal users from editing certain fields. We have created a portal and provided View and Edit (Shared Only) access for
Function #11: Apply unused credits automatically to invoices
Today, we bring you a custom function that automatically applies unused credits from excess payments, credit notes, and retainer payments to an invoice when it is created. Prerequisites: Create a Connection named "zbooks" to successfully execute the function.
Edit Contact Roles in the Potentials Mod
New to ZOHO so I need some help. I work the same people on different projects concurrency. Their contact info remains the same but their role changes from project to project. In the Potential Mod you can pick contacts and assign a Role to them. I know how to edit the roles. What I want to do is add some fields. Specifically I want to add the following "Expectation" "Requirements" and "Communication "Requirements." This will allow me to look at a Potential and see information associated with this
Duplicating report but custom layout does not
Dear Zoho Creator, I need to duplicate a report into 10 copies, but unfortunately the custom layout (detail view) doesn’t copy along with it. I tried exporting and importing the custom layout, but the field mappings are incorrect. I believe everyone are
Credit Card Readers?
We would like to use our commerce website at conferences (and eventually in store) to swipe credit cards to pay for orders. How would we accomplish this? Does Zoho have anything available for a developer write code to integrate something like Stripe Terminal
AI generated meeting notes associated to Account or Deal
As our organization works to improve efficiency we are looking for a solution to leverage AI to generate meeting notes and then add those notes to a CRM record such as an Account or Deal. I see Zoho has a Notebook AI offering that talks about the ability
Stock count by bin location
Is there a configuration to make a stock count by bin or area and not by product. these is useful to manage count by area Regards
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
How Do I Refund a Customer Directly to Their Credit Card?
Hi, I use books to auto-charge my customers credit card. But when I create a credit note there doesn't seem to be a way to directly refund the amount back to their credit card. Is the only way to refund a credit note by doing it "offline" - or manually-
Can we generate APK and IOS app?
Dears, I want to know the availability to develop the app on zoho and after that .. generate the APK or IOS app and after that I added them to play store or IOS store.. Is it possible to do this .. I want not to use zoho app or let my customers use it. thanks
Limitation with Dynamic Email Attachment Capture
I've discovered a flaw in how Zoho Creator handles email attachments when using the Email-to-Form feature, and I'm hoping the Zoho team can address this in a future update. The Issue According to the official documentation, capturing email attachments
Zoho Learn Course Completion Notifications/Triggers/API
Zoho Learn works great and will suit our course creation needs, but it appears to be lacking a bit when it comes to integration with other Zoho services (creator etc.) when it comes to course completion. 1) Is there an API or Zoho Flow trigger for when
Sorting a list of record acquired from the zoho.crm.searchRecords function.
This is something for which I'm trying to figure out a straightforward way to do. The searchRecords does a great job fetching me the records that I want. However, in some cases, where it returns multiple records, I want it to sort the returned list by date of creation of that record, so that when I do records.get(0), I get the most recent record. As an example, here's my sample pseudo code: records = zoho.crm.searchRecords("Clients", "Office_Number:equals:123456"); Now the "records" list above contains
Enhanced Recording Permission Controls for Zoho Cliq Meetings (Similar to Zoom)
Hello Zoho Cliq Team, We hope you are doing well. We would like to request an enhancement to the recording permission functionality in Zoho Cliq Meetings. Current Limitation: in Zoho Cliq Only hosts and co-hosts can record a meeting. Participants cannot
Phone Connection
When on a call the person on the other end complains that there is static, I am cutting in and out or they can't hear me all. This happens on the cell connection as well.
Can't add a sender adress from zoho campaigns
hi, I need to change the sender address for a campaign. When i try to add it i get a message to say 'duplicated email address found while adding your sender address'. This is the first campaign i'm sending so I don't understand why this message is displayed? Thanks Jane
Admin asked me for Backend Details when I wanted to verify my ZeptoMail Account
Please provide the backend details where you will be adding the SMTP/API information of ZeptoMail Who knows what this means?
This domain is not allowed to add. Please contact support-as@zohocorp.com for further details
I am trying to setup the free version of Zoho Mail. When I tried to add my domain, theselfreunion.com I got the error message that is the subject of this Topic. I've read your other community forum topics, and this is NOT a free domain. So what is the
This user is not allowed to add in Zoho. Please contact support-as@zohocorp.com for further details
Hello, Just signed up to ZOHO on a friend's recommendation. Got the TXT part (verified my domain), but whenever I try to add ANY user, I get the error: This user is not allowed to add in Zoho. Please contact support-as@zohocorp.com for further details I have emailed as well and writing here as well because when I searched, I saw many people faced the same issue and instead of email, they got a faster response here. My domain is: raisingreaderspk . com Hope this can be resolved. Thank you
Export History timeline
Hi, I have an idea, bout zoho desk history of the ticket it would be great if the agent or admin of the zoho desk can export the timeline of the ticket history for agent report or on other matter.
Desk fails to create a new ticket on Reply email
When I send a direct email to support@mysite.com, Desk will create a new ticket as expected. When I REPLY to an email sent from support@mysite.com, Desk will NOT generate a new ticket. This is very bad. How can I fix this? Use case: In a separate system
Condition based aggregate fields in subforms
Hello everyone, We're excited to inform you about the latest enhancements made to our aggregate field capabilities in subforms; create aggregate fields based on conditions! An aggregate field is a column on which a mathematical function has been applied.
Is there a way to disable the Activity Reminders Pop-Up Window every time I log in?
Just wondering if there is a setting to disable the window from opening every time I open my CRM? Thanks Chris
Ask the Experts 25: Experience the full spectrum of Zoho Desk’s autumn and spring releases for 2025
Hello Everyone, We’re on the 25th episode of our ATE series! It's a true milestone in our live community interactions! It’s been an amazing journey since we started in October 2018. Zoho Desk has come a long way, evolving with the support of a wonderful
Printing Multi-Page Reports (PDF Export)
Hi, I am moving a report from Google's Looker Studio to Zoho Analytics and trying to reproduce the Looker page by page dashboard editing experience. With Google, what you see is what you get when you print to PDF. But I can't seem to create the same experience
Addin Support in Zoho Sheet
Is there any addin support available in zoho sheet as like google marketplace to enhance productivity by connecting with other apps, providing AI data analysis, streamlining business processes, and more?
Mass Update of Lookup Fields not possible
Hello List I've created a custom field for Leads and Contacts 'Current Campaign'. This is very Handy as I can filter leads and then related them to a campaign. Everything ready, but then I realized that mass update doesn't work for lookup fields... a
Zoho Books | Product updates | November 2025
Hello users, We’ve rolled out new features and enhancements in Zoho Books. From translating email notification templates to the new transaction locking restrictions, explore the updates designed to enhance your bookkeeping experience. Making Tax Digital
Function #61: Automatically add free item to the invoice based on item quantity
Hello everyone, and welcome back to another Custom Function Friday! During holiday seasons or special promotions, businesses offer deals like BOGO (Buy One, Get One), Buy 3 Get 1 Free, Buy 2 at 50% off, and much more to attract customers. These promotions
Notes for Items for Future Purchase Order
Next time when I order an item, tau have to make some changes in it, that order has to be placed after 4-5 months, I want to save those changes or points somewhere in the item, how will that be possible..
Schemes of different tyoe
How can easily apply hourly, day wise or month wise schemes on Bill, Quantity, and other schemes. Like I want to apply a scheme Form today to next 7 days .where i can mention in zoho books so scheme will implement automatically to all customers and
Alphabetically
How can i arrange alphabetically - (Manage Manufacturer) Field in Item Master
Zohomail
Im trying to setup email address zoho
Clients not receiving emails
I've been informed that my emails are not being received. Is there anything that I should look into to rectify this? Many thanks!
Next Page