0

I have borrowed a fairly complex JS stopwatch and am trying to report the resulting time to my Rails app's database. I have consulted many similar SO posts, but haven't been able to get it working.

Here is my ERB:

<%= form_for @new_log do |f| %>
...
<div class="row text-center">
   <div class="btn-white" id="startTime" style="display: inline-block;">
        <h4 value="start" onclick="start();">Start Timer</h4>
    </div>
    <div style="display: inline-block;">
        <span id="time" style="color: white"></span><br>
        <span class="btn-white" value="reset" onclick="reset()">Reset</span>
    </div>
    <div class="btn-white" id="stopTime" style="display: inline-block;">
        <h4 value="stop" onclick="stop();">Stop Timer</h4>
    </div>
    <%= f.hidden_field :duration, id: "duration" %>

         ...

    <%= f.submit "Record My Log", id: "submit", class: "btn-ghost" %>

<% end %>

Here's the JS:

<script> // STOPWATCH
    var clsStopwatch = function() {
        // Private vars
        var startAt = 0;    // Time of last start / resume. (0 if not running)
        var lapTime = 0;    // Time on the clock when last stopped in milliseconds

        var now = function() {
                return (new Date()).getTime(); 
            }; 

        // Public methods
        // Start or resume
        this.start = function() {
                startAt = startAt ? startAt : now();
            };

        // Stop or pause
        this.stop = function() {
                // If running, update elapsed time otherwise keep it
                lapTime = startAt ? lapTime + now() - startAt : lapTime;
                startAt = 0; // Paused
            };

        // Reset
        this.reset = function() {
                lapTime = startAt = 0;
            };

        // Duration
        this.time = function() {
                return lapTime + (startAt ? now() - startAt : 0); 
            };
    };

    var x = new clsStopwatch();
    var $time;
    var clocktimer;

    function pad(num, size) {
        var s = "0000" + num;
        return s.substr(s.length - size);
    }

    function formatTime(time) {
        var h = m = s = ms = 0;
        var newTime = '';

        h = Math.floor( time / (60 * 60 * 1000) );
        time = time % (60 * 60 * 1000);
        m = Math.floor( time / (60 * 1000) );
        time = time % (60 * 1000);
        s = Math.floor( time / 1000 );
        ms = time % 1000;

    newTime = pad(h, 2) + ':' + pad(m, 2) + ':' + pad(s, 2) + ':' + pad(ms, 3);
    return newTime;

    // THIS IS THE PART I ADDED, WHICH IS NOT WORKING
    $('#submit').on('click', function() {
      $('#duration').val(newTime);
    });
    // MY ADDITION ENDS HERE
}

function show() {
    $time = document.getElementById('time');
    update();
}

function update() {
    $time.innerHTML = formatTime(x.time());
}

function start() {
    clocktimer = setInterval("update()", 1);
    x.start();
}

function stop() {
    x.stop();
    clearInterval(clocktimer);
}

function reset() {
    stop();
    x.reset();
    update();
}
</script>

Hopefully this will be a fairly simple fix for someone with a better eye for JS than mine. Currently the stopwatch and the form submission still work, but the :duration still gets recorded into the database as nil.

Thanks for any help you can spare!

1 Answer 1

0

Your event method never gets called because the formatTime function returns newTime before it can reach it. Try moving the click function out of the formatTime function. Remember to set the return value of formatTime to a variable because newTime will be out of scope.

Sign up to request clarification or add additional context in comments.

2 Comments

I changed it to var newTime and tried the onclick val change outside of the function and it was still nil. I tried the onclick right before the return and the value was 0 regardless of the value of newTime. Thoughts?
Putting a console.log(newTime); right before the return newTime shows a value of 00:00:00:000 no matter what the stopwatch says. Does this help matters any?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.