I'm stuck on this and it's so simple but I don't understand anything of JavaScript.
Basically I want to create a simple calculation to know the travel time, based on three different variables. I'm Dutch so some words are Dutch and some are English in the code. The first variable is the "woonplaats" which is the starting location. The second one is the "bestemming" which is the location of destination. The third one is the "vervoer" which is the vehicle you'll travel by.
Now all of these variables have a standard value. So the only thing that needs to be done is the calculation.
This is what my script code looks like:
function location() {
var woonplaats = document.getElementById("woonplaats").value;
switch (woonplaats) {
case "amstelveen":
locationAm();
break;
case "badhoevedorp":
poelBa();
break;
div2.innerHTML = "Jouw gemiddelde reistijd is: <b>" + tijd + "</b> km/h";
function locationAm() {
var e = document.getElementById("bestemming");
var eindbest = e.options[e.selectedIndex].value;
var x = document.getElementById("bestemming");
var vervoer = x.options[e.selectedIndex].value;
if (eindbest == ameer) {
var distance = 14500 ; }
else if (eindbest === groning) {
var distance = 183000 ; }
else if(eindbest === zwolle) {
var distance = 114000 ;
}
if (vervoer === kuruma ) {
var time = distance / 28 ;
}
else if (vervoer === jitensha) {
var time = var distance / 4 ;
}
else if ( vervoer === densha) {
var time = var distance / 56 ;
}
else if (vervoer === scoot) {
var time = var distance / 8 ; }
div2.innerHTML = "your travel time will be <b>" + time + "</b> km/h";
}
function locationBa() {
var e = document.getElementById("bestemming");
var eindbest = e.options[e.selectedIndex].value;
var x = document.getElementById("bestemming");
var vervoer = x.options[e.selectedIndex].value;
if (eindbest == ameer) {
var distance = 13000 ; }
else if (eindbest === groning) {
var distance = 40000 ; }
else if(eindbest === zwolle) {
var distance = 600000 ;
}
if (vervoer === kuruma ) {
var time = distance / 28 ;
}
else if (vervoer === jitensha) {
var time = var distance / 4 ;
}
else if ( vervoer === densha) {
var time = var distance / 56 ;
}
else if (vervoer === scoot) {
var time = var distance / 8 ; }
div2.innerHTML = "your travel time will be: <b>" + time + "</b>";
And this is my body
<form>
I live in <select id="woonplaats">
<option value="amstelveen">Amstelveen</option>
<option value="badhoevedorp">Badhoevedorp</option>
</select>
<p></p>
I'll travel to <select id="bestemming">
<option value="ameer">Aalsmeer</option>
<option value="groning">Groningen</option>
<option value="zwol">Zwolle</option>
</select>
<p></p>
My vehicle is <select id="vervoer">
<option value="kuruma">Auto</option>
<option value="jitensha">Fiets</option>
<option value="scoot">Scooter</option>
<option value="densha">Trein</option>
</select>
<p></p>
<p></p>
calculate time <input onclick="poel()" type="button" value="Bereken!">
</form>
<p> </p>
<div id="div2">your travel time will be.. gemiddelde ... km/h</div>
Basically the idea is that the first and the second variable decide the distance between them, and the vehicle decides at which speed you'll travel, so it should calculate the travel time.
That's an immense amount of code for a relatively simple problem.
You should encode the distances as data tables instead of logic, and put the vehicle speeds directly into the form as the value attribute of the individual option elements:
The code below does the whole thing:
var distances = {
amstelveen: {
ameer: 14500,
groning: 183000,
einbest: 11400
},
badhoevedorp: {
ameer: 13000,
groning: 40000,
zwolle: 600000
}
};
document.getElementById('calculate').addEventListener('click', function () {
var from = document.getElementById('woonplaats').value;
var to = document.getElementById('bestemming').value;
var speed = +document.getElementById('vervoer').value;
var distance = distances[from][to];
var time = distance / speed;
document.getElementById('div2').innerHTML = "your travel time will be: <b>" + time + "</b>";
}, false);
Demo at http://jsfiddle.net/alnitak/cwdhbk2x/
Related
I'm having trouble figuring out on how can I properly use the array of distance that I made. I am creating a simple web app where user is going to select their origin and preferred destination and I need to compute for the ETA. I already can compute for ETA but the code is so long and so I was wondering if there is better way to do this.
for example:
1) in the select options I have 4 locations which is manila,QC, makati and marikina.
2) if the user selected Manila as Origin and QC as the destination I can compute it using only if-else but if I were to consider every possible way my code will be long with if-else statement.
BTW this is just a sample data of select options and the true data consist of 24 locations and destinations. So I'm really hoping I can have an easy way to do this.
I only tried if-else statement and I was thinking maybe I just loop it but I don't how to start.
please see code for reference. Thank you!
console.clear()
function validateSelect(e) {
var origin = e.target.querySelector("[name=origin]").value;
var destination = e.target.querySelector("[name=destination]").value;
if (origin == destination) {
e.stopPropagation()
e.preventDefault()
alert("Origin and Destination can't be the same");
return false;
}
}
var distanceArray = [10000,20000,30000];
//manila to qc 10000 meter
//qc to makati 20000 meter
//makati to marikina 30000 meter
document.getElementById('findEta').addEventListener('submit', validateSelect);//for form find eta
function getEta(){
var selectedOrigin = document.getElementById("origin").selectedIndex;
var selectedDestination = document.getElementById("destination").selectedIndex;
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
if((selectedOrigin == 0)&& (selectedDestination == 1)){
//manila to qc
distance = 10000;
var speed = 5.56; //converted speed from 20km/h
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}else if((selectedOrigin == 0)&& (selectedDestination == 2)){
distance = 20000;
var speed = 5.56;
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}else if((selectedOrigin == 0)&& (selectedDestination == 2)){
distance = 30000;
var speed = 5.56;
time = distance/speed;
eta = Math.floor(time).toString();
if((eta >=60)){
var newEta = eta /60; //minutes
var mod = eta%60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m "+mod+"s" ;
}else{
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
}
}
function alertFunction(){
var selectedOrigin = document.getElementById("origin").value;
var selectedDestination = document.getElementById("destination").value;
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
if((selectedOrigin == "")&&(selectedDestination =="")){
alert("Please select an option first.");
}else if(selectedOrigin == selectedDestination){
validateSelect(e);
}
else{
getEta();
alert("\nYour Origin is: "+selectedOrigin+"\nYour Destination is: "+selectedDestination+"\nYour ETA is: "+estimatedTimeOfArrival.value);
}
}
<form action="" id="findEta">
<select name="origin" id="origin">
<option value="manila">manila</option>
<option value="QC">QC</option>
<option value="makati">Makati</option>
<option value="marikina">marikina</option>
</select>
<select name="destination" id="destination">
<option value="manila">manila</option>
<option value="QC">QC</option>
<option value="makati">Makati</option>
<option value="marikina">marikina</option>
</select>
<input type="hidden" name="estimatedTimeOfArrival"id="estimatedTimeOfArrival">
<button type="submit" value="submit" onclick="alertFunction()">submit</button>
</form>
We can rule out travel from point A to point A (0 distance) and we can assume that the trip from point A to point B is the same distance as the reverse trip. With this, representing places as single letters (a, b, c, d) a matrix of distances can be described compactly like this... (with made-up distance values)
let distances = {
ab: 1000,
ac: 2000,
ad: 3000,
bc: 1500,
bd: 2500,
cd: 1200
}
function distance(from, to) {
let key = [from, to].sort().join('')
return distances[key]
}
console.log(distance('d', 'a'))
console.log(distance('b', 'c'))
If my understanding is correct, your ETA calculation is the same for each, the variables are the origin and destination which together give you the distance.
To simplify your logic, what you can do is store your distances indexed by these in an object or multi-dimensional array e.g.:
const distances = {
0: {
1: 10000,
2: 20000
},
...
}
And then just lookup the distance from there, e.g.:
const distance = distances[selectedOrigin][selectedDestination];
const speed = 5.56;
...
To take this one step further, you could make it easier to read your structure by using the name values directly in your object, e.g.:
const distances = {
manila: {
qc: 10000,
makati: 20000
},
...
}
And then use the values during lookup, e.g.:
const selectedOrigin = document.getElementById("origin").value;
const selectedDestination = document.getElementById("destination").value;
const distance = distances[selectedOrigin][selectedDestination];
const speed = 5.56;
...
I would consider holding all information in a JSON object or similar.
You can then dynamically populate the drop downs based on the object, including dynamically populating the destination drop down based on origin.
As we are populating the destination dynamically based on origin, we can save the lookup by putting the distance directly as the value of the destination options
//Object to hold info
//Adjust distances as required
const origins = {
"manila": {
"name": "Manilla",
"distances": {
"QC": 1000,
"makati": 2000,
"marikina": 3000
}
},
"QC": {
"name": "QC",
"distances": {
"manila": 1000,
"makati": 2000,
"marikina": 3000
}
},
"makati": {
"name": "Makati",
"distances": {
"manila": 2000,
"QC": 2000,
"marikina": 3000
}
},
"marikina": {
"name": "Marikina",
"distances": {
"manila": 3000,
"QC": 3000,
"makati": 3000
}
}
}
let originDD = document.getElementById("origin");
let destinationDD = document.getElementById("destination");
originDD.innerHTML = "<option value=''>Please Select</option>"
//Populate Origins
for (var prop in origins) {
originDD.innerHTML += `<option value=${prop}>${origins[prop].name}</option>`;
}
//Populate Destinations on change
originDD.addEventListener("change", function() {
var thisOrigin = this.value;
destinationDD.innerHTML = "<option value=''>Please Select</option>";
for (var dest in origins[thisOrigin].distances) {
console.log(dest);
console.log(origins[dest])
destinationDD.innerHTML += `<option value=${origins[thisOrigin].distances[dest]}>${origins[dest].name}</option>`
}
});
//Calculate on destination change
destinationDD.addEventListener("change", function() {
var distance = parseInt(this.value, 10);
var speed = 5.56; //converted speed from 20km/h
var time = distance / speed;
var eta = Math.floor(time).toString();
var estimatedTimeOfArrival = document.getElementById("estimatedTimeOfArrival");
console.log(eta)
if ((eta >= 60)) {
var newEta = eta / 60; //minutes
var mod = eta % 60; //seconds
newEta = Math.floor(newEta);
estimatedTimeOfArrival.value = newEta + "m " + mod + "s";
} else {
eta.toString();
estimatedTimeOfArrival.value = eta + " s";
}
document.querySelector("#eta > span").innerHTML = estimatedTimeOfArrival.value;
});
<form action="" id="findEta">
<select name="origin" id="origin">
</select>
<select name="destination" id="destination">
<option value="">Please Select Origin</option>
</select>
<input type="hidden" name="estimatedTimeOfArrival" id="estimatedTimeOfArrival">
<div id="eta">ETA: <span></span></div>
</form>
It looks like what you're after is the Travelling Salesman problem. It's considered a difficult problem to solve, and probably something beyond the scope of a regular Stack Overflow answer, especially if it's going to be 24 cities (not so bad for 4 cities).
A good place to start is the Branch and Bound algorithm, again by no means trivial. Basically given a starting cities, we work out how to branch out to subsequent available cities in such a way with the lowest "cost" (distance or time) till we arrive at the destination city.
I am writing a Hearthstone pack opening simulator. I am running into an issue when I try to open multiple packs. When I open 1 pack I get an array of 5 cards. When I open 2 packs I get 2 arrays of 10 cards. I would like it to be 1 array of 10 cards. I am thinking this is something to do with async functions or callbacks but not sure how to fix this.
var dataPromise;
var allCards;
var set;
var numberOfPacks;
var commons;
var rares;
var epics;
var legendarys;
var card;
var cardRob;
var pack = [];
var collection = [];
var pittyE;
var pittyL;
$(document).ready(function(){
getCardData()
.done(function(data){
allCards = data;
});
$('#submit').click(function(event){
event.preventDefault();
filterByQuality();
openPacks();
console.log(collection);
});
});
function getCardData() {
if(!dataPromise){
dataPromise = $.ajax({ // Store jQuery promise so that we can return it for subsequent calls ensuring only one AJAX request is made
url: 'https://omgvamp-hearthstone-v1.p.mashape.com/cards?collectible=1',
type: 'GET',
dataType: 'json',
beforeSend: function(xhr) {
xhr.setRequestHeader("X-Mashape-Authorization", "mXtnPm3ltOmshc9dQJjtVdKzfnhbp14UZncjsnfzwvp6uLiMwH");
}
});
}
return dataPromise;
};
function filterByQuality(){
set = document.getElementById('sets').value;
commons = allCards[set].filter(function(common){
return common.rarity == "Common"});
rares = allCards[set].filter(function(rare){
return rare.rarity == "Rare"});
epics = allCards[set].filter(function(epic){
return epic.rarity == "Epic"});
legendarys = allCards[set].filter(function(legendary){
return legendary.rarity == "Legendary"});
};
function getCard(){
var x = Math.floor((Math.random() * 10000) + 1);
if (x <= 96){
card = legendarys[Math.floor(Math.random() * (legendarys.length))];
pittyL = 0;
}else if (x > 96 && x <= 420){
card = epics[Math.floor(Math.random() * (epics.length))];
pittyE = 0;
}else if (x > 420 && x <= 2167){
card = rares[Math.floor(Math.random() * (rares.length))];
}else{
card = commons[Math.floor(Math.random() * (commons.length))];
}
pack.push(card);
};
function getCardRob(){
var x = Math.floor((Math.random() * 10000) + 1);
if (x <= 96){
card = legendarys[Math.floor(Math.random() * (legendarys.length))];
pittyL = 0;
}else if (x > 96 && x <= 420){
card = epics[Math.floor(Math.random() * (epics.length))];
pittyE = 0;
}else{
card = rares[Math.floor(Math.random() * (rares.length))];
}
pack.push(card);
};
function getLegendary(){
card = legendarys[Math.floor(Math.random() * (legendarys.length))];
pack.push(card);
pittyL = 0;
};
function getEpic(){
card = epics[Math.floor(Math.random() * (epics.length))];
pack.push(card);
pittyE = 0;
};
function getPack(){
pittyL ++;
pittyE ++;
if (pittyL == 40 && pittyE == 10){
getLegendary();
getEpic();
getCard();
getCard();
getCard();
} else if (pittyL = 40 && pittyE < 10){
getLegendary();
getCard();
getCard();
getCard();
getCard();
} else if (pittyL < 40 && pittyE == 10){
getEpic();
getCard();
getCard();
getCard();
getCard();
} else {
getCardRob();
getCard();
getCard();
getCard();
getCard();
}
collection.push(pack);
};
function openPacks(){
numberOfPacks = document.getElementById('nop').value;
for (var i = 0; i < numberOfPacks; i++){
getPack();
}
};
Here is the html
<html>
<body>
<header>
<h1>Hearthstone Pack Simulator</h1>
<form>
<select name="sets" id="sets">
<option value="Classic">Classic</option>
<option value="Goblins vs Gnomes">Goblins vs Gnomes</option>
<option value="Journey to Un'Goro">Journey to Un'Goro</option>
<option value="Mean Streets of Gadgetzan">Mean Streets of Gadgetzan</option>
<option value="The Grand Tournament">The Grand Tournament</option>
<option value="Whispers of the Old Gods">Whispers of the Old Gods</option>
</select>
<select name="no of packs" id="nop">
<option value="1">1</option>
<option value="2">2</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<input type="submit" id="submit">
</form>
</header>
<div>
</div>
</body>
</html>
When you call getCard() (or any of its varients) you are updating the global pack. You end up calling getCard() 10 times for two packs, so the same global pack gets updated with 10 total cards. collection is also global and gets updated with the same pack twice.
In order for this to work properly, you should create a new pack object each time you call getPack().
Generally speaking, don't use global variables to manage this state. Instead, create a pack or collection object each time you call getPack(), getCollection(), etc and return that.
You only have one asynchronous function that gets all of the card data at the start. Asynchronicity isn't causing you any issues here.
function getCard() {
let card = /* snip */
return card;
}
function getPack() {
let pack = [];
pack.push(getCard());
/* snip -- add more cards */
return pack;
}
1) You have a typo mistake on if (pittyL = 40, should be if (pittyL == 40).
2) I would recommend doing a method that gets the number of cards you want so you can do getCard(3); to get 3 cards and avoid calling same function a lot of times.
3) As for the pack issue, your pack variable is always the same and you always push cards to that variable, so if you open 100 packs, packs will have 500 cards. As for why you have 2 packs, its because you are doing collection.push(pack); every time you open a pack, so you are pushing to collection the same pack reference every time.
You need separate pack array for each getPack() call.
Please, for your pleasure rewrite this in objects, also consider scope
Once you use objects and correct scope, it should be allright.
var variable_passed_to_function;
variable_passed_to_function = 'foo';
console.log( variable_from_outside_of_function );
function myFunction( variable_from_outside_of_function ) {
let variable_for_only_inside_of_function;
variable_for_only_inside_of_function = 'bar';
console.log( variable_from_outside_of_function );
console.log( variable_for_only_inside_of_function );
variable_from_outside_of_function = 'baz';
console.log( variable_from_outside_of_function );
console.log( variable_for_only_inside_of_function );
return 'this can be also usable';
}
another_variable = myFunction( variable_passed_to_function );
console.log( another_variable );
console.log( variable_passed_to_function );
console.log( variable_for_only_inside_of_function );
I am trying to make a web page which will allow to set multiple alarms using dynamic element creation property of javascript but I'm not able to get the values of these multiple elements and create a alert on that time.
This is my code so far
<div id="TextBoxContainer">
<!--Textboxes will be added here -->
</div>
<br />
<input id="btnAdd" type="button" value="add" onclick="AddTextBox();" />
<script type="text/javascript">
var room = 0;
var i = 0;
function GetDynamicTextBox(){
return '<div>Alarm ' + room +':</div><input type="number"style="text-align:center;margin:auto;padding:0px;width:200px;" min="0" max="23" placeholder="hour" id="a'+room+'" /><input type="number" min="0" max="59" placeholder="minute" style="text-align:center; padding:0px; margin:auto; width:200px;" id="b'+room+'" /><input type="date" style="margin:auto;text-align:center; width:200px; padding:10px"><input type="button" value ="Set" onclick = "AddAlarm('+room+');" /> <input type="button" value ="Remove" onclick = "RemoveTextBox(this)" />';
}
function AddTextBox() {
var div = document.createElement('DIV');
div.innerHTML = GetDynamicTextBox("");
document.getElementById("TextBoxContainer").appendChild(div);
}
function RemoveTextBox(div) {
document.getElementById("TextBoxContainer").removeChild(div.parentNode);
}
function RecreateDynamicTextboxes() {
var html = "";
html += "<div>" + GetDynamicTextBox() + "</div>";
document.getElementById("TextBoxContainer").innerHTML = html;
room++;
}
window.onload = RecreateDynamicTextboxes;
function AddAlarm(values){
var hour = document.getElementById('');
var minute = document.getElementById('');
var date = document.getElementById('');
}
</script>
To create a notification whenever a given time or state is reached, I think you are looking for setInterval (see reference).
This method allows you to take action at a regular interval and it tries to honor that interval the best it can. It opens to a common mistake if your action can take longer than that interval duration so be careful not using a too short interval. In such case, actions can overlap and weird behavior will occur. You do not want that to happen so don't be too greedy when using that.
For an alarm project, I would recommend an interval of one second.
Example (not tested):
JavaScript
var alarmDate = new Date();
alarmDate.setHours(7);
alarmDate.setMinutes(15);
// set day, month, year, etc.
var ONE_SECOND = 1000; // miliseconds
var alarmClock = setInterval(function() {
var currentDate = new Date();
if (currentDate.getHours() == alarmDate.getHours() &&
currentDate.getMinutes() == alarmDate.getMinutes()
/* compare other fields at your convenience */ ) {
alert('Alarm triggered at ' + currentDate);
// better use something better than alert for that?
}, ONE_SECOND);
To add dynamic alarms, you could put them into an array then have your setInterval iterate over it.
In the long run you will probably get sick of alert and feel the need to use something that doesn't break the flow of your application. There are a lot of possibilities, one being the use of lightboxes that could stack over each other. That way you would be able to miss an alarm and still be notified by the next one.
Hope this helps and good luck!
You forgot the ID attribute on the date input and you were collecting the input elements in AddAlarm instead of their values.
EDIT: To check the alarms you have to store them and check every minute, if the current date matches one of the alarms. I added a short implementation there.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="TextBoxContainer">
<!--Textboxes will be added here -->
</div>
<br />
<input id="btnAdd" type="button" value="add" onclick="AddTextBox();" />
<script type="text/javascript">
var alarms = {};
var room = 0;
var i = 0;
setInterval(function() {
var current = new Date();
for (var nr in alarms) {
var alarm = alarms[nr];
console.log("checking alarm " + nr + " (" + alarm + ")");
if(current.getHours() == alarm.getHours()
&& current.getMinutes() == alarm.getMinutes()) { // also check for day, month and year
alert("ALERT\n"+alarm);
} else{
console.log('Alarm ' + nr + '('+alarm+') not matching current date ' + current);
}
}
}, 60000);
function GetDynamicTextBox(){
return '<div>Alarm ' + room +':</div><input type="number"style="text-align:center;margin:auto;padding:0px;width:200px;" min="0" max="23" placeholder="hour" id="a'+room+'" /><input type="number" min="0" max="59" placeholder="minute" style="text-align:center; padding:0px; margin:auto; width:200px;" id="b'+room+'" /><input type="date" style="margin:auto;text-align:center; width:200px; padding:10px" id="c'+room+'"><input type="button" value ="Set" onclick = "AddAlarm('+room+');" /> <input type="button" value ="Remove" onclick = "RemoveTextBox(this)" />';
}
function AddTextBox() {
var div = document.createElement('DIV');
div.innerHTML = GetDynamicTextBox("");
document.getElementById("TextBoxContainer").appendChild(div);
}
function RemoveTextBox(div) {
document.getElementById("TextBoxContainer").removeChild(div.parentNode);
}
function RecreateDynamicTextboxes() {
var html = "";
html += "<div>" + GetDynamicTextBox() + "</div>";
document.getElementById("TextBoxContainer").innerHTML = html;
room++;
}
window.onload = RecreateDynamicTextboxes;
function AddAlarm(values){
var hour = $('#a'+values).val();
var minute = $('#b'+values).val();
var date = $('#c'+values).val();
console.log(hour + ':' + minute + ' on ' + date);
var dateObj = new Date(date);
dateObj.setMinutes(minute);
dateObj.setHours(hour);
console.log(dateObj);
alarms[values] = dateObj;
}
</script>
So far I'm able to generate a alert when the values match the system time but I don't know how to delete the array value when an element is deleted. I am not able to do it. This is my code so far:
<script type="text/javascript">
var snd = new Audio("clock.mp3"); // buffers automatically when created
// Get
if (localStorage.getItem("test")) {
data = JSON.parse(localStorage.getItem("test"));
} else {
// No data, start with an empty array
data = [];
}
var today = new Date();
var d = today.getDay();
var h = today.getHours();
var m = today.getMinutes();
//since page reloads then we will just check it first for the data
function check() {
//current system values
console.log("inside check");
//if time found in the array the create a alert and delete that array object
for(var i = 0; i < data.length; i++) {
var today = new Date();
var d = today.getDay();
var h = today.getHours();
var m = today.getMinutes();
if (data[i].hours == h && data[i].minutes == m && data[i].dates == d ) {
data.splice(i,1);
localStorage["test"] = JSON.stringify(data);
snd.play();
alert("Wake Up Man ! Alarm is over ");
}
}
if((data.length)>0)
{
setTimeout(check, 1000);
}
}
//we do not want to run the loop everytime so we will use day to check
for(var i =0 ; i< data.length; i++)
{
if((data[i].dates == d) && (data[i].hours >= h) && (data[i].minutes >= m) )
{
check();
}
}
console.log(data);
var room = 1;
//var data = [];
var i = 0;
function GetDynamicTextBox(){
var date = new Date();
var h = date.getHours();
var m = date.getMinutes();
var d = date.getDay();
return '<div>Alarm ' + room +':</div><input type="number" style="text-align:center;margin:auto;padding:0px;width:200px;" min="0" max="23" value ='+h+' placeholder="hour" id="a'+room+'" /> <input type="number" min="0" max="59" placeholder="minute" style="text-align:center; padding:0px; margin:auto; width:200px;" id="b'+room+'" value ='+m+' /> <select id="c'+room+'" style="margin:auto; width:150px; padding:10px; color: black" required> <option value="1">Monday</option> <option value="2">Tuesday</option> <option value="3">Wednesday</option> <option value="4">Thursday</option> <option value="5">Friday</option> <option value="6">Saturday</option> <option value="0">Sunday</option> </select> <input type="button" value ="Set" onclick = "AddAlarm('+room+');" /> <input type="button" value ="Remove" onclick = "RemoveTextBox(this)" />';
}
function AddTextBox() {
room++;
var div = document.createElement('DIV');
div.innerHTML = GetDynamicTextBox("");
document.getElementById("TextBoxContainer").appendChild(div);
}
function RemoveTextBox(div) {
document.getElementById("TextBoxContainer").removeChild(div.parentNode);
}
function RecreateDynamicTextboxes() {
var html = "";
html += "<div>" + GetDynamicTextBox() + "</div>";
document.getElementById("TextBoxContainer").innerHTML = html;
}
window.onload = RecreateDynamicTextboxes;
function AddAlarm(values){
var hour = $('#a'+values).val();
var minute = $('#b'+values).val();
var date = $('#c'+values).val();
//get the current time and date
var today = new Date();
//current system values
var d = today.getDay();
var h = today.getHours();
var m = today.getMinutes();
//first check that whether a same date present in the array or not then push it
var found = -1;
for(var i = 0; i < data.length; i++) {
if (data[i].hours == hour && data[i].minutes == minute && data[i].dates == date ) {
found = 0;
break;
}
}
//if value does not present then push it into the array
if(found == -1)
{
data.push({hours: hour, minutes: minute, dates: date});
//storing it into localstorage
localStorage.setItem("test", JSON.stringify(data));
}
else
{
alert("Same value Exists");
}
//console.log(data);
function check() {
//current system values
//console.log("inside check");
//if time found in the array the create a alert and delete that array object
for(var i = 0; i < data.length; i++) {
var today = new Date();
var d = today.getDay();
var h = today.getHours();
var m = today.getMinutes();
if (data[i].hours == h && data[i].minutes == m && data[i].dates == d ) {
data.splice(i,1);
snd.play();
alert("Wake Up Man ! Alarm is over ");
}
}
if((data.length)>0)
{
setTimeout(check, 1000);
}
}
//we do not want to run the loop everytime so we will use day to check
for(var i =0 ; i< data.length; i++)
{
if((data[i].dates == d) && (data[i].hours >= h) && (data[i].minutes >= m))
{
check();
}
}
}
</script>
I am building a website and I want to do calculations based on information provided. I obviously need to have information provided in two out of the three fields to calculate the third's value.
The three fields are:
Price Per Gallon
Gallons Bought
Total Sale
I obviously know that I can calculate the amount of gas bought by dividing the Total Sale amount by the Price Per Gallon.
However I want to calculate based on whatever two fields are entered. I am trying to find out the best way to do this.
I know this much:
Check to see which fields are empty
Determine which type of calculation to make
Here is what I have so far:
<form>
<input type="number" id="totalSale" placeholder="Total Sale Amount" class="calculate" />
<input type="number" id="gallonPrice" placeholder="Price Per Gallon" class="calculate" />
<input type="number" id="gallons" placeholder="Gallons" class="calculate" />
</form>
<script>
var e = document.getElementsByClassName("calculate");
function calc(){
var sale_amt = document.getElementById("totalSale");
var ppg = document.getElementById("gallonPrice");
var gallons = document.getElementById("gallons");
if (sale_amt || ppg !== null) {
var calc_gallons = sale_amt.value / ppg.value;
gallons.value = calc_gallons.toFixed(3);
}
}
for (var i = 0; i < e.length; i++) {
e[i].addEventListener('keyup', calc, false);
}
</script>
the logic should take into consideration which element is currently being entered (that will be this in calc). Also, you need to take into consideration what happens when all three have values, and you change one ... which of the other two should be changed?
See if this works for you
var sale_amt = document.getElementById("totalSale");
var ppg = document.getElementById("gallonPrice");
var gallons = document.getElementById("gallons");
function calc(){
var els = [sale_amt, ppg, gallons];
var values = [sale_amt.value, ppg.value, gallons.value];
var disabledElement = els.find(e=>e.disabled);
var numValues = els.filter(e => e.value !== '' && !e.disabled).length;
var calc_gallons = function() {
gallons.value = (values[0] / values[1]).toFixed(3);
};
var calc_ppg = function() {
ppg.value = (values[0] / values[2]).toFixed(3);
};
var calc_sale = function() {
sale_amt.value = (values[1] * values[2]).toFixed(2);
};
if (numValues < 3) {
if (numValues == 1 && disabledElement) {
disabledElement.disabled = false;
disabledElement.value = '';
disabledElement = null;
}
els.forEach(e => e.disabled = e == disabledElement || (numValues == 2 && e.value === ''));
}
disabledElement = els.find(e=>e.disabled);
switch((disabledElement && disabledElement.id) || '') {
case 'totalSale':
calc_sale();
break;
case 'gallonPrice':
calc_ppg();
break;
case 'gallons':
calc_gallons();
break;
}
}
var e = document.getElementsByClassName("calculate");
for (var i = 0; i < e.length; i++) {
e[i].addEventListener('keyup', calc, false);
e[i].addEventListener('change', calc, false);
}
A user inputs an amount of water they need, I need to calculate which bottles to use, either 10l bottles or 20l bottles. So if they ask for 67l, the script pops up with 3x20l and 1x10l
I have tried the following 2 solutions
var resinAm = rsize*1.1*2.5
var resTin = '';
if(resinAm<10){
resTin = 1;
} else {
resTin = resinAm/20;
resTin = Math.ceil(resTin);
}
and this
var resAm = resinAm;
var resAm10 = (resAm/10)+0.001;
var resAm20 = (resAm/20)*2;
if(resAm10>resAm20){
resTin10 = 1;
resTin20 = Math.floor(resAm/20);
} else {
resTin20 = Math.ceil(resAm/20);
}
I have also tried using modulo, but it always comes out with an extra 20l bottle, 70.5l came out as 5x20l and 1x10l
How do I fix this
Check the code at: https://jsfiddle.net/a4k2cyoy/2/
var resAm = 70.5;
var resAm20 = parseInt(resAm / 20);
var resAm10 = 0;
if(resAm % 20 > 10) {
resAm20++;
}
if(resAm % 20 <= 10 && resAm > 0) {
resAm10++;
}
alert(resAm + " will go into " + resAm20 + " x 20 bottles and " + resAm10 + " x 10 bottles");
As simple as this
var value = 67;
var tenLBottles = Math.ceil(value % 20 /10);
var twentyLBottles = (value - value%20)/20
You can do that, fill bottles array with what you want
var water = 67;
var bottles = [20, 10, 3]; // bottles in desc order
var currentBottleIndex = 0
while(water > 0 && currentBottleIndex < bottles.length) {
console.log(Math.floor(water / bottles[currentBottleIndex]) + ' bottles of ' + bottles[currentBottleIndex])
water = water % bottles[currentBottleIndex]
currentBottleIndex ++;
}
console.log('rest water', water)
This is a math quesion, put it simple,you can realize it this way:
var bottles=[20,10];
function choose_bottle(water) {
var bottle1_num,bottle2_num;
if(water<=10) {
return "1*"+bottles[1];
}
else if(water>10&&water<=20) {
return "1*"+bottles[0];
}
else {
bottle1_num = Math.floor(water/bottles[0]);
bottle2_num = Math.ceil((water -bottle1_num*bottles[0])/bottles[1]);
return bottle1_num+"*"+bottles[0]+" "+bottle2_num+"*"+bottles[1];
}
}
This should do the job:
var amount = 67;
var bottle20 = Math.floor(amount / 20);
var bottle10 = Math.ceil((amount - bottle20 * 20) / 10);