how to implement multiple countdowns on the same DOM element - javascript

I have a DOM element, that contains values (milliseconds) from my database, and I want to implement a countdown for the values. For example, I can have 4 product deals in a section, with different duration in milliseconds, and i want to dynamically create different countdowns(HH:mm:ss) for each deal according to its duration.
Currently, the duration values (milliseconds) are stored in a hidden input field for each deal in the section.
<input type="hidden" name="" id='duration' value="{{this.deals.duration}}">
What i tried (it works fine for only one product deal). I used moment.js for the duration. and also for the countdown here:
<script type="text/javascript">
$(document).ready(function(){
console.log($('#duration').val());
var interval = 1000;
var durations = $('#duration').val();
setInterval(function(){
durations = moment.duration(durations - interval, 'milliseconds');
// console.log(durations);
$('#countdown').text(durations.hours() + ":" + durations.minutes() + ":" + durations.seconds())
}, interval);
})
</script>
Thanks very much :)

To add another answer to this question...
No dependencies (jQuery,Moment.js) and only for 24 hour duration (days,months,years are not calculated).
function countDown(elClass) {
let labels = document.querySelectorAll(elClass);
let now = Date.now();
labels.forEach((label,key) => {
let duration = document.getElementById(label.getAttribute('for')).value;
if(duration <= 86400000) {
let futureDate = now + parseInt(duration);
let counterInterval = setInterval(() => {
let diff = futureDate - Date.now();
if(diff <= 0) {
clearInterval(counterInterval);
return;
}
if(diff > 0) {
let milliseconds = diff%1000;
let seconds = parseInt(diff/1000)%60;
let minutes = parseInt(diff/(60*1000))%60;
let hours = parseInt(diff/(60*60*1000))%24;
label.innerHTML = hours.toString().padStart(2, '0')+':'+minutes.toString().padStart(2, '0')+':'+seconds.toString().padStart(2, '0')+'<br>';
}
},1000);
}
});
}
countDown('.countdown');
<input type="hidden" name="a" id="a" class='duration' value="5000"><label for="a" class="countdown"></label>
<input type="hidden" name="b" id="b" class='duration' value="15000"><label for="b" class="countdown"></label>
<input type="hidden" name="c" id="c" class='duration' value="190000"><label for="c" class="countdown"></label>
<input type="hidden" name="d" id="d" class='duration' value="2003200"><label for="d" class="countdown"></label>
<input type="hidden" name="e" id="e" class='duration' value="20067100"><label for="e" class="countdown"></label>
<input type="hidden" name="f" id="f" class='duration' value="86023104"><label for="f" class="countdown"></label>

$(document).ready(function(){
var interval = 1000;
setInterval(function(){
$('.duration').each(function () {
var t = Number($(this).val()) - interval;
if (t>=0) {
var d = moment.duration(t, 'milliseconds');
$(this).next('.countdown').text([
String(d.hours()).padStart(2,'0'),
String(d.minutes()).padStart(2,'0'),
String(d.seconds()).padStart(2,'0')
].join(':'));
$(this).val(t);
}
});
}, interval);
})
input + span {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<input type="hidden" name="a" class='duration' value="5000"><span class="countdown"></span>
<input type="hidden" name="b" class='duration' value="15000"><span class="countdown"></span>
<input type="hidden" name="c" class='duration' value="20000"><span class="countdown"></span>

Related

JS time calculation add and set value

I'm making a page to easily calculate when I could go home from work. The page should set a start date when loaded. That way I don't have to know when I started working and just open my browser. Then by clicking one of the buttons it should just add some hours.
The example is one of the many things I've tried already. But this one is close I think. Any suggestions are welcome. I didn't include jquery because of the small scale this has.
function reset() {
var date = new Date();
var hour = date.getHours(),
min = date.getMinutes();
hour = (hour < 10 ? "0" : "") + hour;
min = (min < 10 ? "0" : "") + min;
var timestamp = hour + ":" + min;
document.getElementById("start_time").value = timestamp;
}
function add_time_76() {
var start = document.getElementById("start_time").value;
document.getElementById("end_time").value = start + 7, 6;
}
function getTotal() {
var start = document.getElementById("start_time").value;
var end = document.getElementById("end_time").value;
document.getElementById("total").value = end - start;
}
<body onload="reset()">
<p>Start time: <input name="start_time" type="time" /></p>
<p>Time to go home: <input name="end_time" type="time" /></p>
<p>Total hours: <input type="text" name="total" readonly></p>
<button onclick="add_time_76()">Add 7,6h</button>
<button onclick="add_time_8()">Add 8h</button>
<br><br>
<button onclick="getTotal()">Calculate Total</button>
<br><br>
<button onclick="reset()">Reset</button>
</body>
The time fields aren't getting populated when I want them to be.
Just add a id to your inputs.
<p>Start time: <input id="start_time" name="start_time" type="time" /></p>
<p>Time to go home: <input id="end_time" name="end_time" type="time" /></p>
<p>Total hours: <input id="total" type="text" name="total" readonly></p>

Calculate the values of input where each input has different prices. Any shorter code for this?(javascript only)

The code below is working fine but what if there are 100 inputs? any shorter way to do this?
function checkTotal() {
var a = document.getElementById("sandwich").value;
var b = document.getElementById("burger").value;
var c = document.getElementById("cake").value;
var d = document.getElementById("coffee").value;
document.getElementById("total").value = parseInt(a) * 10 + parseInt(b) * 5 + parseInt(c) * 15 + parseInt(d) * 20;
}
<form role="form" name="listForm">
<label>Sandwich</label>
<input type="number" id="sandwich" value="0" onkeyup="checkTotal()"><br>
<label>Burger</label>
<input type="number" id="burger" value="0" onkeyup="checkTotal()"><br>
<label>Cake</label>
<input type="number" id="cake" value="0" onkeyup="checkTotal()"><br>
<label>Coffee</label>
<input type="number" id="coffee" value="0" onkeyup="checkTotal()"><br> Total: <input type="text" size="2" name="total" id="total" value="0" />
</form>
1) Here each input article has a different price.
2) The value of the input should be mutiply with its price given(Eg. if the sandwich has a price:30, and user inputs value 2 it should calculte the total=price*input value.)
3) i have my code which is working fine but is the above code is the right way to do?
4) what if there are 100 of article inputs. is there shorter code or should i create variable for each one?
what if there are 100 of article inputs. is there shorter code or
should i create variable for each one?
You can maintain a map
var idPriceMap = {
"sandwich" : 20,
"burger" : 10,
"cake" : 5,
"coffee" : 10
};
You can iterate this and produce your value using reduce
var output = Object.keys( idPriceMap ).reduce( function(a,b){
var value = +document.getElementById( b ).value;
a += value * idPriceMap[ b ];
return a;
}, 0);
document.getElementById( "total" ).value = output;
Another way to try is to give your elements a class and some data attributes that can be retrieved by JavaScript using dataset. You can then use them to make your calculations. That way you get rid of ids and you just have to change the HTML code to add a new element.
function checkTotal() {
var total = 0,
foods = document.querySelectorAll('.food');
for (var i = 0; i < foods.length; i++) {
var food = foods[i],
name = food.dataset.item,
price = parseInt(food.dataset.price),
howMany = parseInt(food.value);
console.log(howMany, name, 'costs', (howMany * price));
total += howMany * price;
}
document.getElementById('total').value = total;
}
<form role="form" name="listForm">
<label>Sandwich</label>
<input class="food" data-item="sandwich" data-price="30" type="number" value="0" onBlur="checkTotal()"><br>
<label>Burger</label>
<input class="food" data-item="burger" data-price="10" type="number" value="0" onBlur="checkTotal()"><br>
<label>Cake</label>
<input class="food" data-item="cake" data-price="5" type="number" value="0" onBlur="checkTotal()"><br>
<label>Coffee</label>
<input class="food" data-item="coffee" data-price="15" type="number" value="0" onBlur="checkTotal()"><br>
Total: <input type="text" size="2" name="total" id="total" value="0" />
</form>
As a side note, you should give a try on Angular or Knockout which can help you to achieve those operations.

Automatic input sum with jQuery

I'm making a calculation of more fields and I would like to get the #price + # price2 automatic sum without any jQuery event.
I've been looking for a variety of tutorials but I just managed to get the sum with the click.
I would like her without the click, how can she do it?
function calcscore() {
score = 0;
$(".calc:checked,#TextBox4").each(function() {
score += Number($(this).val());
});
$("#sum").val(score)
$("#price").text(score.toFixed(2));
}
function add() {
var sum = 0;
$(".test").each(function() {
sum += +this.value;
});
return sum; // an add function shouldn't really "alert"
}
$(document).on("change", ".test", function() {
var sum = 0;
$(".test").each(function() {
sum += +$(this).val();
});
$("#price3").val(sum);
});
$(document).ready(function() {
$(".calc").change(function() {
calcscore();
});
$('#add').click(function() {
$("#price3").text(add().toFixed(2));
});
$("#TextBox1").datepicker({
minDate: 0,
maxDate: '+1Y+6M',
altField: "#arrivo",
altFormat: "DD, d MM, yy",
onSelect: function(dateStr) {
var min = $(this).datepicker('getDate'); // Get selected date
$("#TextBox2").datepicker('option', 'minDate', min || '0'); // Set other min, default to today
}
});
$("#TextBox2").datepicker({
minDate: '0',
maxDate: '+1Y+6M',
altField: "#partenza",
altFormat: "DD, d MM, yy",
onSelect: function(dateStr) {
var max = $(this).datepicker('getDate'); // Get selected date
$('#datepicker').datepicker('option', 'maxDate', max || '+1Y+6M'); // Set other max, default to + 18 months
var start = $("#TextBox1").datepicker("getDate");
var end = $("#TextBox2").datepicker("getDate");
var timeDiff = Math.abs((end - start));
var days = Math.ceil(timeDiff / (1000 * 3600 * 24));
$("#TextBox3").val(days);
if (days == 1) {
parseInt($("#TextBox4").val('10'), 10);
parseInt($("#price2").text('10'), 10);
} else if (days == 0) {
parseInt($("#TextBox4").val('10'), 10);
parseInt($("#price2").text('10'), 10);
$("#TextBox3").val('1');
} else if (days == 2) {
parseInt($("#TextBox4").val('12'), 10);
parseInt($("#price2").text('12'), 10);
} else if (days == 3) {
parseInt($("#TextBox4").val('14'), 10);
parseInt($("#price2").text('14'), 10);
} else if (days == 4) {
parseInt($("#TextBox4").val('16'), 10);
parseInt($("#price2").text('16'), 10);
} else if (days >= 5) {
var y = (days) * 4;
parseInt($("#TextBox4").val(y), 10);
parseInt($("#price2").text(y), 10);
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<form>
<div id="tipo-veicolo">
<input class="calc" type="radio" name="type" value="5"> Macchina
<input class="calc" type="radio" name="type" value="2"> Scooter
<input class="calc" type="radio" name="type" value="10"> Camion
</div>
<div class="variant">
<label>Cambio olio</label>
<input class="calc" type="checkbox" name="check1" id="check1" value="10" />
<label>Cambio gomme</label>
<input class="calc" type="checkbox" name="check1" id="check2" value="2" />
<label>Car valet</label>
<input class="calc" type="checkbox" name="check1" id="check3" value="12" />
</div>
<div id="selezione-data">
<div class="check-in">
<label>Check-In</label>
<input type="text" id="TextBox1" />
</div>
<div class="check-out">
<label>Check-Out</label>
<input type="text" id="TextBox2" />
</div>
<div class="numero-giorni">
<label>Numero Giorni</label>
<input type="text" id="TextBox3" value="0" />
<label>Arrivo</label>
<input type="text" id="arrivo" size="30">
<label>Partenza</label>
<input type="text" id="partenza" size="30">
</div>
</div>
<div class="totale">
<input class="test num1" name="totale" id="TextBox4" value="0" />
<input class="test num2" type="text" name="sum" id="sum" value="0"> Sum: <input type="text" class="sum" readonly="readonly">
</div>
</form>
<p>Total: PHP <span id="price">0</span></p>
<p>Total: PHP <span id="price2">0</span></p>
<p>Total: PHP <span id="price3">0</span></p>
<input id="add" type="button" value="add" />
Thank you and good day
Im not sure if I understand you correctly, but you can't do it without using any events.
You can achive automatic aggregation by using, for example, input event in jQuery.
Here is example of this:
$('.num1, .num2').on('input', function () {
$('.sum').val(parseInt($('.num1').val()) + parseInt($('.num2').val()));
});
Here is jfiddle.
Try this to achieve your goal, place it the end of document.ready event
$(document).ready(function() {
..
..
..
$("input").change(function() { // place it at the bottom of other events, this will listen for all inputs
$("#price3").text(add().toFixed(2)); // after input changes it will calculate
});
});
demo
Hope helps,

Display Leading Zeros On Input Number Fields

I have two input fields representing hours and minutes.
<input type="number" min="0" max="24" step="1" value="00" class="hours">
<input type="number" min="0" max="0.60" step="0.01" value="00" class="minutes">
Which display as:
0:0
Or:
5:3
Is there a way to display it as:
00:00
Or:
05:03
i.e in 24-hour data format (before people suggest it, I can't use type="time").
You can add an onchange attribute to your input tag, which calls a javascript function.
<script>
function myFunction() {
var minuteValue = document.getElementById("minutes").value;
if (minuteValue.length < 2) {
minuteValue = "0" + minuteValue;
}
alert(minuteValue);
}
</script>
<input id="minutes" onchange="myFunction()"/>
function formatNums(num){
if (nums < 10){
return "0" + num;
}
}
var formattedHours = formatNums(hours);
var formattedMinutes = formatNums(minutes);
NOTE: This method uses type="text" so be sure to convert back to a number if needed. Number(formattedHours);
Add a leading zero with a JavaScript function.
const hours = document.getElementById("hours");
const minutes = document.getElementById("minutes");
function addLeadingZero(value) {
return value.length < 2 ? "0" + value : value;
}
hours.addEventListener("input", function() {
hours.value = addLeadingZero(hours.value);
});
minutes.addEventListener("input", function() {
minutes.value = addLeadingZero(minutes.value);
});
<input type="number" min="0" max="24" value="00" id="hours" class="hours">
<input type="number" min="0" max="59" value="00" id="minutes" class="minutes">
simple is the best
`${number}`.padStart(2, '0')

Form with radio buttons and one input field. Calculate the value depending on radio button selcted

I would like to convert the temperature given in Celsius to Fahrenheit degrees or the other way round. I would like the unit to be chosen via radio button form and the converted units calculated with JS function. However, I am doing something wrong, and I am not sure what exactly. Any help would be appreciated. Thanks.
<body>
<p>Convert temperatures to and from celsius, fahrenheit.</p>
<p id="myForm>
<form name="units" onsubmit="return convertTemp();" method="post">
<input type="number" id="temp"><br>
Temperature in:
<fieldset>
<input type="radio" name="Temperature" id="c" value="c" checked><label for="c">Celsius degrees</label>
<input type="radio" name="Temperature" id="f" value="f"><label for="f">Fahrenheit degrees</label>
</fieldset>
<input type="submit" value="Oblicz">
<form>
</p>
<p id="wynik"></p>
And here is my JavaScript function:
function convertTemp() {
alert("Włączyła się");
var x = document.Jednostki.Temperature.value;
if (x == "c"){
alert("Celsjusz");
}
else if (x == "f"){
alert("Fahrenheit");
}
returns false;
}
Here is what I would suggest
window.addEventListener("load", function() {
document.getElementById("units").addEventListener("submit", function(e) {
e.preventDefault();
console.log("Włączyła się");
var num = parseInt(document.getElementById("temp").value, 10);
if (document.getElementById("c").checked) {
console.log("Celsjusz");
document.getElementById("wynik").innerHTML = num + "C," + (Math.round(num * 9 / 5) + 32) + "F";
} else if (document.getElementById("f").checked) {
console.log("Fahrenheit");
document.getElementById("wynik").innerHTML = num + "F," + (Math.round((num - 32) * 5 / 9)) + "C";
}
});
});
<p>Convert temperatures to and from celsius, fahrenheit.</p>
<p>
<form id="units">
<input type="number" id="temp"><br> Temperature in:
<fieldset>
<input type="radio" name="Temperature" id="c" value="c" checked><label for="c">Celsius degrees</label>
<input type="radio" name="Temperature" id="f" value="f"><label for="f">Fahrenheit degrees</label>
</fieldset>
<input type="submit" value="Oblicz">
<form>
</p>
<p id="wynik"></p>
Using querySelector:
window.addEventListener("load", function() {
document.getElementById("units").addEventListener("submit", function(e) {
e.preventDefault();
console.log("Włączyła się");
const num = parseInt(document.getElementById("temp").value, 10);
const type = document.querySelector("[name=Temperature]:checked").value;
if (type==="c") {
console.log("Celsjusz");
document.getElementById("wynik").innerHTML = num + "C," + (Math.round(num * 9 / 5) + 32) + "F";
} else {
console.log("Fahrenheit");
document.getElementById("wynik").innerHTML = num + "F," + (Math.round((num - 32) * 5 / 9)) + "C";
}
});
});
<p>Convert temperatures to and from celsius, fahrenheit.</p>
<p>
<form id="units">
<input type="number" id="temp"><br> Temperature in:
<fieldset>
<input type="radio" name="Temperature" id="c" value="c" checked><label for="c">Celsius degrees</label>
<input type="radio" name="Temperature" id="f" value="f"><label for="f">Fahrenheit degrees</label>
</fieldset>
<input type="submit" value="Oblicz">
<form>
</p>
<p id="wynik"></p>
First issue I see: returns false; should be return false; (no s).
You should also retrieve the values using document.getElementById():
function convertTemp() {
alert("Włączyła się");
var celsius = document.getElementById('c');
var fahr = document.getElementById('f');
if (c.checked){
alert("Celsjusz");
}
else{
alert("Fahrenheit");
}
return false;
}
document.getElementById("units").onsubmit = convertTemp;
using jquery you can do it raplce this line
var x = document.Jednostki.Temperature.value;
to
var x = $('input[name="Temperature"]:checked').val()
you can see it working here
to get jquery click here

Categories