Efficiently transferring time values from dynamically created list items to an input box using JavaScript

Is there a way to store a dynamically generated time value from an li element into an input box using JavaScript? I have a basic timer functionality on my website that includes starting, stopping, pausing, taking time snaps, and resetting them. These time snaps are displayed as list items (li) on the webpage. While everything else is working smoothly, I am facing difficulty in clicking on a displayed time snap and transferring its value to an input box for later saving it to a database.

var items = document.querySelectorAll("#list li");
      for (var i = 0; i < items.length; i++) {
        items[i].onclick = function () {
          document.getElementById("inptSnap").value = this.innerHTML;
        };
      }

This is how the HTML structure looks like:

<div class="container">
      <div class="timeDisplay">00:00:00</div>

      <button id="begin">Start</button>

      <button id="hold">Pause</button>

      <button id="end">Stop</button>

      <button id="timeSnap">Time Snap</button>
      <button id="resetSnap">Reset Time Snap</button>

      <ul id="list" class="laps"></ul>

      <div>
        <input type="text" id="inptSnap" />
      </div>
    </div>

Below is the complete timer script along with the attempt to select a value onclick:

// Timer and button event listener setup

// Function definitions for start, run, stop, stopTimer, pause; displayTimeCount; snap; resetSnaps
...
// Script to put lap into input box
...

If you want to view the code and interact with it, check out the CodePen Link here.

Your suggestions and advice on this matter would be greatly appreciated, thank you!

Answer №1

You have the option to implement something like this...

PS: It might be beneficial to reconsider the ergonomics of your button, I made some revisions.

const
  btStartPause = document.querySelector('#container button:nth-of-type(1)')
, btStopClear  = document.querySelector('#container button:nth-of-type(2)')
, btSnap       = document.querySelector('#container button:nth-of-type(3)')
, snapList     = document.querySelector('ol')
, inptSnap     = document.querySelector('input#inptSnap')
, chrono = ((dZTime='#container time') =>
  {
  const
      displZone  = document.querySelector(dZTime)
    , chronoZero = '00:00:00.000'
    , one_Sec    = 1000
  //, one_Min    = one_Sec * 60
  //, one_Hrs    = one_Min * 60
    , n_Dgts     = (n,t) => `${t}`.padStart(n,'0')
    ;
  let startTime   = null
    , timeElapsed = 0
    , pausedTime  = 0
    , reqRef      = null
    , reqPause    = false
    , stoped      = false
      ;
  displZone.textContent = chronoZero

  function reqLoop(timeStamp)  // timeStamp is float
    {
    startTime ??= timeStamp  // Logical nullish assignment (??=)

    if (stoped)
      {
      cancelAnimationFrame(reqRef)
      return
      }
    if (reqPause) 
      { 
      pausedTime = (timeStamp - startTime) - timeElapsed;
      }
    else
      {
      timeElapsed = ((timeStamp - startTime) - pausedTime) | 0 // get integer part of float
      let
        Tms = timeElapsed % one_Sec
      , tim = (timeElapsed - Tms) / one_Sec
      , T_s = tim % 60
      , T_m = 0
      , T_h = 0
        ;
      tim = (tim - T_s) / 60 
      T_m = tim % 60
      T_h = (tim - T_m) / 60 

      displZone.textContent = `${n_Dgts(2,T_h)}:${n_Dgts(2,T_m)}:${n_Dgts(2,T_s)}.${n_Dgts(3,Tms)}`
      }
    requestAnimationFrame( reqLoop )
    }
  const jso =
    { dispSz:      chronoZero.length
    , getVal: ()=> displZone.textContent 
    , start()      { reqRef   = requestAnimationFrame(reqLoop) }
    , pause(OnOff) { reqPause = OnOff }
    , stop()       { stoped   = true  }
    , RaZ()
      {
      startTime   = null
      timeElapsed = 0
      pausedTime  = 0
      reqRef      = null
      reqPause    = false
      stoped      = false
      displZone.textContent = chronoZero
      }
    }
  Object.freeze(jso)
  return jso
  })()
  ;
btStartPause.onclick =_=>
  {
  if (btStartPause.classList.toggle('pause') )
    {
    btStopClear.disabled = false 

    if ( btStartPause.dataset.lib !== 'continue' )
      {
      btStartPause.dataset.lib = 'continue'
      chrono.start()
      }
    else
      chrono.pause(false)
    }
  else
    {
    btStopClear.disabled = true 
    btStopClear.classList.remove('clear') 
    chrono.pause(true)
    }
  }
btStopClear.onclick =_=>
  {
  if (btStopClear.classList.toggle('clear') )
    {
    btStartPause.disabled    = true
    btStartPause.dataset.lib = 'start'
    btStartPause.classList.remove('pause')
    chrono.stop()   
    }
  else
    {
    btStartPause.disabled = false
    btStopClear .disabled = true 
    chrono.RaZ()
    }
  }
btSnap.onclick =_=>
  { 
  snapList
  .appendChild( document.createElement('li'))
  .innerHTML = chrono.getVal() 
              + '<span title="delete"> &#10006; </span>'
              + '<span title="copy"> &#x2398 </span>'
  }
snapList.onclick =({target}) =>
  {
  if (!target.matches('li > span'))
    {
    inptSnap.value = target.closest('li').textContent.substring(0, chrono.dispSz)
    inptSnap.focus()
    return
    } 

  if (target.matches('span[title=delete]'))
    {
    target.closest('li').remove()
    }

  if (target.matches('span[title=copy]'))
    {
    let origin = target.closest('li')
    copySomething ( origin.textContent.substring(0, chrono.dispSz), origin )
    }
  }
async function copySomething(toCopy, el ) 
  {
  try
    {
    await navigator.clipboard.writeText(toCopy);
    el.classList.add('copyOK')
    setTimeout(() => { el.classList.remove('copyOK')}, 1200);
    }
  catch (err) 
    {
    el.classList.add('copyBad')
    setTimeout(() => { el.classList.remove('copyBad')}, 1200);
    console.error('Failed to copy :/', err);
    }
  }
body {
  font-family : Arial, Helvetica, sans-serif;
  font-size   : 16px;
  }
time {
  display        : block;
  font-size      : 1.4rem;
  margin         : .6rem 1rem;
  letter-spacing : .2rem;
  }
ol {
  list-style : none;
  font-size  : 1.6rem;
  padding    : 0;
  margin     : 1.5rem;
  width      : 15rem;
  list-style-type: decimal;
  }
li {
  border    : 1px solid lightblue;
  padding   : .3rem .6rem;
  position  : relative;
  cursor    : pointer;
  }
li::marker {
  font-size : .9rem;
  color     : darkslategray;
  }
li span {
  float     : right;
  margin    : 0 0 0 .3em;
  font-size : 1.2rem;
  color     : darkslategray;
  }
li span[title=delete]:hover {
  color     : crimson;
  }
li span[title=copy]:hover {
  background : white;
  color      : darkblue;
  }
#container button {
  min-width      : 4.4rem;
  text-transform : capitalize;
  }
#container button:before {
  content : attr(data-lib)
  }
#container button.pause:before {
  content : 'pause'
  }
#container button.clear:before {
  content : 'clear'
  }
li:hover {
  background : lightblue;
}
li.copyOK::after,
li.copyBad::after {
  position   : absolute;
  display    : block;
  font-size  : .8rem;
  top        : 1.2rem;
  left       : 11rem;
  padding    : .1rem .2rem;
  }
li.copyOK::after {
  content    : 'copied';
  background : lightgreen;
  }
li.copyBad::after {
  left       : 1rem;
  content    : 'Failed to copy :/';
  background : lightcoral;
  }
<input type="text" id="inptSnap" >
<hr>

<div id="container">
  <time datetime="00:00:00.000">00:00:00.000</time>
  <button data-lib="start"><!-- start / continue / pause --></button>
  <button data-lib="stop" disabled><!-- stop / clear --></button>
  <button>snap</button>
</div>
<ol></ol>

for more information : Fastest way to cast a float to an int in javascript?

Answer №2

It seems like you're looking for a way to manage time values.

 var startButton = document.getElementById("begin");
      startButton.addEventListener("click", beginTimer);

      var stopButton = document.getElementById("end");
      stopButton.addEventListener("click", endTimer);

      var pauseButton = document.getElementById("hold");
      pauseButton.addEventListener("click", pauseTimer);

      var snapButton = document.getElementById("timeSnap");
      snapButton.addEventListener("click", takeSnap);

      var resetSnapButton = document.getElementById("resetSnap");
      resetSnapButton.addEventListener("click", clearSnaps);

      var milliseconds = 0,
        seconds = 0,
        minutes = 0;
      var timerInterval;
      var displayElement = document.querySelector(".timeDisplay");
      var lapsContainer = document.querySelector(".laps");

      function beginTimer() {
        if (!timerInterval) {
          timerInterval = setInterval(updateTime, 10);
        }
      }

      function updateTime() {
        displayElement.textContent = formatTime();

        milliseconds++;
        if (milliseconds == 100) {
          milliseconds = 0;
          seconds++;
        }
        if (seconds == 60) {
          seconds = 0;
          minutes++;
        }
      }

      function endTimer() {
        stopTimer();
        milliseconds = 0;
        seconds = 0;
        minutes = 0;
        displayElement.textContent = formatTime();
      }
      
      function stopTimer() {
        clearInterval(timerInterval);
        timerInterval = false;
      }

      function pauseTimer() {
        stopTimer();
      }

      function formatTime() {
        return (
          (minutes < 10 ? "0" + minutes : minutes) +
          ":" +
          (seconds < 10 ? "0" + seconds : seconds) +
          ":" +
          (milliseconds < 10 ? "0" + milliseconds : milliseconds)
        );
      }

      function takeSnap() {
        if (timerInterval) {
          var inputField = document.createElement("input");
          inputField.value = formatTime();
          lapsContainer.appendChild(inputField);
        }
      }

      function clearSnaps() {
        lapsContainer.innerHTML = "";
      }

      // Script to put lap into input box
      var lapItems = document.querySelectorAll("#list li");
      for (var i = 0; i < lapItems.length; i++) {
        lapItems[i].onclick = function () {
          document.getElementById("inptSnap").value = this.innerHTML;
        };
      }
 .timeDisplay {
        font-size: 32px;
      }
      ul li {
        list-style: none;
        font-size: 32px;
      }
      .container {
        width: 400px;
        margin: auto;
      }
<div class="container">
      <!--               Different App            -->

      <div class="timeDisplay">00:00:00</div>

      <button id="begin">Start</button>

      <button id="hold">Pause</button>

      <button id="end">Stop</button>

      <button id="timeSnap">Time Snap</button>
      <button id="resetSnap">Reset Time Snap</button>

      <ul id="list" class="laps">
        
      </ul>

      <div>
        <input type="text" id="inptSnap" />
      </div>
    </div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with Google Interactive Charts failing to load after UpdatePanel refresh

Desperately seeking assistance! I have spent countless hours researching this issue but have hit a dead end. My dilemma involves using the Google Interactive Charts API within an UpdatePanel to dynamically update data based on dropdown selection changes. H ...

What's the reason behind this file not opening?

When I try to insert this code into files index.html, style.css, and app.js, the page refuses to open. The browser constantly displays a message saying "The webpage was reloaded because a problem occurred." I am using a MacBook Air with macOS Big Sur and a ...

Submitting selected options from radio buttons to the server-side using HTML

I'm facing a challenge that requires some guidance. Here is the html code I am working with: Avatar: <br /> <input type="radio" id="avatar" name="avatar" value="Option1"/><img src="" alt=""> <input type="radio" id="avatar" name ...

Validation within nested Joi schemas

Need help validating a nested object conditionally based on a parent value. const schema = Joi.object({ a: Joi.string(), b: Joi.object({ c: Joi.when(Joi.ref('..a'), { is: 'foo', then: Joi.number().valid(1), otherwise: Jo ...

How to eliminate a hyperlink from an HTML element with the help of JQuery

Recently, I was assigned to revamp a website for the company I work for. However, upon closer inspection, I realized that the website is quite messy and relies heavily on templates, resulting in certain elements being auto-generated as active links. The i ...

Designing numerous vertical lists in HTML

I need help with displaying multiple lists vertically using HTML For example: +--------+---------------------------------------------+--+ | Global | Region Country Currency Account Type Entity | | +--------+---------------------------------------------+ ...

Update nested child object in React without changing the original state

Exploring the realms of react and redux, I stumbled upon an intriguing challenge - an object nested within an array of child objects, complete with their own arrays. const initialState = { sum: 0, denomGroups: [ { coins: [ ...

Prevent further triggering of the .click function when the user clicks repeatedly

Is there a way to prevent the .click function from executing if the user clicks too many times? This is my current code: $('button').click(function() { $('#bg').fadeToggle('200'); }); Check out the jsfiddle DEMO ...

creating a personalized tooltip for every item within a dynamically generated @html.dropdownfor control in mvc3

Currently, I am developing a web project using MVC 3 and Razor in C#. In my code, I have implemented @Html.DropDownListFor to dynamically display items. Now, I would like to add tooltips for each item displayed by @Html.DropDownListFor. Here is the relev ...

The issue with using HTML code inside a variable that is passed into a partial view is that the code is not being

I have created a partial view to show the page header, which takes in two variables - an Icon and a title. The code for pageHeader.blade.php is as follows: <div class="page-header"> <div class="row"> <!-- Page header, center on small sc ...

simulating interaction with databases within API routes

I am currently working on developing a full stack application using NextJS along with a MySQL database. Within my API routes, I interact with this database by making calls to various functions such as createOne(), which is responsible for creating new inst ...

Backbone.js experiencing synchronization issues exclusively in Internet Explorer

Can anyone confirm if they have encountered this issue before? I'm unsure how to elaborate further as it seems to be the only symptom. Additionally, it does not sync correctly in Internet Explorer. ...

AngularJS selection controls: checkbox and dropdown menus

Can someone provide an example that includes a dropdown menu and checkboxes? The options in the checkbox list should match the data in the dropdown. Once a value is selected from the dropdown, the corresponding checkbox option should be automatically chec ...

The XMLHttpRequest function successfully logs data in the console, but does not return the data within the function itself

I find it puzzling that the console.log statement at the end of the code snippet displays the data as expected, while the return optiondata line does not. function populate_selectbox() { var ajaxRequest; try { // Opera 8.0+, Firefox, S ...

Issue with accessing container client in Azure Storage JavaScript library

When working on my Angular project, I incorporated the @azure/storage-blob library. I successfully got the BlobServiceClient and proceeded to call the getContainerClient method, only to encounter this error: "Uncaught (in promise): TypeError: Failed ...

Difficulty encountered in setting the background image to cover the entire screen

I'm facing difficulties while creating a parallax website. Specifically, I'm having troubles with CSS. Here's the HTML code: <div id="skrollr-body"> <div class="subnav"> <ul id="nav"> ...

Wcf Service does not define Angular JS methods

I am utilizing a WCF Service within an AngularJS application. The WCF Service is functional, and I am attempting to display a list of user records from a SQL database. However, upon running the application, I encountered the following errors: angular.js: ...

The items are misaligned in a horizontal position

The 4 divs are styled with a width of 23% and displayed using inline-block. They have a fixed height of 220px and no margin applied. However, the issue arises as they are not aligning horizontally Despite attempting to adjust the height and width paramete ...

Using React.js to add MongoDB documents into the database

Is there a way to directly insert documents into a MongoDB collection from a React component? I have been working on a personal project, which is a chat web application used for training purposes. For instance, when a user wants to post a new message in a ...

When using the .after() method to add jQuery elements, keep in mind that they will not trigger any

Here is the snippet of code provided: <s:file name="upload" id="upload"></s:file> $('input[id^="upload"]').change(function(){ alert("aa"); $(this).after('<input type="file" name="upload_3" id="upload_3"/> ...