
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
Best way to account for shipping charges to customer
I have been allocating all our shipping expenses to the "postage" account, but I realise that is probably incorrect, as for the most part, we pass on shipping charges to our customers. So I should probably add the shipping charges into the "shipping charges"
Zoho Flow s’enrichit avec les subflows et les actions Webhook
Nous sommes ravis d’annoncer deux ajouts importantsà Zoho Flow : les subflows et les webhooks sortants. Ces nouvelles fonctionnalités ont été conçues pour vous aider à créer des workflows plus facilement et à automatiser davantage de tâches répétitives.
How to assign canvas view for portal user
Hi , as a portal user, I can switch to another canvas view, however, I cannot find any field to configure a default canvas view for portal user. May I ask how to set it up in CRM? And if I can view list by sheet view as a portal user?
Restrict Leave Application Based on Attendance Cycle (24th to 23rd)
Hi Zoho Team, Our organization follows a custom attendance cycle from 24th of the current month to 23rd of the next month. I would like to configure the system so that: Employees should not be able to apply backdated leave for any date after the attendance
How do I assign a parent to an existing campaign?
I created a campaign but now I'd like to make that existing campaign a child of another. How can I do this?
Categorize Tickets Through The App
I used to be able to categorize and assign tickets through the app without any issues. However, for the past year, whenever I try to edit a ticket, select a category, and click save, it doesn’t actually save the changes. As a result, I haven’t been able
Can't add picture to email template. Says I'm over the character limit.
I tried creating an email template with a picture and it says I'm over the character limit. The picture is pretty small. What can I do?
Allow breakdown of per diem for meals provided
Would it be possible to break the per diem down into what you get for each meal. The reason for this is we want to offer per diem but if a meal is provided by a customer or sales we need to remove this from the per diem bucket for that day. We break down
Automatically moving Leads into their corresponding buckets
Hi, I have developed a lead pipeline and created different cadences for various lead segments. After enrolling leads into their respective cadences, each lead goes through a series of follow-ups (in my case, three emails). If a lead does not respond after
Tracking Email Template usage
I'd like to be able to track how many times agents/users send an email from Templates. This is so we can track their activity in relation to Campaigns in CRM. Thanks
Get employee id of authenticated user via API
Hi, For adding timetracking records an employee id is required. Is there an API Route available to get the employee ID of the current authenticated user? or something like /users/me Currently using https://people.zoho.com/people/api/forms/employee/getRecords
Zoho Social API for generating draft posts from a third-party app ?
Hello everyone, I hope you are all well. I have a question regarding Zoho Social. I am developing an application that generates social media posts, and I would like to be able to incorporate a feature that allows saving these posts as drafts in Zoho Social.
Collect in-app feedback with richer context and granular insights
Hello, Apptics community! From GenAI chatbots to one-tap checkouts, user experience standards keep rising—yet 96% of unhappy users never explain what went wrong; they simply leave. Introducing in-app feedback 2.0 banner In-app feedback 2.0 is here to
Temporary restiction
My account says You have been temporarily restricted from publishing jobs from Zoho Recruit.Click here to request a one-time approval to publish your jobs and when I go to click it shows error. Kindly assist.
Help with Quote template for peer review
We are wanting to do peer review of quotes/proposals, however the quote templates dont have product cost, profit margins, etc. It is difficult for a manager to approve a quote without ensuring nothing is going out at improper margins, etc. I have not
How many AR fields We can add in a form?
I want to add at least 10-15 AR fields in a form. I just want to know is there any limit on the AR fields or do I need to pay extra money for using 10-15 AR fields. Thanks in advance.
Agent working hours
Hi, I know it is possible to set company business hours but is it possible so that agents can have different ones? I.e. some agents cover later hours on specific weeks - can these be set so those agents that are "working" get notified about tickets etc.
Disallow CLOSE if tags field is empty
I want to introduce a mandatory condition that NEW tickets (not prior closed tickets) cannot enter the CLOSED state without first having an entry in the tags field. Is there a way I can do this?
Central de Ajuda - Restringir visualização de tickets
Estou tentando configurar o Zoho Desk para que determinados usuários dentro de uma mesma conta consigam visualizar apenas os tickets criados por usuários específicos dessa conta — e não todos os tickets ou apenas os seus próprios. Até onde sei, existe
Business Hours with lunch break
Our business hours are: mon - fri 08:30 - 13:00, 15:00 - 18:30. How can I handle the lunch break? If I use 8:30 - 18:30 it obviously breaks SLA. Thanks
Default/Private Departments in Zoho Desk
1) How does one configure a department to be private? 2) Also, how does one change the default department? 1) On the list of my company's Zoho Departments, I see that we have a default department, but I am unable to choose which department should be default. 2) From the Zoho documentation I see that in order to create a private department, one should uncheck "Display in customer portal" on the Add Department screen. However, is there a way to change this setting after the department has been created?
Ask the Experts 21: Power up your support game with Zoho Desk Automation
" In every business, there are tasks to automate, Zoho Desk helps with features that integrate Assignments to manage tickets and teams to align,Macros for quick actions and workflows to streamline Contracts and schedules to hold things tight, Plans run
If leads are assigned to a person before 4:00 PM and the stage is "Fresh Lead", then an email should be triggered at 4:00 PM to all assigned users. If leads are assigned after 4:00 PM and the stage is
If leads are assigned to a person before 4:00 PM and the stage is "Fresh Lead", then an email should be triggered at 4:00 PM to all assigned users. If leads are assigned after 4:00 PM and the stage is "Fresh Lead", then the email should be triggered the
Multiselect lookup in subform
It would be SO SO useful if subforms could support a multiselect look up field! Is this in the works??
Tasks as calendar events? What about a way to verify a meeting actually happened?
I'm not sure how to best ask this, but i'm looking to add some guard-rails into zoho for the end-user. However for guardrails to be effective they can't really add extra steps for the end-user. i.e. every step that's added for the user, is another place
Attachments should sync between Zoho Finance in CRM and Zoho Books
It would EXTREMELY helpful and practical if the attachments added to an invoice via Zoho Finance in CRM synced with the invoice updates in Zoho Books. Currently, attachments to an invoice updated in CRM DO NOT appear as attachments when viewing the same
Introducing a new home page view and UI enhancements for Dashboards
Hello everyone, In CRM, the home pages provide a quick view of the various happenings in a business with the help of dashboards. The home pages also help to organize one's and the team's day's work. There are three views in the home tab: Classic User's
Call result pop up on call when call ends
I’d like to be able to create a pop up that appears after a call has finished that allows me to select the Call Result. I'm using RingCentral. I have seen from a previous, now locked, thread on Zoho Cares that this capability has been implemented, but
Data Template Amending
Hi, is it possible to remove data templates once you have applied them in Workdrive? Also, once I have added a new field to a data template can I mass update multiple files who have already been allocated that template and amend just that one added
Zoho Flow y subformularios de Zoho CRM
Buenas tardes, En mi empresa vamos a empezar a usar los subformularios de zoho crm pero estos los voy a tener que rellenar con zoho flow ya que va a ser el encargado de rellenar dichos campos del subformulario. El problema es que a la hora de intentar
Recurring Invoices
We are looking at moving our invoices to ZOHO Billing, I have started the trial period and like that I can et up for four different companies. The one feature we need which is mentioned in the documentation is Recurring Invoices so we can send our Rent
Implement Meeting Polls in Zoho Bookings
Dear Zoho Bookings Support Team, We'd like to propose a feature enhancement related to appointment scheduling within Zoho Bookings. Current Functionality: Zoho Bookings excels at streamlining individual appointment scheduling. Users can set availability
Zoho Projects App update: Arabic and Hebrew language support
Hello everyone! In the latest version(v3.10) of the Zoho Projects iOS app update, we have brought in support to access the app in RTL(Right to Left) languages (Arabic and Hebrew). Note: RTL is yet to be supported on the Calendar and Gantt charts modules
I want to cancel @mention group in the notes in Zoho CRM
Hi Everybody, I want to prevent people from mentioning a specific group in notes in Zoho CRM. We have one group called Team Sales, and although we've asked users not to mention groups, they still mention the group name. My workaround is to change the
Kaizen #193: Creating different fields in Zoho CRM through API
🎊 Nearing 200th Kaizen Post – We want to hear from you! Do you have any questions, suggestions, or topics you would like us to cover in future posts? Your insights and suggestions help us shape future content and make this series better for everyone.
How to install node packages in Zoho Creator cloud functions
I wanted to create some functions which requires node packages like axios, fetch, multer etc., How and where can i install the node packages in Zoho creator to use it in Zoho creator Nodejs function.
Session "Ask Me Anything" Zoho France - Le 26 Juin 2025 14h à 17h (en Français
Chers Utilisateurs, Vous cherchez à mieux comprendre Zoho CRM ou Zoho Desk ? Nos experts seront disponibles pour répondre à toutes vos questions lors de notre session Ask Me Anything. Rejoignez-nous ici pour en discuter en ligne. Pendant trois heures,
Option to Crop Existing Agent Image in Zoho One Directory
Hello Zoho Team, We hope you're all doing well. We would like to request a small but useful enhancement to the Zoho One Directory. 🎯 Current Limitation At present, the system allows cropping an agent image only during the initial upload of an agent's
Introducing Sub-Accounts in Zoho Books!
Hello Everyone, Sub-Accounts is LIVE! Yes, you read it right. The much needed and most requested feature is now live in Zoho Books. The sub-accounts feature in Zoho Books will help you to classify your accounts further which will give you a more detailed view of your accounts while running reports. You can create sub-accounts for the below Accounts: Asset Cost of Goods Sold Expense Liability Fixed Asset Other Asset Other Current Asset Long Term Liability Other Current Liability Other Liability Other
Sesión "Ask me anything" Zoho en Español - 26 de junio de 2025, de 14:00 a 17:00 (en español)
¡Hola Comunidad! ¿Quieres entender mejor Zoho CRM o Zoho Desk? Nuestros expertos estarán disponibles para responder a todas tus preguntas durante nuestra sesión "Ask me anything". Puedes comentar este artículo y durante tres horas, nuestro equipo estará
Next Page