
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
Canva Integration
Hello! As many marketing departments are streamlining their teams, many have begun utilizing Canva for all design mockups and approvals prior to its integration into Marketing automation software. While Zoho Social has this integration already accomplished,
Clone Entire Zoho Boooks Organization, including all transactions for testing & training
Can Zoho Books support help with direct cloning of entire Zoho Books & Inventory Organization? including all transactions, just like a copy & paste or disk cloning. Is this possible?
Can't change login email address in zoho books.
Hello, Does anyone have any idea how to change login email in zoho books?
Zoho Site Vs. Wordpress website - which is better ?
Hi I have a Wordpress website hosted at hostgator. I use zoho CRM for leads , customers, scheduling , etc. I am considering moving my website to zoho sites. What are advantages and disadvantages to using zoho site compared to a wordpress website? On a scale of 1 to 10 , how good is zoho sites? zoho sites with being found by potential customer searching the web for products , services? I sell and service business phone systems into local markets in California. My goal would be to increase
Bank Reconciliation Reports Do Not Have the Requisite Information Needed for a Proper Bank Rec Report
Basic accounting practices for bank reconciliations dictate that bank reconciliation reports have the following components: Date or Period of Reconciliation: The report should clearly state the date for which the reconciliation is being performed, typically
How to record chargeback in zoho books?
Hi all, Does anyone know how to record a chargeback transaction in zoho books? Thanks, Mo
workflow fields before assigning the ticket when the client opens the case by email.
I want to create a workflow that forces the technician to complete the mandatory fields before assigning the ticket when the client opens the case by email.
Answer to wrong email address
Hi Everybody! When we receive a customer request (let's call him Peter) on our info@abc.com mail address, we manually forward the email message to Zoho desk (support@). Of course, sender of that message is info@abc.com and Zoho opens a new ticket with "info" as the contact name and info@abc.com as email address (nobody can blame Zoho for doing that). We then edit the ticket and fill in contact name (Peter), account name (Peter Ltd) and email address (peter@mail.com) of the customer. When we answer
Zoho Desk nog sending true Gmail
Desk isn't sending our outgoing e-mail anymore. We can still receive e-mails but not send. I reconnected the email again and disabled the 2FA (to test). If I choose the Desk generated outgoing email address it works just fine. Please assist.
Add Hebrew Language Support for Zia Auto-Tag in Zoho Desk
Dear Zoho Desk Team, We hope this message finds you well. We are currently utilizing the Zia Auto-Tag feature in Zoho Desk, which has proven to be quite valuable for categorizing and organizing tickets based on their content. However, we’ve encountered
Footer: Zoho make a big downgrad with new footer option
Every post about the new footer function is negative and all say: its a big downgrade. The idea behind this new function was: Make it more simple. Great, now its faster and more simple to add an footer. But nobody from zoho team think about the more bigger
Need help with Zoho Billing/Subscriptions API
Hello, We need help in figuring out which APIs to use in the following scenarios to process customer payments and manage subscriptions. When 14 days trial period is over and subscription status in Zoho changes to "TRIAL_EXPIRED" , customer comes back
Multiple Filters? Question answered many times, but never satisfactorily
Hi. I love Zoho Creator. However, I would like to know more about creating a view that allows users to easily filter the records, using several filters at once. I know many people have asked this before, and mostly the answer given is "Use the search function, and search in each column for the required parameter" However, this is not a satisfactory solution for a number of reasons: 1) You have to know the exact value to search for (sometimes the value might be a two or three word answer)
Sendmail with filtered report as attachment - Best practice ?
Salut, I am scripting sendmail workflows with reports attached. I need those reports to be filtered. For example, a 10 subrows order would have 3 different suppliers, and I want those 3 suppliers to receive a copy of the order with only the subrows related
Issues w/ Screen Share & Accessing via Mobile Web Browsers
1. How do I share my screen while still seeing video of myself & paticipants without rebroadcasting the participant video feeds? All other video conferencing tools provide this feature so not sure if it's a setting I'm missing or a programming oversight. 2. How do I know what screen/application I'm sharing? After selecting the screen/application a notice appears however it is appears on the wrong screen leading to confusion about what participants can actually see. 3. How to I allow participants
Time Limited Coupon or Expiring Link in Workflows
I would like to see a feature where I can include a time limited link in Workflow Campaigns. For example: I could link to a sales page with a discount and set the link to expire after 24h. The link would be generated by Campaigns for each campaign sent
Option to duplicate views ( ticket and others)
Hello, I would like to ask for the option to duplicates views, especially ticket views. Often we need to use the views for very particular information, including filtering out custom data. It would be great to allow duplicate an existing View, so it can
Option to copy/duplicate Custom Ticket views
Hi Team, Hope you're all well. I was wondering if you would consider a feature on Custom Ticket views: The option to copy or duplicate an existing custom ticket view It would help tremendously for views with a lot of criteria that could be reused multiple
Democratize data visualization across your organization using Chart View in CRM
Hello everyone - As part of CRM for Everyone, we've introduced a whole new set of features. This announcement will focus on one of them: Chart View. Why did we add this view? To put insights directly in the hands of the people closest to the action. Here's
Will Zoho implement DANE?
I know that setting up DNSSEC and DANE is quite a risky process. But it will improve email security. With DANE, a server can verify a SSL certificate before connecting to the server. There are some RFC related to DANE which can be found here: DNS-based
How do I stop Notifications in Mail?
How does one turn off notifications for our Mail accounts? Why is an answer to such a basic question impossible to find in this community forum? Also, could you point us to the most current user guide so we don't have to spend time asking such fundamental
Turning off self view in Zoho Meeting
Hi Is it possible to turn off/hide self view in meetings? Cant see any options for it. Thanks
Is it possible to hide self view in Zoho Meetings
Hi - I want to hide my camera view when conducting meetings in Zoho Meetings. Most of my meetings are one to one with clients & I prefer to focus on them them on the screen? I've searched and cant find any options for this? Thanks Ro
Darshan Hiranandani : Can I hide my self-view in Zoho Meetings, and if so, how?
Hi everyone, I’m Darshan Hiranandani, looking for a way to hide my self-view during meetings in Zoho Meetings. I find that seeing my own video feed can be distracting, and I’d like to know if there’s an option to hide or disable it. Could anyone provide
mx.zoho.com servers blacklisted by UCEPROTECTL3
Hello, An MXtoolbox check for my domain showed that UCEPROTECTL3 has blacklisted all three of the zoho MX servers. I am unable to sign up for Zeptomail service for our company transactional emails until this issue is resolved. But this is out of my hands.
How to integrate Zoho CRM, Zoho Forms and a WIX Web Site
Attached video demonstrates how to use Zoho Forms included in Zoho One, to design a Contact Us form to be embedded into a WIX web site and integrated into Zoho CRM.
Events on Calendar disappeared
hello, Events (e.g. repeating events) disappeared on my calendar for Wed, Oct 2, which led to missing some meetings on that day. What exactly is wrong? This is not the first time this is happening! Please, fix this calendar issue.
FICHIER FEC - ZOHO BOOKS
J'ai testé le fichier FEC, disponible depuis quelques semaines dans zoho books pour les sociétés françaises. C'est une grande avancée car nous allons enfin pouvoir importer facilement (sans avoir à réaliser de complexes rapports dans zoho analytics) la
ERROR CODE :550 - Your message to <xxx@xxxxx.xx> was classified as SPAM.
Hey Team, I'm using Zoho Mail with my own domain, and from some of the recipients I'm receiving following error message: ERROR CODE :550 - Your message to <xx@xxxx.xx> was classified as SPAM. Please add more content, cut down on HTML links, use fewer
Allow 3 Subforms in a custom module
We have many custom modules in CRM and every now and then we need more than 2 subforms for a module We are on Zoho One Plan Can you please increase the subfrom limit from 2 to 3 Our current workaround is to create a solution in Zoho Creator and embed
Time Zones
Hello, Is there a way to add a time zone in a Deal related to "bid due"? We work on projects across the world and even though some things adjust to my own time zone, I have found that any dates we manually enter - Bid Date, RFI Due Date, etc. do not appear
Create Zoho Project and assign a contact without account
I’m trying to automate the creation of new projects in Zoho Projects using Zoho Flow. In my setup, I often need to assign projects to individual contacts who don’t have an associated Account/Company in Zoho CRM—just a personal contact. When I create a
Update main form's Lookup value following the completion of a Subform within that same main form
Hi, It's quite a simple request but I'm struggling with getting the deluge to work smoothly. In short, I have a main form (Place_New_Order). Public users will be able to use it. They have a subform to complete with their contact details etc (name, email,
ZOHO LOGIN PROBLEM
Hello, my name is Bernice. One of the users in our company is having a problem logging into their system. They had two-factor authentication on their phone but unfortunately, they lost that phone. Now when trying to login to their Zoho people they are
New in CRM: Dynamic filters for lookup fields
Last modified on Oct 28, 2024: This feature was initially available only through Early Access upon request. It is now available to all users across all data centers, except for the IN DC. Users in the IN DC can temporarily request access using this form
Sync Zoho CRM Events with Google Calendar?
Hi, Is there a way to permanently sync all events from Zoho CRM with Google Calendar? I’ve seen that you can link Zoho CRM to Zoho Calendar and then connect Zoho Calendar to Google Calendar — but is there a way to sync existing and future events from
Pre-fill webforms in Recruit
I don't want to use the career site portal (as I have my own already), but I would like to direct users to the application forms for each role, from my website job pages. Is there a way to pre-fill fields in Recruit application forms, so that I only have
image cover div or original aspect
I changed my app's theme, and now when I return to the original theme, the images in my reports cover the entire div, whereas before they were displayed in their original aspect ratio. How can I change this? I can't find the option. I only see that you
Delete subform rows based on mainform input
I took my first adventure in getting ChatGPT to write some code for me this weekend. I want to ADD new rows, UPDATE existing rows and DELETE existing rows based on the input of a mulitselect lookup in the mainform. ChatGPT produced this for me which seems
Des parcours WhatsApp simples pour engager vos prospects et les convertir durablement
En tant que professionnel du marketing, il vous est sûrement arrivé de déployer des campagnes par e-mail, SMS, réseaux sociaux ou pop-ups, sans obtenir l'engagement espéré. Une situation frustrante, mais malheureusement fréquente. Vous vous posez sans
Next Page