I'm trying to write a Javascript calculation for an insurance sales form that I've designed. I'm very new to JS, and am having trouble getting the script to work. I would really appreciate if you could help point out what I'm missing! Thanks so much.
The script is meant to calculate an insurance premium based on two checkboxes (vars cb1 & cb2), a pair of radio buttons which indicate whether insured vehicles are for short or long haul trips (var haul), and the number of insured vehicles (vars trucks_num, cars_num, pvthire_num, buses_num, trailers_num).
At the end, I want the premium (var premium) to be displayed in the field "totalpremium".
I really appreciate your help!
Thank you :).
var cb1 = this.getField("cbexcellent");
var cb2 = this.getField("cbsatisfactory");
var haul = this.getField("haul");
var premium = this.getField("totalpremium");
var trucks_num = this.getField("over4.5t_num").value;
var cars_num = this.getField("cars_num").value;
var pvthire_num = this.getField("pvthire_num").value;
var buses_num = this.getField("buses_num").value;
var trailers_num = this.getField("trailers_num").value;
if((cb1 == "1") && (cb2 == "0") && (haul.valueAsString == "short")) {
var premium = (trucks_num.value * 150) + (cars_num.value * 100) + (pvthire_num.value * 250) + (buses_num.value * 150) + (trailers_num.value * 50);
}
if((cb1 == "0") && (cb2 == "1") && (haul.valueAsString == "short")) {
var premium = (trucks_num.value * 190) + (cars_num.value * 100) + (pvthire_num.value * 250) + (buses_num.value * 150) + (trailers_num.value * 50);
}
if((cb1 == "1") && (cb2 == "0") && (haul.valueAsString == "long")) {
var premium = (trucks_num.value * 190) + (cars_num.value * 100) + (pvthire_num.value * 250) + (buses_num.value * 150) + (trailers_num.value * 50);
}
if((cb1 == "0") && (cb2 = "1") && (haul.valueAsString == "long")) {
var premium = (trucks_num.value * 235) + (cars_num.value * 100) + (pvthire_num.value * 250) + (buses_num.value * 150) + (trailers_num.value * 50);
}
this.getField("totalpremium").value = premium.valueAsString
Check that the export values of your checkboxes match the values indicated as required in your if statements. By default these are set to Yes or No. If they don't match your script won't run right.
Related
I am building a sample application, a mockup of a medical records system, using Oracle Apex. On one page, the object is to enter patient vitals. What is required is that, once the patient's height (feet and inches) and weight are entered, which are three separate textboxes, the BMI is automatically calculated. I attempted to set this using dynamic actions, but the result was that, anytime any one of the textboxes was changed, the calculation would fire. I would like this calculation to only fire if and only if all three textboxes have both been changed and have valid data. Listed below is the current status of the Javascript function:
function getBMI() {
var feet = parseInt(document.getElementById('P601_HEIGHTFT').value);
var inches = parseInt(document.getElementById('P601_HEIGHTIN').value);
var weight = parseInt(document.getElementById('P601_WEIGHT').value);
var height = (feet * 12) + inches;
var warning = document.getElementById('BMIWarning');
while ((feet == '') && (inches == '') && (weight == '')) {
document.getElementById('P601_BMI').value = '';
}
var BMI = (weight / Math.pow(height, 2)) * 703;
document.getElementById('P601_BMI').value = BMI.toFixed(2);
if(BMI < 18.5) {
warning.style.color = "red";
warning.innerHTML = "Patient is underweight";
} else if (BMI >= 18.5 && BMI < 25.0) {
warning.innerHTML = "";
} else if (BMI >= 25.0 && BMI <= 29.9) {
warning.style.color = "red";
warning.innerHTML = "Patient is overweight";
} else if (BMI > 29.9) {
warning.style.color = "red";
warning.innerHTML = "Patient is obese";
}
}
While it would function properly after all values were entered, the fact that the function fired after each individual textbox was highly undesired.
When I clicking the button the user HP goes down till 0 and then button changes. But what happens more is, when the userHealth reaches zero the button did not change. You have to click one more time to button change. How to solve this ?
JS:
$(".attBtn").click(function() {
var userId = 4;
var attackdmg = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var userdmg = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
var minimum = 0;
if(userHealth == 0){
info.innerHTML = '<strong>'+user.textContent+'</strong> have been defeated.';
attackBtn.css("backgroundColor", "blue");
attackBtn.css("border", "none");
innerAttBtn.innerHTML = "Get the reward <img src="+"/img/chest2.png"+"/> ";
return false;
}else if(attackerHealth == 0){
info.innerHTML = '<strong>You</strong> have been defeated.';
}else if(attackerHealth == 0 && userHealth == 0){
info.innerHTML = '<strong>DRAW FIGHT</strong>';
}else{
userHealth -= attackdmg;
attackerHealth -= userdmg;
document.getElementById('attackerBar').setAttribute("style","width:"+attackerHealth+"%");
document.getElementById('userBar').setAttribute("style","width:"+userHealth+"%");
$.ajax("/arena/fight-user/"+userId+"/attack/"+attackdmg+"/"+userdmg,
{
});
if(userHealth < 0){userHealth = minimum;}
if(attackerHealth < 0){attackerHealth = minimum;}
userHp.innerHTML = '<strong>'+userHealth+'</strong>';
attackerHp.innerHTML = '<strong>'+attackerHealth+'</strong>';
info.innerHTML = '<strong>' +user.textContent+'</strong>' +' hit <strong>You</strong> with ' +userdmg+' dmg <br> ' + '<strong>You</strong> hit '
+'<strong>'+user.textContent+'</strong>'+ ' with '+ attackdmg +' dmg';
}
});
there is a logical flaw.
The reason, why you have to click once more, is because you declare what should happen at 0 HP before the HP gets actually to zero.
The solution
put this
userHealth -= attackdmg;
attackerHealth -= userdmg;
if(userHealth < 0){userHealth = minimum;}
if(attackerHealth < 0){attackerHealth = minimum;}
before this
if(userHealth == 0){
...
So I try to create three values between 1 and 3 that are going to be different every time the page loads. It works perfectly when I open the page the first time, but whenever I try to reload or submit my form the page freeze and it is stuck loading. Any help is much appreciated!
function uniqueAnswerId(){
var rand = (Math.random() * 3.4);
while (Math.round(rand) == 0) {
var rand = (Math.random() * 3.4);
}
return (Math.round(rand));
}
var answerId1 = uniqueAnswerId();
function uniqueAnswerId2(){
var rand2 = (Math.random() * 3.4);
while (answerId1 == Math.round(rand2) || Math.round(rand2) == 0) {
var rand2 = (Math.random() * 3.4);
}
return (Math.round(rand2));
}
var answerId2 = uniqueAnswerId2();
function uniqueAnswerId3(){
var rand3 = (Math.random() * 3.4);
while (answerId1 == Math.round(rand3) || answerId2 == Math.round(rand3)){
while (Math.round(rand3) == 0){
var rand3 = (Math.random() * 3.4);
}
}
return (Math.round(rand3));
}
var answerId3 = uniqueAnswerId3();
console.log("AnswerIds: " + (answerId1) + ", " + (answerId2) + ", " + (answerId3))
your 3rd while loop should look like this, with another "||" in your condition instead of a whole new while loop.
function uniqueAnswerId3(answerId1, answerId2){
var rand3 = (Math.random() * 3.4);
while (answerId1 === Math.round(rand3) || answerId2 === Math.round(rand3) || Math.round(rand3)===0){
rand3 = (Math.random() * 3.4);
}
return (Math.round(rand3));
}
I believe you have an infinite loop. Here is the fiddle to fix your code.
Changes: Use '===' instead of '=='
Function Hoisting executes those functions before the variable declarations, which means referencing them inside the functions doesn't work. Added parameters to accept the arguments required.
https://jsfiddle.net/80xdmsjL/
function uniqueAnswerId(){
var rand = (Math.random() * 3.4);
while (Math.round(rand) === 0) {
rand = (Math.random() * 3.4);
}
return (Math.round(rand));
}
var answerId1 = uniqueAnswerId();
function uniqueAnswerId2(answerId1){
var rand2 = (Math.random() * 3.4);
while (answerId1 === Math.round(rand2) || Math.round(rand2) === 0) {
rand2 = (Math.random() * 3.4);
}
return (Math.round(rand2));
}
var answerId2 = uniqueAnswerId2(answerId1);
function uniqueAnswerId3(answerId1, answerId2){
var rand3 = (Math.random() * 3.4);
while (answerId1 === Math.round(rand3) || answerId2 === Math.round(rand3)){
while (Math.round(rand3) === 0){
rand3 = (Math.random() * 3.4);
}
}
return (Math.round(rand3));
}
var answerId3 = uniqueAnswerId3(answerId1, answerId2);
console.log("AnswerIds: " + (answerId1) + ", " + (answerId2) + ", " + (answerId3))
Take a look at this part of your code:
while (answerId1 === Math.round(rand3) || answerId2 === Math.round(rand3)){
while (Math.round(rand3) === 0){
rand3 = (Math.random() * 3.4);
}
}
Lets see what happen with the following values:
answerId1 = 1
answerId1 = 2
Math.round(rand3) = 1
in this case, you will have:
while (true){
while(false){
never_executed();
}
}
So it will loop until infinite in the outer 'while'.
To avoid this you could simply do what #Nicholas Bakolias says, add 'another "||" in your condition instead of a whole new while loop'
I'm having a problem figuring out where I'm going wrong in my code that is supposed to automatically fill in "railQuantity" for a form I am building. Currently my code only "works" when either 6ft or 8ft "fenceHeight" is selected but either way it uses the total = (Math.ceil(footage / 8) * 3); equation. It will, however, correctly blank out when I choose "Select Fence Height". So I am trying to figure out where I am going wrong with my logic so that it does not correctly use the equation for the corresponding fenceHeight. Any and all help is appreciated! Thanks you guys!
Html snippet:
Fence Description:
<select name="fenceHeight" id="fenceHeight">
<option value="select">Select Fence Height</option>
<option value="4" id="fH4">4 Ft.</option>
<option value="6" id="fH6">6 Ft.</option>
<option value="8" id="fH8">8 Ft.</option>
</select>
Javascript snippet:
//Quantity for Rails
$('#fenceHeight, #footage').bind('keypress keydown keyup change', function() {
var footage = parseFloat($(':input[name="footage"]').val(),10);
var total = '';
if($(':input[name="fenceHeight"]').val() != "select"){
if(parseFloat($(':input[name="fenceHeight"]').val() == "8")) {
total = (Math.ceil(footage / 8)* 4);
}
if(parseFloat($(':input[name="fenceHeight"]').val() == "4" || "6")) {
total = (Math.ceil(footage / 8) * 3);
}
$(':input[name="railQuantity"]').val(total.toString());
} else {
$(':input[name="railQuantity"]').val('');
}
});
Try
var $footage = $('#footage'),
$fenceHeight = $('#fenceHeight'),
$railQuantity = $('input[name="railQuantity"]');
$footage.add($fenceHeight).bind('keypress keydown keyup change', function () {
var footage = parseFloat($footage.val(), 10),
fenceHeight = $fenceHeight.val();
var total = '';
if (fenceHeight != NaN) {
if (fenceHeight == '8') {
total = (Math.ceil(footage / 8) * 4);
}
if (fenceHeight == '4' || fenceHeight == '6') {
total = (Math.ceil(footage / 8) * 3);
}
$railQuantity.val(total);
} else {
$railQuantity.val('');
}
});
Demo: Fiddle
These lines are wrong:
if(parseFloat($(':input[name="fenceHeight"]').val() == "8")) {
total = (Math.ceil(footage / 8)* 4);
}
if(parseFloat($(':input[name="fenceHeight"]').val() == "4" || "6")) {
total = (Math.ceil(footage / 8) * 3);
}
You're not comparing the result of parseFloat with the strings, you're comparing the val() with the strings and passing the result of the comparison to parseFloat. And in the second one, you're comparing val() with the result of 4 || 6, which is 4 -- you can't combine comparisons with or in programming languages like you can in English. Change it to:
var height = $(':input[name="fenceHeight"]').val();
if (height == "8") {
total = (Math.ceil(footage / 8)* 4);
} else if (height == "4" || height == "6") {
total = (Math.ceil(footage / 8) * 3);
}
My code works (doesn't fail), but it doesn't do the right thing.
I call the "generate" function every time i want to generate a new "chunk", passing a new number into the function each time its called. It generates the chunk fine, but it doesn't generate what I want it to generate.
I want it to generate either a space, a jump, a slide, or a gap, if the previous generation was a space. But if the previous generation wasn't a space, generate a space.
It doesn't do that. It sometimes generates 2 gaps, 2 jumps, or 2 slides after each other and i have no idea why... ???
Here is my code:
var ptg = 'space'; // what was previously generated to top
var wtgt; // what is currently being generated to top
var chunktogenerateto = 0;
function generate(a){
chunktogenerateto = a;
var rand1 = Math.floor(Math.random()*100) + 1;
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
wtgt = 'jump';
}
else if(ptg == 'space' && rand1 <= 75 && rand1 > 50){
wtgt = 'slide';
}
else if(ptg == 'space' && rand1 > 75){
wtgt = 'gap';
}
else{
wtgt = 'space';
}
ptg = wtgt;
topGen(wtgt);
}
function topGen(g){
document.getElementById('t' + chunktogenerateto).setAttribute('src','images/terrain/t' + g + '.png');
}
I hope it's not a typo... HELP!
Where the calls to "generate" are coming from:
var chunkpos = new Array();
chunkpos[0] = -100;
chunkpos[1] = 0;
chunkpos[2] = 100;
chunkpos[3] = 200;
chunkpos[4] = 300;
chunkpos[5] = 400;
chunkpos[6] = 500;
chunkpos[7] = 600;
chunkpos[8] = 700;
chunkpos[9] = 800;
chunkpos[10] = 900;
chunkpos[11] = 1000;
var temppos = new Array();
var time1;
var millis1;
var time2;
var millis2;
var millis3;
var firstreset = true;
var pos;
var poschange;
function moveLevel(){
if(firstreset == true){
resetTime();
}
var time2 = new Date();
var millis2 = time2.getTime();
var millis3 = millis2 - millis1;
poschange = Math.floor(millis3 / 5);
for(i = 0; i < chunkpos.length; i++){
temppos[i] = chunkpos[i] - poschange;
if(temppos[i] <= -150){
generate(i);
temppos[i] += 1200;
}
pos = temppos[i];
document.getElementById('chunk' + i).setAttribute('style','left: ' + pos + 'px;');
}
}
function resetTime(){
time1 = new Date();
millis1 = time1.getTime();
if(firstreset != true){
for(i = 0; i < chunkpos.length; i++){
chunkpos[i] = temppos[i];
}
}
firstreset = false;
setTimeout('resetTime()',1000);
}
Where the calls to "moveLevel" are coming from:
window.onload = function(){
if(test = 'runnable')
{
gameLoop();
}
else
{
document.getElementById('gm').innerHTML = (gm + 'Failed to run game.');
}
}
function gameLoop(){
if(currentscreen == 'playing'){
moveLevel();
}
setTimeout('gameLoop()',0);
}
Here is a download link to a zip file containing all of the code:
ParkourFreak.zip
The code i'm having trouble with is under scripts/generation.js.
The main game page (where the generation is visible is index.html.
Rather than each if statement starting with "if(ptg == 'space' ... etc" - do this first in one simple "if not space return space".
After that you can start on your random - that should work for you.
Roughly a quarter of the time you previously had a space, it will create another, because of this code:
if(ptg == 'space' && rand1 <= 25){
wtgt = 'space';
}
Note that it's creating a space when a space was previously created.
Side note:
There's no need for the && rand1 > 25 on this line:
else if(ptg == 'space' && rand1 <= 50 && rand1 > 25){
Since you previously had if(ptg == 'space' && rand1 <= 25){, it's impossible as of that line for rand1 to be <= 25 when ptg == 'space'.
(And similarly the && rand2 > 50 on the following condition.)
Are you sure you're incrementing chunktogenerateto?
It appears to stay at 0 with the current code, is that in a segment you haven't shown?
Edit: oh, it's the argument of the function. Try logging that variable, maybe that's the problem?
// elsewhere
var wtgts = ['space','jump','slide','gap'];
// in the function
if(ptg !== 'space') {
wtgt = 'space';
} else {
var randidx = Math.floor(Math.random()*4);
wtgt = wtgts[randidx];
}
Or even in the function:
var newidx = (ptg == 'space') ? Math.floor(Math.random()*4) : 0;
wtgt = wtgts[newidx];
The weights were equal, so just pick a random index from 0 to 3 and use that to pick an action from an array.
Separate the logic for ptg being space so that you only test for it once
Consider denoting the actions as numbers instead of strings, as the assignment, comparison etc will be faster and more robust.
I thought the problem lied with the generation, when in fact all I had to do to solve it was to change this:
if(temppos[i] <= -100){
generate(i);
temppos[i] += 1200;
}
to this:
if(temppos[i] <= -100){
generate(i);
chunkpos[i] += 1200;
temppos[i] += 1200;
}