Stopwatch built within form

  • 0
  • 2
  • Question
  • Updated 5 months ago
  • In Progress



I have the following form above for a fabrication department. The fabrication operator must fill out the form whenever he/she starts a new job. Instead of having the "Clock in" and "Clock out" fields, I'd like to create a stopwatch, similar to the one in the video below. I'd like the operator to be able to start and stop a timer whenever they'd like. The duration time would automatically appear in a field titled "Duration". I've looked into zapier.com and workato.com . I've also looked for other services, but most are very expensive and it'd be better to just let the operator manually opening their own stopwatch. Does anyone know any stopwatch that could be integrated into a form? I've found a quickbase app that is a timer, but that would be just as much work for the operator as manually opening their own stopwatch. Does anyone have any hints/tricks/resources?


Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb

Posted 6 months ago

  • 0
  • 2
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
I have a novel solution and halfway through creating a demo. The demo will work from a report or view record page and timers will continue to count if started even when the page holding the counters is not displayed! And you will be able to have multiple counters active at the same time.
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Thanks Dan. I've seen some of your demos and their very useful. When do you think you'll finish the demo?
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
Probably by the end of the week - I tend to work on these demos at odd times and refine it. The code is actually the easiest part. Here is a screenshot of what I am playing with now:




Normally you would not see the fields [Last Start Time] and [Last End Time] as these fields store an internal state of milliseconds values and allows the timer to "calculate the passage of time" even if the page is not currently being displayed.
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Hey Dan looks great. I've found different javascripts for stopwatches, but this one seems to have the most features https://codepen.io/_Billy_Brown/pen/dbJeh . I found one of the challenges is creatinga stopwatch that can have "laps" and can start and stop and start again at any moment.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
>creating a stopwatch that can have "laps" and can start and stop and start again at any moment.

I probably won't go quite so fancy on the display as that demo does because my intention is to have the ability to have multiple timers displayed in a report as well as a single timer on a view page.

This isn't going to be too complicated in the end. It is the practical workflow and navigation that takes a little time to nail.

By storing the last start and last stop times in fields you can resume the display of the counter and it will just display the current elapsed time and continue counting (if it had been started) despite the fact that the page may have been closed in the intervening time.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
This was pretty easy to do. Here you go:




StopWatch
https://haversineconsulting.quickbase.com/db/bnsjt3e2s?a=td

Paste Database
https://haversineconsulting.quickbase.com/db/bgcwm2m4g?a=dr&rid=666

Notes

(1) I used the library FlipClock:

FlipClockJS
http://flipclockjs.com/

(2) This demo is intended for a user to observe and manipulate their own timers. If multiple users are manipulating the same timer there will probably be some confusion as the underlying state of the time may become inconsistent with what is displayed for another user.
(Edited)
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Got it working! Thank you for all of your help I appreciate it.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
You are a testament for others at the threshold of employing script in their QuickBase.
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Quick question for you, I'm calculating the duration of the stopwatch as Seconds([Last Saved Time]). But since I'm using the stopwatch in a form, the Last Saved Time only updates when the user saves and closes the form. How would I edit the formula so when the user presses the "Stop Timer" button, the Last Saved Time will update?
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
>But since I'm using the stopwatch in a form, the Last Saved Time only updates when the user saves and closes the form.

The script updates the three fields using the API - not through saving the new or edit native form.

The way I coded the script was for the timer to only operate on a report or a view page - not on an edit or new page. This eliminated the possibility of directly viewing or editing the state of the stopwatch.

When using script on a page there is a general rule I follow to not use the API to modify a field that is currently being displayed or edited on a native form. If you do so you can create an inconsistency for the user who might think a field has the displayed value but in reality it has been saved through the API.
(Edited)
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Hi Dan, sorry for the late response, I was out of town. Thank you for explaining how script should only be applied to a report or a view page. I changed the timers, so they're in a report. I'm still unsure where I put the calculation for the duration. I've put a photo of my timers page down below

Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
I tried calculating the duration as shown in the comment above. I made a field and did Seconds([Last Saved Time]). However, the duration isn't saved. Is there another way I could display the duration?
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
Seconds([Last Saved Time]) is the correct formula but it is only valid as the total elapsed time when the Timer is stopped. When the Timer is running the elapsed time is evolving and [Last Saved Time] merely represents the time the Timer was last stopped (or reset)..

The [Last Saved Time] is saved with the timer is Stopped or when Reset.
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
I put the formula in a duration field as shown below.




 But when I tried to start the timer and stop the timer at 8 seconds (as shown below), the duration field doesn't change. I understand the formula, but it's not working in the report. 

Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,954 Points 20k badge 2x thumb
If you wand to display the Duration field it will only be valid if the timer is stopped and you need to reload the page when stopped to display the correct value.

  $("a.QBU_Stop").on("click", function(event) {
    var rid = this.dataset.rid;
    $(`a.QBU_Start[data-rid=${rid}]`).css("visibility", "visible");
    $(`a.QBU_Stop[data-rid=${rid}]`).css("visibility", "hidden");
    clocks[rid].stop();
    var lastsavedtime = clocks[rid].getTime().time;
    $.post(dbidTimers, {
      act: "API_EditRecord",
      rid: rid,
      _fid_8: parseInt(new Date().getTime(), 10) / 1000,
      _fid_10: lastsavedtime 
    }).then(function() {
      document.location.reload(true);
    });
  });
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
So I added a code page named duration.js and copied in the above code you commented. Would I only need to change the  _fid_ ? Would I need to change anything else? Or would I just insert the code into my existing code page for the timer?




I changed my duration field to this, but the duration field on the table doesn't have anything in its column:





Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,694 Points 20k badge 2x thumb
My example did not use a formula field [Duration] = Seconds([Last Saved Time]).

If you choose to use and display such a field it will only hold a valid value when the timer is stopped,

My script set the [Last Saved Time] through the API when the timer was stopped and your [Duration] field will react to this change. However, you don't want to  create a situation where a displayed value is different than the stored value. So all you have to do is reload the page when the timer is stopped and when the page refreshes the stored value of [Duration] will once again be in sync with the displayed value of [Duration]

This is a generic concern. If you are using the API to change a field's value you never want to get into a situation where the displayed value is different than the stored value or it will cause confusion to your users,
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
>My script set the [Last Saved Time] through the API when the timer was stopped and your [Duration] field will react to this change. 

How can the duration field automatically change if it's not referenced in the timer field's formula or in the script? I understand you reference the last start time, last saved time and last stop time in the formula, but the duration field isn't referenced.
Photo of Ⲇanom the ultimate (Dan Diebolt)

Ⲇanom the ultimate (Dan Diebolt), Champion

  • 27,694 Points 20k badge 2x thumb
>How can the duration field automatically change

It is a formula field so if the input changes (ie [Last Saved Time]) the formula could calculate a new value. I do change [Last Saved Time] via the API when the timer stop button is clicked.
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
This is the very last part I need help with. I've tried editing the javascript myself, but I don't have a lot experience with it. Do you have any other suggestions to the comment below? It's greatly appreciated
(Edited)
Photo of Jessica Haskins

Jessica Haskins

  • 366 Points 250 badge 2x thumb
Since [Duration] is a duration formula field that is dependent on [Last Saved Time] , then this is all I need to have in as the duration, correct? 




And since I need to reload the page, my code page should remain the same as the pastie, but include the highlighted part, correct?





But when I create a new timer, I try to start the timer and let it go for a 7 seconds. When I stop the timer, the page refreshes and the timer resets just goes back to 0 and the duration field doesn't save as 7 seconds. Below is a picture of what the table looks like, when it automatically refreshes. Why is this? Is it because of the script where it resets the all of the _fid_ as 0?

(Edited)