Inspired by this discussion, I wrote a script for the Scripting block that lets you instantly start and stop a virtual timer on any record, provided that the table is set up to work with this script. Aside from adding the script into a Scripting block, setup only requires three new fields:
A single line text field, which will store the script’s timing data (used internally; may be hidden)
A duration field, where the script will store the tracked time
A button field, which must be set to trigger the Scripting block that contains the script. I suggest labeling this button “Start/Stop,” for reasons that you’ll see below.
Use: Click the button once to start the “timer.” Click it again to stop it and see the duration. Need to continue timing on that same record? Click the button again to restart. The next click after that will tally the elapsed time from both timing “sessions” and put the total in the duration field. Start and stop the timer as much as you need.
How it works: Each time you click the button, the script adds the current time (converted to a number) to an array, and stores that array in the single line text field. An time that a button click results in an even number of values in the array, the script calculates the difference between each pair of values, and stores the resulting duration in the duration field.
The benefit of this timer system is that you can have multiple records all “timing” simultaneously, and all using the same Scripting block. Using Airtable’s timer block, you first have to pick a record for the timer, and you need one timer block per record that you wish to time.
One optional feature in the script is to clear the duration field while the timer is “active.” This is one possible way to avoid confusion when looking at a record and wondering whether the timer is active or not. It’s not exactly a status indicator, but it’s a first start. I’ve got some other ideas that I plan on adding to later updates, including optional status indicators (text/emojis), and an alternate method of starting/stopping the timer using automation so that the blocks sidebar doesn’t need to be involved.
Thanks for sharing this script! Storing the timer history as json in a text field is an awesome idea. One reason why I didn’t like the Time Tracker block was because there is no history.
Pretty cool. I set up a little color scheme so that when stopped it’s red (Duration is not empty) and green when started (Duration empty). The only issue is the start. You have to click that first time to get this started. Not sure how we could indicate that the button has never been pushed before.
Pretty cool. I set up a little color scheme so that when stopped it’s red (Duration is not empty) and green when started (Duration empty). The only issue is the start. You have to click that first time to get this started. Not sure how we could indicate that the button has never been pushed before.
I recall seeing a comment by @Bill.French about storing data in text fields as JSON, so he deserves some credit for inspiring that approach.
Using color conditions is an awesome idea! To add one that will trigger for un-timed records, add another color option above the {Duration} field check that sets a color when the data field is empty. It’s only going to be empty before the timer is run once, so that condition will only be true once. After that, the others will take over.
Ya’ll are INCREDIBLE. Thank you SO MUCH for your help. I love the idea of the conditional formatting with the colors, too! I was so anxious to ask for help but you all have been INCREDIBLE!
I agree @Justin_Barrett, about the block opening and being annoying, so keep me in the loop.
I love that your solution includes making the duration block blank while the timer is running, because I couldn’t figure out what was on! Ha!
PS I wrote my own mini-script for an automation yesterday to delete a record once it moves. I’m learning! Seeing all of your example that solve real-world problems for me has helped me understand more about java script. This community is awesome!
Ya’ll are INCREDIBLE. Thank you SO MUCH for your help. I love the idea of the conditional formatting with the colors, too! I was so anxious to ask for help but you all have been INCREDIBLE!
I agree @Justin_Barrett, about the block opening and being annoying, so keep me in the loop.
I love that your solution includes making the duration block blank while the timer is running, because I couldn’t figure out what was on! Ha!
PS I wrote my own mini-script for an automation yesterday to delete a record once it moves. I’m learning! Seeing all of your example that solve real-world problems for me has helped me understand more about java script. This community is awesome!
If i have the time tracker block set up to also go to the same duration field, could i use either/or to start? Sometimes I need to do the quick search to start a timer and sometimes i want to click from the task base. If not, no biggie, I was just curious.
I recall seeing a comment by @Bill.French about storing data in text fields as JSON, so he deserves some credit for inspiring that approach.
Using color conditions is an awesome idea! To add one that will trigger for un-timed records, add another color option above the {Duration} field check that sets a color when the data field is empty. It’s only going to be empty before the timer is run once, so that condition will only be true once. After that, the others will take over.
Using color conditions is an awesome idea! To add one that will trigger for un-timed records, add another color option above the {Duration} field check that sets a color when the data field is empty. It’s only going to be empty before the timer is run once, so that condition will only be true once. After that, the others will take over.
If i have the time tracker block set up to also go to the same duration field, could i use either/or to start? Sometimes I need to do the quick search to start a timer and sometimes i want to click from the task base. If not, no biggie, I was just curious.
Unfortunately not. The way I’m tracking time has no connection to the Time Tracker block, and there’s no way I can interface with that block to stop a timer that has been started with it.
However, that does give me an idea for an update to the script, which would allow you to use either system on the same record and keep everything in sync. The only caveat is that it would only work provided that you start and stop the timer with the same system each time. For example, you could start and stop the timer with my script, then start and stop it with the Time Tracker block, then go back to my script for the next run, and everything would work. What wouldn’t work is to start with one and stop with the other. That’s not technically possible.
Unfortunately not. The way I’m tracking time has no connection to the Time Tracker block, and there’s no way I can interface with that block to stop a timer that has been started with it.
However, that does give me an idea for an update to the script, which would allow you to use either system on the same record and keep everything in sync. The only caveat is that it would only work provided that you start and stop the timer with the same system each time. For example, you could start and stop the timer with my script, then start and stop it with the Time Tracker block, then go back to my script for the next run, and everything would work. What wouldn’t work is to start with one and stop with the other. That’s not technically possible.
That’s kinda what i was thinking would happen. I could start/stop with the time block or i could start/stop with the script button. I’d just prefer, at the end of the day, to have the duration be in one field for tracking purposes.
No rush, really. Both of your scripts have been incredibly helpful already!
May I ask a silly question? What do you use a timer in Airtable for most often?
I love learning new applications for Aitable, but the timer seemed like more of a gimmick to me than useful. That must be false based on this thorough and intelligent conversation. Now I feel like I’m missing something super cool.
Thanks!!
May I ask a silly question? What do you use a timer in Airtable for most often?
I love learning new applications for Aitable, but the timer seemed like more of a gimmick to me than useful. That must be false based on this thorough and intelligent conversation. Now I feel like I’m missing something super cool.
Thanks!!
At the moment, the only thing I use it for is tracking the time I work on client projects. My gut says that’s the most common use of it, but I’m sure there are other uses I haven’t thought of.
That’s kinda what i was thinking would happen. I could start/stop with the time block or i could start/stop with the script button. I’d just prefer, at the end of the day, to have the duration be in one field for tracking purposes.
No rush, really. Both of your scripts have been incredibly helpful already!
Hey! Ran into a snag! I accidentally have left my timer on overnight (more than once…ADHD is fun!) and I can’t find a way to edit it. When using the time tracker block, I would just fix the time (Example: Just subtract 12 hours) but when I do that with yours, and then start the script again, it overrides my input with the Json record. Any ideas?
often some records are open for a month for me. (Example, I have one line item for “Client Management” that I use for the entire month for when clients call in to order or I have to adjust their back end of their subscription accounts, etc
You can edit the JSON data directly if you wish. With the timer stopped, there should be an even number of values in the array, with each pair representing a single timing period. Each number represents the time when the button was pressed, down to the millisecond. It’s just a matter of doing the math to figure out how much to reduce the last number.
To take away 12 hours, it’s 12 hours x 60 minutes x 60 seconds x 1000 milliseconds, or 43200000. Subtract that from the last number in the sequence, then replace the last number with the new value. I just ran a quick test adding 12 hours, then taking it away again, and it works. If you want to confirm, and don’t mind adding a couple more seconds, you can start the timer briefly, then stop it again, and there should be 12 fewer hours in the duration field.
@Caroline_Ritenour I’m planning to add an option to the script (how soon, I have no idea, because my schedule is quite full at the moment) to allow for the user to review the most recent tracked time before saving it, in case adjustments need to be made. It’ll have a more user-friendly interface, and won’t require any mathematical gymnastics to get the job done. I’ll post an update here once that revision is complete.
At the moment, the only thing I use it for is tracking the time I work on client projects. My gut says that’s the most common use of it, but I’m sure there are other uses I haven’t thought of.
This Justin. This looks amazing.
The standard Timer Block is a bit clunky to use.
I plan on using it for Time Tracking my tasks - what gets measures gets managed!
This Justin. This looks amazing.
The standard Timer Block is a bit clunky to use.
I plan on using it for Time Tracking my tasks - what gets measures gets managed!
Welcome to the community, @Amit_Patel1! :grinning_face_with_big_eyes: Glad you like it! Keep an eye on this space, as I’ve got an alternate version that I plan on sharing soon that works via automation so that the sidebar won’t open when it’s triggered.
Hi Justin. This was very useful. Thanks for posting it here. I have a question. Have you found a way to run the script without the application area opening? Thanks.
Hi Justin. This was very useful. Thanks for posting it here. I have a question. Have you found a way to run the script without the application area opening? Thanks.
Short answer: Yes…sorta. Instead of triggering it via a button, I chose to set it up as an automation—more accurately two automations—triggered by a single-select. I still have plans (that have been floating around my noggin for ages) to document the setup in more detail, but using automations is the only way to keep the app sidebar closed.
That’s an interesting idea. I tried running the same script as an automation, but it failed for me. I suspect that it’s losing focus and isn’t “in” any record when it runs, but you must know how to get around that.
That’s an interesting idea. I tried running the same script as an automation, but it failed for me. I suspect that it’s losing focus and isn’t “in” any record when it runs, but you must know how to get around that.
The exact same script won’t work. To make it work in an automation context requires some changes to the script, and and as I said, it actually takes two scripts: one to start the timer, the other to stop it.
The automation knows exactly which record triggered it. That info has to be passed from the trigger to the script using the input mechanism designed for script actions.
As I said above, I’ve got plans to share the details on how to build this out, but it’s going to take a while to outline it all. I might be able to get to it sometime during this holiday break, but I can’t make any promises.
Thank you so much!! This is fantastic, is there an easy way to keep a timestamp (with the date) in the json array as well? So we can do other calculations such as monthly time tracked for a record?
Thank you so much!! This is fantastic, is there an easy way to keep a timestamp (with the date) in the json array as well? So we can do other calculations such as monthly time tracked for a record?
@SamA Each entry in the the JSON array is already a timestamp. It’s just represented as the number of milliseconds since January 1, 1970 (created using the getTime() method on a Date object). If you want to use these values in a script of your own, make a new Date object, then use the setTime() method to set that object using a number from the array. Each pair of numbers represents a start and stop time. Get the difference in each pair, add them all up, and you’ve got the total elapsed time. To isolate totals by month would take a little more work, but it’s doable.
@SamA Each entry in the the JSON array is already a timestamp. It’s just represented as the number of milliseconds since January 1, 1970 (created using the getTime() method on a Date object). If you want to use these values in a script of your own, make a new Date object, then use the setTime() method to set that object using a number from the array. Each pair of numbers represents a start and stop time. Get the difference in each pair, add them all up, and you’ve got the total elapsed time. To isolate totals by month would take a little more work, but it’s doable.
Thank you for your reply Justin, I’ve created an object that holds a few other values (category and current user) in there as well…
Works perfectly. Thank you!
The exact same script won’t work. To make it work in an automation context requires some changes to the script, and and as I said, it actually takes two scripts: one to start the timer, the other to stop it.
The automation knows exactly which record triggered it. That info has to be passed from the trigger to the script using the input mechanism designed for script actions.
As I said above, I’ve got plans to share the details on how to build this out, but it’s going to take a while to outline it all. I might be able to get to it sometime during this holiday break, but I can’t make any promises.
Justin, Do you have the two scripts mentioned above you can share for creating this via an automation?