
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
Using Zoho Inventory for managing Item compatibilities
Use case: Using Zoho Inventory for managing (as an example) aftermarket car parts, where a single part can suit many makes, models and years. How do most businesses assign and manage compatibility for each part? Do ZI users typically do this using multi-select
Unable to enter manual journal entries in AR/AP.
Hi there, i am facing some problem relating to AR/AP. I want to make some entries in AR/AP through manual journal. for example. some time I send cash 500 to Mr. A (Customer) for any purpose and then after 2 or 3 days Mr. A returned back 700 to me and
Questions regarding WorkDrive
Here are my questions regarding WorkDrive: Does WorkDrive have a limit on the number of downloads? What will happen if a file is downloaded excessively? Does WorkDrive have any restrictions on download speeds? Are there any limitations on downloading
How to record tips from customers
I run a cleaning service business and on occasion customers include a tip with their check payment. How can I record the amount paid for service and the tip separately? Any amount over the invoice is looked at as an overpayment and suggest a credit note
Multi-currencies in Zoho Books
I'd like to request multiple currencies in Zoho Books. I have customers paying in USD, CAD, CNY. I need to bill customers in these currencies too. I can set up a base currency, and then set up a exchange-rate table to convert these currencies.
I want refund of Zoho standard subscription on WEB payment
Hi, Kindly help to refund the WEB payment made on 13/07/2025 for Zoho standard annual subscription. I didn't find the software useful for my project. Regards
Is Conditional display of field(s) possible in a Canvas Customer Portal?
Is Conditional display of field(s) possible in a Canvas Customer Portal? How?
Automate Backups
This is a feature request. Consider adding an auto backup feature. Where when you turn it on, it will auto backup on the 15-day schedule. For additional consideration, allow for the export of module data via API calls. Thank you for your consideration.
View Linked Subscription on Invoice list
When looking at the list of invoices in billing is it possible to see the subscription that an invoice is for. This would allow you to see if it's a subscription a customer is behind on, or they simply haven't paid a one time invoice.
Recording Credit Card Fees when Recording Payment for Bills
It seems I am unable to record credit card fees when paying a bill. I pay close to 100% of my bills with a company credit card via online portals. I'm happy for the CC fess to be recorded as Bank Charges but it will not allow that field to be used if
Workerly/Zoho One Pricing
Hi What is the pricing model that is suppose to be as a Zoho One user? If i use the services of a freelancers or temp workers (Sometimes for a few hours a week/month), I need to purchase a zoho one license for each of them as well as workerly licenc
DKIM
I have my DKIM in Titan, which is another email service provider. I get this notification on my portal. What shall I do? ( Improve the deliverability of emails sent from Zoho Social by adding DKIM (DomainKeys Identified Mail) records to your DNS settings.
Show All Notes For A Single Record
I would like to be able to view a list of all Notes for a particular record. We can add several (unlimited) Notes for the Leads, Contacts, Accounts and Potentials records. The subject line and some of the note content for up to 10 notes is visible on the first page. You can select the arrow to view additional notes in the list. I would like a button next to the New Note button that says View All. This would bring up a printable list of all notes listed in descending order by Modified Time (newest
Zoholics Europe 2025: Build Smarter with the Zoho Creator Low-code Workshop!
Why should you attend? This year, Zoholics Europe 2025, Zoho’s official user conference, is your opportunity to connect directly with the teams behind the tools you use every day. Don’t miss one of the most requested sessions: dedicated, hands-on workshop
Assigning multiple roles to a user in Creator
Hi I find we can assign only one role and permission to an user in creator. There is a requirement to assign multiple roles and corresponding permission to one user. Is there any solution or workaround for this? Refer the screenshot below
【Zoho CRM】ウィザード機能のアップデート:セクション要素の追加
ユーザーの皆さま、こんにちは。コミュニティチームの中野です。 今回は「Zoho CRM アップデート情報」の中から、ウィザード機能のアップデートをご紹介します。 ウィザード機能に新たに「セクション要素」が追加されました。 各ウィザード画面内で項目、テキスト、サブフォーム、ウィジェット要素などをより柔軟に整理できるようになりました。 セクション要素とは? ウィザードの中で、関連する項目や要素をひとつの「サブエリア」 としてまとめられる新しい構成要素です。 セクション要素活用メリット 入力内容やプロセスによっては、より細かな構造や階層化が求められる場合があります。
Edit PDFs from within your web app using Zoho Office Integrator
Hi users, We are excited to introduce PDF editing capabilities in Zoho Office Integrator. You can now open, edit, and collaborate on PDFs from within your web app—in addition to documents, spreadsheets, and presentations—and save them in your configured
Zoho CRM Workflow and Function Backup Options
Hi everyone! I have been able to make several backups of my CRM data and noticed that the Workflows and Functions are not included in these backups. To my knowledge, there is no backup feature for workflows and functions, which is problematic in of itself.
Zoho Recruit > Job Opening Module> Editing, Deleting, Adding (Fields)
Hello All In the Job Opening Modules How do i go about deleting the Positing Title or changing to Job Title or can i hide it from all? I want to add a Look Up User Field, however when i select the look up field i do not see that Can i have the industry
Can you create a lead without assigning an owner?
Here is the question I have: Is there a way I can create a bunch of leads without assigning it an owner? What I want is for my salespeople to pick and choose their own leads without me assigning them.. right now all leads are owned by me because
Bug - Incorrect example in the documentation
I found an issue in the Zoho API documentation. The example "Sample Request" on this page is incorrect — it shows the example for "Get Email Attachment Info" instead of "Get Email Attachment Content". Wrong example: curl "https://mail.zoho.com/api/accounts/12345678/folders/9000000002014/messages/1710915488416100001/attachmentinfo"
Power of Automation :: Dynamically generate Tasklists based on values selected in Task Custom Fields
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
WhatsApp Enhancements to Boost Customer Engagement
We're excited to introduce a series of powerful enhancements to the WhatsApp integration in Zoho FSM, making customer interactions faster, smarter, and more actionable—right from your Zoho FSM interface. Here’s a quick rundown of what’s new: Try It Out
Store reviews module just got smarter in Zoho Apptics
Hello, Apptics community! Every app deserves better visibility in the marketplace, and reviews play a crucial role in improving your app's App Store Optimization (ASO), rankings, and credibility across stores. That's why we've rolled out a set of enhancements
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.
Include EVERYTHING in Language Files
Hey, we are building out a system, that needs to be translated. The language files lack a few things though. 1. Blueprint names 2. Canvas View elements like tab names Please include everything into these files, otherwise it's not really a multi language
A way to create kits (groups of items) that do not require bundling and are added to an order as the individual items
We are evaluating moving off of Sage BusinessWorks (which handles accounting, order entry, inventory control, accounts receivable, etc) to Zoho Books/Inventory. One of the things we heavily use is a feature called Kits, which allows creating a group of
Allocating Salesman To Customer
Hello, please add a feature to allocate a salesman to a particular business customer/account. Regards
Shipment
I have 70 shipments Out of which 40 delivery date are updated( since it is live tracked) 30 numbers i need to update manually. How to do it in bulk?
arabic not printing
Qatar has a legal requirement to have invoices in English and Arabic. When writing invoice fields in Arabic, they don't print. Why?
How to show Order Number/SO Ref on Invoice emails
When creating a sales order or invoice we have an option to input an order number or ref# (see attached images). For the Sales Order email template we can add a placeholder for the SO_REF. However, for the Invoice email template there's no option to reference
Specify in-line image size in question
I have an image inserted into a file upload type question. I can click and drag the corner of the image to make it larger or smaller, but I would like to manually input the dimensions I need. No matter what size I make the image in photoshop before uploading
Can you limit who creates tags?
Hi there, I'd like to find out if it's possible to limit which Agents create tags on Zoho desk. Thank you.
Auto CC - Moving Departments
We have Auto CC e-mail replies to your support mailbox enabled. We have two departments: Helpdesk (helpdesk@domain.com) Delivery (delivery@domain.com) If we create a Helpdesk ticket, and reply, replies are CC'd to helpdesk@domain.com (OK) We then move
Sudden Layout Issue After Last CSS Update for ZML (Temporary Fix Inside)
Hi, Our clients have noticed today that every section laid out with ZML suddenly shows an unwanted top padding/blank space that interrupts the user screens. It appears that Zoho has changed the default CSS for the .zcp-col.zcp-panel-rowtype-auto element.
Customer paid excess. How do I record payment?
A customer has paid me Rs. 7150 which is in excess. The amount due is Rs. 5388 I owe them Rs. 1762 back which I will be transferring to their account tomorrow. How do I get this entered into Zoho Books? I'm a little lost. :) Rishi
Search Bar Improvement for Zoho Commerce
Hey everyone, I've been using Zoho Commerce for a bit now, and I think the search bar could really use an upgrade. Right now, it doesn't show products in a dropdown as you type, which would make finding items a lot faster. On Shopify, for example, you
Tabular View Report | Scale To Fit Screen
Please add the option to scale Tabular View reports to fit the screen. I constantly have to adjust the column size of Tabular View reports to fit various screen sizes and it just looks messy. You can see in the screenshot below there is a blank gap after
Why Server error in creatiing Landing Pages
Hi Zoho Team, pls see my screenshot and tell me, what's wrong. Thx
Tip 31: How to make a field in a Zoho Creator form mandatory based on criteria
Hi folks, I'm sure most of you are familiar with the Mandatory property available in our form builder. It enables you to ensure that your users enter an input in a required field. If they don't enter an input in that field, they'll be unable to submit
Next Page