ZombieDivision
ZombieDivision

Reputation: 183

Rounding times in time inputs to full hours or half-times

I need:

XX:01 through XX:14 to round down to XX:00

XX:15 through XX:29 to round up to XX:30

XX:31 through XX:44 to round down to XX:30

XX:45 through XX:59 to round up to (XX+1):00

Notes:

  1. I gave only two cases in the code, ultimately I have more of them
  2. For example, I added additional inputs in the code that are not used, they are not valid
  3. They must check automatically if it has been entered.

My code html:

<table>

<tr class="day"> 
  <td class="forUser1"><input type="time" class="start" id="start_1"></td>
  <td class="forUser2"><input type="time" class="end"  id="end_1"></td>
</tr>

<tr class="day">
  <td class="forUser1"><input type="time" class="start"  id="start_2"></td>
  <td class="forUser2"><input type="time" class="end" id="end_2"></td>
</tr>

</table>

I tried:

funtion dist (parting) {
dist = parting.split(":");
const distDate = new Date(0, 0, 0, dist[0], dist[1], 0);
(...)
}


document.querySelector('table').addEventListener('change', function(e) {
  const classList = e.target.classList
  if (classList.contains('start') || classList.contains('end')) {

    const tr = e.target.parentNode.parentNode
    const [start, end] = [...tr.querySelectorAll('.start,.end')]
    (...)
  }
})

I thought that this time should be divided into individual components, but honestly I will take every good way out of this situation

Upvotes: 1

Views: 668

Answers (2)

AndrewL64
AndrewL64

Reputation: 16311

You can just get all the input elements using the querySelectorAll() method and then add an change listener to each one which will run a function called say, roundFunc that will round the numbers for you and then assigned the new rounded numbers back to the input value.

Check and run the following Code Snippet or open this JSBin for a practical example of the above approach:

const timeInputs = document.querySelectorAll('table input.start, table input.end');

const roundFunc = e => {
  let x = e.target.value.split(':');
  if (x[1] > 00 && x[1] < 15) {
    x[1] = "00";
  } else if (x[1] > 44 && x[1] < 60) {
    x[0] = x[0] < 10 ? "0" + (parseInt(x[0]) + 1) : parseInt(x[0]) + 1;
    x[1] = "00";
  }
  else {
    x[1] = "30";
  }
  e.target.value = x.join(':');
}

timeInputs.forEach(input => {
    input.addEventListener('change', roundFunc);
});
<table>
  <tr class="day"> 
    <td class="forUser1"><input type="time" class="start" id="start_1"></td>
    <td class="forUser2"><input type="time" class="end"  id="end_1"></td>
  </tr>

  <tr class="day">
    <td class="forUser1"><input type="time" class="start"  id="start_2"></td>
    <td class="forUser2"><input type="time" class="end" id="end_2"></td>
  </tr>
</table>


However, it would be cleaner to round it off when the data is being submitted tbh since the end-user won't end up confused by the change of numbers as they typed. To round the numbers when you're ready to send the data to your server, you can just run the above function roundFunc() right before you are going to submit the data instead.

Upvotes: 1

domsson
domsson

Reputation: 4681

It might not be the most elegant, but it seems to work:

let start = document.querySelector(".start");
start.addEventListener("change", roundTime);

/*
  01:00 .. 01:14 -> 01:00
  01:15 .. 01:44 -> 01:30
  01:45 .. 01:59 -> 02:00
*/
function roundTime(event) {
  let time = event.target.value.split(":");
  let hours = parseInt(time[0]);
  let mins = parseInt(time[1]);

  if (mins < 15) {
    mins = 0;
  } else if (mins < 45) {
    mins = 30;
  } else if (mins < 60) {
    mins = 0;
    hours = (hours + 1) % 24;
  }

  let rounded = [hours.toString().padStart(2, '0'), mins.toString().padStart(2, '0')].join(":");
  let result = document.querySelector(".result");
  event.target.value = rounded;
}
<input type="time" class="start">

Upvotes: 1

Related Questions