Javascript and Variable assistance - javascript

(Rephrasing question from earlier) So here is the assignment:
First, you will have to calculate a cost for the weight of the parcel. The user will enter the total weight of their parcel into the text field. The schedule is as follows…
0 – 150 lbs $20.00 per pound
| 151 – 300 lbs $15.00 per pound
| 301 – 400 lbs $10.00 per pound
Do not allow the user to enter a weight that is < 0 or > 400. If they do, output an error message in red to div#results and ‘return’ out of the function.
Next, the user will choose a discount amount (for whatever reason, does not matter). You will need to apply whatever discount amount is chosen. (50% off, 20% off, none).
This is what I have done so far. Variable aren't declared yet, just wrote them in.
function calcTotal() {
var msg;
var weight = parseInt( document.getElementById("weight").value );
var discount;
var total;
if( weight >= 0 && weight <= 150 ) {
total = weight * 20
}
else if( weight >150 && weight <= 300 ) {
total = weight * 15
}
else if( weight >300 && weight <= 400 ) {
total = weight * 10
}
if( document.getElementById("50%").selected == true ) {
total = total * 0.50;
}
if( document.getElementById("25%").selected == true ) {
total = total * 0.25;
}
if( document.getElementById("none").selected == true ) {
total = total;
}
Is this somewhat correct so far?
Can't seem to figure out how to apply the discount based on what the user selects. The discounts are 3 radio buttons. Do i need to apply an id to each radio button?

First of all you need to use && (AND) instead of || (OR) because you want both conditions to be met not just one. First IF statement will process value -1000 as TRUE (as well as any other value because your interval is from 0 to infinity plus from minus infinity to 150) because it satisfies the second part of the first condition.
Second, the formula is correct but you have to convert percents into 0-1 interval. 100% = 1, 0% = 0 and x% = x/100. Then it should work without any problems.
Last thing to do is that you need to pass the values into your function:
function calcTotal(weight, discount) {
// do the calculation with passed values, you do not need to declare them here anymore
}
Or you need to set values right inside of that function, e.g.:
function calcTotal() {
var discount = $("#inputField").val(); // using jQuery, where inputField is element
// from which the value is taken e.g. < input >
...
}
To display the final output, add this to your function:
$("body").append("<div id='output'>" + output + "</div>"); // using jQuery, watch for single/double quotes
and style it with css to be in the center:
#output {
position: absolute;
width: 200px;
height: 200px;
left: 50%;
margin-left: -100px;
top: 200px;
}

I made a fiddle that you should be able to get what is going on pretty quickly.
http://jsfiddle.net/a58rR/3/
I used a touch of jQuery just to get the bindings on the UI elements.
I hope this is not for a class and you copy this wholesale! ;)
Basically, I put all your Tier pricing into one object.
Tiers = [{
nPrice: 20,
nWeightMin: 1,
nWeightMax: 150
}, {
nPrice: 15,
nWeightMin: 151,
nWeightMax: 300
}, {
nPrice: 10,
nWeightMin: 301,
nWeightMax: 400
}];
Then, your function will calculate based on the entered weight and discount selected, determine the Tier, validate the weight, update the UI with a message if out of range, calculate the final price and apply any discount, and update the UI with the total price:
function calculatePrice() {
console.log('Begin Calc');
var _nW = document.getElementById('nParcelWeight').value * 1;
var _nD = document.getElementById('aDiscounts').value * 1;
var _nP = 0;
var nTotalPrice = 0;
var _TotalPrice = document.getElementById('nPrice');
var _nMaxWt = Tiers[Tiers.length - 1].nWeightMax;
// Using the last Tier keeps the max weight dynamic no matter how many tiers you add as long as they are in order
console.log('Max Weight: ' + _nMaxWt);
console.log('Weight: ' + _nW);
console.log('Discount: ' + _nD);
if (isNaN(_nW) || _nW < 1 || _nW > _nMaxWt) {
// Throw/Display an out of range error here
console.log('Yep, out of range');
document.getElementById('uiFeedback').innerHTML = 'The number is out of range.';
} else {
// reset if valid
document.getElementById('uiFeedback').innerHTML = '';
}
// Find Tier
for (var i = 0; i < Tiers.length; i++) {
console.log('we are in loop:' + i);
if (_nW >= Tiers[i].nWeightMin && _nW <= Tiers[i].nWeightMax) {
_nP = Tiers[i].nPrice;
break;
}
}
console.log('Tier: ' + i);
console.log('Price: ' + _nP);
// Calculate Discount
if (_nD != 1) _nD = 1 - _nD; // (20%==.20, but that would be .80 of the Price, etc)
// Calc Price
nTotalPrice = (_nP * _nW * _nD);
_TotalPrice.value = nTotalPrice;
}
The html will look something like this:
<div id='uiFeedback'></div>Parcel Weight:
<input id='nParcelWeight' value='0'>Discount:
<select id='aDiscounts'>
<option value='1'>none</option>
<option value='.2'>20%</option>
<option value='.5'>50%</option>
</select>
<hr>Price:
<input id='nPrice'>
And your CSS at a minimum might just color your messaging:
#uiFeedback {
color: red;
font-weight: bold;
}
Here are the bindings, which you could do with inline onChanges or raw js attach events:
$(function () {
$('#nParcelWeight,#aDiscounts ').on('change', function () {
calculatePrice();
});
})

Related

Taking any 2 inputs and show result in third input in JS onChange

I have a formula:
Capacity = factor * height
I have to show three inputs on the form for the (Capacity, factor, and height), the requirement is that if a user enters any two inputs the third one must be calculated.
For example, if user inputs capacity and height, factor must be calculated by
factor = capacity/height
and so on. Can anyone suggest how it can be achieved by using onChange of any input? Or is there any better way to do it?
HTML
<input id="Factor" min="0" onchange="calculate();" type="number">
<input id="Capacity" min="0" onchange="calculate();" type="number">
<input id="Height" min="0" onchange="calculate();" type="number">
JS
function calculate() {
var capacity = $("#Capacity ").val();
var height = $("#Height").val();
var factor = $("#Factor").val();
if (!capacity || !height || !factor) {
return false;
}
if (height > 0 || factor > 0) {
$("#Capacity").val(factor * height);
}
if (capacity > 0 || factor > 0) {
$("#Height").val(capacity / factor);
}
if (capacity > 0 || height > 0) {
$("#Factor").val(capacity / height);
}
};
I think the problem is still under-specified. You also need to specify how to handle cases when all 3 inputs are non-empty and the user changes one of them. For example: capacity=10, factor=5, height=2 and the user changes capacity to 101 (i.e. just adds 1 to the end). What is the expected behavior? There are a few choices.
Do nothing (i.e. wait till user clears at lest one of the fields) and probably add explicit "Clear" button
Specify re-calculation priorities (e.g. recalculate capacity unless it is the focused field in which case recalculate factor).
less obvious and more complicated: keep track in which order user focused fields and update the one that was focused least recently (or was not focused at all). I think you may come up with a few more ideas.
You may see a demo of the option #3 at JS Fiddle
The code of the solution is mostly written by #mark.hch
//to hold the order in which inputs were populated
var inputOrder = ['Factor', 'Capacity', 'Height'];
//calculation formulae
function UpdateFactor(c, h) { $('#Factor').val(c / h); }
function UpdateCapacity(f, h) { $('#Capacity').val(f * h); }
function UpdateHeight(f, c) { $('#Height').val(c / f); }
//tied to keyup, could easily be change too
$('#Factor,#Capacity,#Height').keyup(function() {
//gather our input numbers as floats
var f = parseFloat($('#Factor').val());
var c = parseFloat($('#Capacity').val());
var h = parseFloat($('#Height').val());
//get the current element's id
var id = $(this).attr('id');
//get the index in inputOrder if already present
var idx = inputOrder.indexOf(id);
//if the input already had a value, splice it from the inputOrder array
if(idx != -1) { inputOrder.splice(idx, 1); }
//add the current input id to the inputOrder array
inputOrder.push(id);
//count how many fields are currently filled out
var ct = 0;
ct += isNaN(f) ? 0 : 1;
ct += isNaN(c) ? 0 : 1;
ct += isNaN(h) ? 0 : 1;
if(ct >= 2) {
//update the least recently populated field
switch(inputOrder[0]) {
case 'Factor':
UpdateFactor(c, h);
break;
case 'Capacity':
UpdateCapacity(f, h);
break;
case 'Height':
UpdateHeight(f, c);
break;
}
}
});

adding an event listener to roll dice javascript

I am currently working on a beginner JavaScript program for class.
The program should display two input fields to the user. The first input field will accept an integer that will determine how many sides the die will have. The second input will accept an integer that will determine the amount of times the die is thrown.
These inputs must be validated to only be positive numbers. When the inputs have been entered, and the user clicks out of the input fields, an addEventListener('blur') will fire and the die will be "thrown". This should display, for example, You rolled: 6, 2, 3, 5 for a total roll of 16.
It was advised that we use a loop that will perform the "roll" of the dice. The loop should be performed as many times as necessary when the blur event occurs and should display the individual roll plus the sum.
My question is:
How would I go about storing the input values from the number of times the die is thrown into an array, then loop through that array to display the random numbers for each die throw, as well as the total throw? This will happen every time the blur event occurs for the two input fields.
At the moment, my program only displays a random number from the die side input and the input for throw amount. I have tried using a for or while loop for this task, but no success. This is what I currently have.
function dieInfo() {
// temporary label to display # of sides
var dieSideNum = document.getElementById('die-side-num');
// convert string input into floating integer,
// if this doesnt create a number use 0 instead
var getDieSide = parseFloat(dieSideQuant.value) || 0;
// temporary label to display throw total
var throwTotal = document.getElementById('throw-total');
//convert string input into floating integer
// if this doesnt create a number use 0 instead
var getThrowTotal = parseFloat(throwQuant.value) || 0;
// if die sides input or throw amount input is <= 0
if (getDieSide <= 0 || getThrowTotal <= 0) {
// display error for improper number of sides for die input
dieSideNum.textContent = "Please enter valid Die sides";
// display error for improper throw amount input
throwTotal.textContent = "Please enter valid throw amount";
} else {
// use random function to store random number from die sides input
throwRand = Math.floor(Math.random() * (1 + (getDieSide) - 1)) + 1;
// test- display random number of sides for die
dieSideNum.textContent = "Number of Sides on Die: " + throwRand;
// test - display throw count
throwTotal.textContent = " You threw " + getThrowTotal + "times";
}
}
// retrieve id for for amount of sides on die
var dieSideQuant = document.getElementById('die-side-quant');
// fire the dieInfo function when the input element loses focus
dieSideQuant.addEventListener('blur', dieInfo);
// retrieve id for throw amount input
var throwQuant = document.getElementById('throw-quant');
// fire the dieInfo function when the input element loses focus
throwQuant.addEventListener('blur', dieInfo);
<h1 id="info-die"> How many sides on die? </h1>
<input type="number" min="0" id="die-side-quant" placeholder="# sides on die">
<h3 id="die-side-num"></h3>
<h1 id="info-throw-die"> Throw Amount? </h1>
<input type="number" min="0" id="throw-quant" placeholder="throw amount">
<h3 id="throw-total"></h3>
a reference picture of what I currently have
To store the input values from the number of times the die is thrown into an array, declare an Array and use the .push method.
// declare an Array variable
var dieThrows = [];
// use .push to store the value in the Array.
dieThrows.push(throwRand);
// or don't bother with the extra throwRand variable by doing it this way
dieThrows.push(Math.floor(Math.random() * (1 + (getDieSide) - 1)) + 1);
To loop through the array, use the .forEach method or just iterate over the values:
// doing it ES5-style:
dieThrows.forEach(function (throwResult, index, array) {
console.log(throwResult); // display the random numbers for each die throw in the dev tools console
});
// doing it ES6-style:
dieThrows.forEach( (throwResult, index, array) => (console.log(throwResult)) );
// doing it old-school:
for (var i = 0; i < dieThrows.length; i += 1) {
console.log(throwResult); // display the random numbers for each die throw in the dev tools console
}
To get the total number of throws, you can just access the .length property of the Array (because you're storing each throw in the Array):
var totalThrows = dieThrows.length;
var numRolls = 6;
var numRollTotal = 0;
for(var i = 0; i < numRolls; i++) //Here happens the for magic.
{
//Write and store
}
//Write again
I left some blanks on purpose ;) Looking at your code you're smart enough to figure it out. No need for arrays on this one.
You've identified the subproblems correctly! You can refer to the following:
window.onload = function() {
document.getElementById('numThrows')
.addEventListener('blur', function() {
var numSides = parseInt(document.getElementById('numSides').value);
var numThrows = parseInt(document.getElementById('numThrows').value);
var randArr = [];
for (var i = 0; i < numThrows; i++)
// On each repetition, store a result into `randArr`
randArr.push(1 + Math.floor(Math.random() * numSides));
// Now display the results
var results = document.getElementById('results');
results.innerHTML = randArr.map(function(randNum, throwNum) {
// Generate HTML markup for each result
return '<div class="result">' +
'Throw #' + (throwNum + 1) + '; ' +
'result: ' + randNum +
'</div>';
}).join('');
});
};
<div>Note this example has no validation</div>
<input id="numSides" placeholder="sides" type="text"/>
<input id="numThrows" placeholder="throws" type="text"/>
<div id="results">
</div>
document.getElementById('throw-quant')
.addEventListener('blur', function(){
var numSides = parseInt(document.getElementId('die-side-quant').value);
var numThrows = parseInt(document.getElementId('throw-quant').value);
var outputString="You rolled:";
var total=0;
for(var i=0; i<numThrows; i++){
var n = Math.floor(Math.random() * (1 + (getDieSide) - 1)) + 1;
total+=n;
outputString+=" "+String(n);
}
outputString+=" for a total roll of "+String(total);
document.getElementById("desired location").innerHTML = "<p>"+outputString+"</p>"
})
I hope this helps. desired location is the ID of the tag that you want your result to be displayed.
Had some fun. This should do exactly what you ask about:
I used "oninput" instead of "onblur", because it seems better in this situation. But "onchanged" can be used if preferred
Changed the formatting of your code, so it is easier to read
Uses "regExp" to check for comma
// Global variables
//
var id_dieSideQuant = document.getElementById('id_dieSideQuant'), // retrieve id for for amount of sides on die
id_throwQuant = document.getElementById('id_throwQuant'); // retrieve id for throw amount input
var id_throwTotal = document.getElementById('id_throwTotal'), // local varible to function only for displaying the throw total
id_dieSideNum = document.getElementById('id_dieSideNum'); // local varible to function only for displaying number of sides
// Functions
//
function dieInfo() {
// Hide and clear up the text-fields
//
id_dieSideNum.parentElement.classList.remove("container1");
document.getElementById('id_throwTotal').innerHTML = "";
document.getElementById('id_dieSideNum').innerHTML = "";
//
// Local variables
/*
convert string input into floating integer,
if this doesnt create a number use 0 instead
*/
var getDieSide = parseFloat(id_dieSideQuant.value) || 0,
getTotalThrows = parseFloat(id_throwQuant.value) || 0,
randThrow,
allDieThrows = [];
//
// Errors
if (getDieSide < 2 && id_dieSideQuant.value.length !== 0) { // if die sides input < 2
id_dieSideNum.innerHTML = "<span style='color: red'>Please enter a valid total of die sides; min. 2.</span>"; // display error for improper number of sides for die input
}
if (getTotalThrows < 1 && id_throwQuant.value.length !== 0) { // if die throw amount input is < 1
id_throwTotal.innerHTML = "<span style='color: red'>Please enter a valid throw amount.</span>"; // display error for improper throw amount input
}
if (getDieSide < 2 || getTotalThrows < 1 || (new RegExp(/\d+(?!\.)/).exec(getDieSide.toString())["index"] !== 0 || new RegExp(/\d+(?!\.)/).exec(getTotalThrows.toString())["index"] !== 0)) return false; // Exit if there is something wrong. "/\d+(?!\.)/" checks that there is no comma
//
//
if (id_dieSideQuant.value.length !== 0 && id_throwQuant.value.length !== 0) {
// Throw the die
//
for (var i = 0; i < getTotalThrows; i++) { // throw the dice the total amount of throws using a standard for-loop
randThrow = Math.floor(Math.random() * getDieSide) + 1; // use random function to store random number from die sides input
allDieThrows.push(randThrow);
}
// Display result
//
id_throwTotal.innerHTML = `Total throws: ${getTotalThrows}`; // test- display random number of sides for die
id_dieSideNum.innerHTML = "Your die landed on:<br><br>"; // test - display throw count
for (var i = 0; i < allDieThrows.length; i++) {
id_dieSideNum.innerHTML += "Throw #" + (i + 1) + ": " + allDieThrows[i] + "<br>";
}
id_dieSideNum.parentElement.classList.add("container1");
}
}
// Event Listeners
//
id_dieSideQuant.addEventListener('input', dieInfo); // fire the 'dieInfo' function when the input element is changed (use: 'input' || 'change')
id_throwQuant.addEventListener('input', dieInfo); // fire the 'dieInfo' function when the input element is changed (use: 'input' || 'change')
id_button0.addEventListener('click', dieInfo); // fire the 'dieInfo' function when the input element is changed
body {
color: olivedrab;
font-family: sans-serif;
background-color: #222;
}
.container0 {
padding: 10px;
border: 1px solid orange;
border-radius: 10px;
margin-left: 20px;
}
.container1 {
padding: 5px;
border: 2px solid orangered;
border-radius: 5px;
margin-left: 20px;
margin-top: 10px;
}
<h1>Die-roller</h1>
<div class="container0">
<h2 id="id_infoThrowDie">Throw Amount? <button id="id_button0">Update throw</button></h2>
<input id="id_throwQuant" type="number" min="1" step="1" placeholder="Throw amount"> (min. 1 throw)
<h3 id="id_throwTotal"></h3>
<h2 id="id_infoDie">How many sides on die?</h2>
<input id="id_dieSideQuant" type="number" min="2" step="1" placeholder="Sides on die"> (min. 2 sides)
<div>
<h3 id="id_dieSideNum"></h3>
</div>
</div>

Javascript conditional find/replace

For my javascript project, I have a list that looks like this:
<li id="1">101.33, "book name 1"</li>
<li id="2">600.01, book name 2</li>
<li id="3">001.11, book name 3</li>
etc...
Of which I am supposed to do the following:
Remap the bullet list entries to a new (consistent) tag type (your choice – make it look pretty!).
For entries between 100 and 200, add 100 to the Dewey decimal number.
For entries between 400 and 500, add 200 to the Dewey decimal number.
Entries between 850 and 900 need to have 100 removed from the Dewey decimal number.
Entries between 600 and 650 need to have 17 added to the Dewey decimal number
For items that get changed, append “changed” to the record.
For items that do not get changed, append “no change” to the record.
For records that are incorrect, append “invalid record” to the record
But I'm not sure how to go about it. I want to target any number in the body, or within a list item. Right now I have this:
var z = document.body.li.innerHTML;
if (z >+ 100 && z <= 200)
{
var q = z + 100;
document.body.li.innerHTML=q;
}
}
Can anyone point me in the right direction of the best approach to do this in javascript? Should I be using find/replace instead?
EDIT: Attempted to amend the last ternary if else statement in David Thomas' code. Can't seem to get it to work:
//define valid record number as at-least-one-integer.at-least-one-integer
var reggie = /\d+(.)+d/
if (_newText = reggie) {
'Invalid Record';
}
else if (_newText === a[textProp]) {
'no change';
}
else(_newText != a[textProp]) {
'changed';
}
+ ')';
One approach, is the following (using plain JavaScript, albeit you'll need to use an up-to-date browser):
// first, we need to get all the 'li' items:
var lis = document.querySelectorAll('ul > li'),
// find the relevant text-property for this browser:
textProp = 'textContent' in document ? 'textContent' : 'innerText',
// empty string variable to allow assessment of changes:
_newText = '';
// Remap the bullet list entries to a new (consistent) tag type (your choice – make it look pretty!).
// do this one yourself.
// a function to zero-pad the numbers (I believe a requirement of Dewey Decimal):
function leftPadNumber(num, numLength, padChar) {
var nString = num.toString(),
major = parseInt(num, 10),
minor = parseFloat(nString.substring(nString.indexOf('.'))),
diff = numLength - major.toString().length;
if (diff > 0) {
return new Array(diff + 1).join(padChar || 0) + (major + minor);
} else {
return num;
}
}
// For entries between 100 and 200, add 100 to the Dewey decimal number.
// For entries between 400 and 500, add 200 to the Dewey decimal number.
// Entries between 850 and 900 need to have 100 removed from the Dewey decimal number.
// Entries between 600 and 650 need to have 17 added to the Dewey decimal number
// note that I've taken a very literal interpretation of 'between' (amend if necessary):
function amendedDeweyDecimal(num) {
if (num > 100 && num < 200) {
num += 100;
} else if (num > 400 && num < 500) {
num += 200;
} else if (num > 850 && num < 900) {
num -= 100;
} else if (num > 600 && num < 650) {
num += 17;
}
// happens if num falls somewhere outside of the above constraints:
return num;
}
// iterates over each element in the 'lis' nodeList/collection:
[].forEach.call(lis, function (a) {
/* replaces the found numbers ('m') in the string, using the two
functions, above, and assigns those to the _newText variable:
_newText = a[textProp].replace(/(\d{3}\.\d{2})/, function (m) {
return leftPadNumber(amendedDeweyDecimal(parseFloat(m)).toFixed(2), 3);
});
// For items that get changed, append “changed” to the record.
// For items that do not get changed, append “no change” to the record.
// returns the original text to the element, along with '(no change)'
// (if 'a[textProp]' is exactly equal to '_newText') or with '(changed)'
// (if the two variables are not identical):
a[textProp] = _newText + ' (' + (_newText === a[textProp] ? 'no change' : 'changed') + ')';
});
// For records that are incorrect, append “invalid record” to the record
// I have absolutely no idea how to assess an 'incorrect' record.
JS Fiddle demo.
References:
Array.prototype.forEach().
document.querySelectorAll().
Number.toFixed().
Number.toString().
String.parseFloat().
String.parseInt().
String.replace().
try jQuery .each
$('li').each(function(index, value) {
var val = $(this).text().split(','); //split into array
if (index >= 100 && index < 200) {
//do stuff
}
if (index >= 400 && index < 500) {
//do stuff
}
//etc
});
Regardless if you want to solve this using pure JavaScript or a helper library (like jQuery for example), i would suggest to disassemble your problem into smaller tasks and solve them one by one. At the end they will fit one into another and will build the complete solution. I would have started with three simple functions (reading your description they will be needed often):
the ability to list all LI elements separately
extract the number from the LI content
check if the number in in a given range
The code can look like this:
// count of all LI items
var elements = 0;
// fetch LI item one at a time
var element = document.getElementById(elements+1);
while (element != undefined) {
// get the number
var number = Number(getNumber(element.innerHTML));
// do something with number and or LI element
if (inRange(number, 100, 200)) { /* add 100 ...*/ } // and so on
// go to next element
elements++;
element = document.getElementById(elements+1);
}
function getNumber(elementContent) {
return elementContent.split(",")[0]; // TODO error handling
}
function inRange(number, min, max) {
return (number >= min) && (number <= max);
}
You can introduce simple objects and arrays to store information and states to track the changes of your content.

Better way for al lot of if else

I have a function to change the background color depending on the value of a slider
There are 35 different colors and I now use this code for it (of course it is longer)
if (value < 25) {
color = '#FFFFFF';
} else if (value > 25 && value < 50) {
color = '#F8F8F8';
} else if (value > 50 && value < 75) {
color = '#F0F0F0 ';
}
Is there a way to shorten this up?
If you're incrementing by 25, then make an Array of colors:
var colors = ['#FFFFFF', '#F8F8F8', '#F0F0F0 ', ... ]
And then do a little math to see which index to use.
color = colors[(value - (value % 25)) / 25];
Or if you prefer:
color = colors[Math.floor(value / 25)];
You could make it a two line statement, without arrays, by doing something similar to this:
var rgbvalue = 255-Math.floor(value/25);
var color = 'rgb('+rgbvalue+','+rgbvalue+','+rgbvalue+');';
Of course you would have to limit the value, so that the rgbvalue doesn't get smaller than 0, but I guess you can easily do that, if you know the possible values.
And if you want it to get dark faster, you can multiply the result of the Math.floor operation, like this:
var rgbvalue = 255-(Math.floor(value/25)*5);
And you have the advantage that you don't have to write a huge array of shades of gray.
More bullet-proof version (not fully -proof though)
var colors = ['#FFFFFF','#F8F8F8','#F0F0F0'];
/* this is not that necessary */
var value = input_value || default_input_value;
var color = colors[ Math.floor(value/25) ];
colors = {'#FFFFFF','#F8F8F8','#F0F0F0 '}
color=colors[(int)value/25];
You may need to adjust this depending on the range of value.
Ditch the && and cascade instead
if(values > 75){
//anything above 75 falls here
}
else if(value > 50){
//anything <= 75 but > 50 falls here
}
else if(values > 25){
//anything <= 50 but > 25 falls here
}
else {
//anything <= 25 falls here
}
You could use an array of objects that describe the color and the min and max of the range and then use a function to iterate through the array to find the color between the range.
function getColor(value) {
var colorRanges = [
{ color : '#FFFFFF', min : 0, max : 25 },
{ color : '#F8F8F8', min : 25, max : 50 },
{ color : '#F0F0F0', min : 50, max : 75 }
],
length = colorRanges.length;
while(length--) {
var colorRange = colorRanges[length];
if (value >= colorRange.min && value < colorRange.max) {
return colorRange.color;
}
}
// default color
return colorRanges[0].color;
}
With a little additional effort, you could expose a way to add new colors and ranges, have a default for the range interval, etc. If your colors and range interval are fixed however, this is probably overkill.

I have a field calculating and need to display a minimum if the result is below 60

Sorry this is obviously my first time here, I am just learning how to work in javascript. My question is this: I have some basic calculations determing a price of a service for our non-profit. t is the number of rooms * 0.81. But we have a monthly minimum of $60. So I need to know how I would factor that into the pricing function. I know it goes that "if x < 60, then 60", just not sure how the language would be written. I will include the full js.
var listenerFieldIDs = {"roomCountID":"item4_text_1"}; //Currently the only form we are using for room count has this value set as its ID attribute.
var impactFields = ["item12_text_1","item1_text_1","item16_text_1","item18_text_1","item20_text_1"]; //Field IDs for the form that will be changed constantly.
var estimatedBottleSize = 1.5, occupancyRate = (60 / 100), collectionDuration = 365, soapOuncesRecoverable = 0.63, bottleOuncesRecoverable = 0.47,lbConversion = 0.0626, rate = 0.81;
var $ = function(id){ //Shortcut to save some typing. Instead of having to write out document.getElementById(elementID) every time I need to access an element, I can put $(elementID).property or $(elementID).method() I need more easily.
return document.getElementById(id);
}
var updateFormField = function(id,amount){ //Updates a form field when gives the element ID and the amount.
$(id).value = amount;
}
var updateForm = function(roomCount){
// This is called when all form data needs to be updated. This is generally invoked each time a keystroke in the room count field.
updateFormField(impactFields[0],calculateLbsOfSoap(roomCount).toFixed(2)); //Updating the first form field after calculating the total weight of soap in lbs.
updateFormField(impactFields[1],calculateLbsOfBottles(roomCount).toFixed(2)); //Same thing as above, but bottles/amenities.
updateFormField(impactFields[2],calculateBarsOfSoap(roomCount).toFixed(0)); //Updating the third form field after calculating the total number of distributed units.
updateFormField(impactFields[3],calculateBottles(roomCount).toFixed(0)); //Same as above, but bottles/amenities.
updateFormField(impactFields[4],("$" + calculatePrice(roomCount).toFixed(2))); //Updating price.
}
var listenForNumbers = function(event){ //This function is acting as a handler for when anything is entered into the field.
updateForm($(listenerFieldIDs["roomCountID"]).value);
}
var calculateLbsOfSoap = function (rmCnt){ // Calculate the weight of soap and return the amount.
return checkCount(rmCnt) ? 0 : ((soapOuncesRecoverable * lbConversion) * (rmCnt * occupancyRate) * collectionDuration);
}
var calculateLbsOfBottles = function (rmCnt){ // Calculate the weight of bottled amenities and return the amount.
return checkCount(rmCnt) ? 0 : ((bottleOuncesRecoverable * lbConversion) * (rmCnt * occupancyRate) * collectionDuration);
}
var calculateBarsOfSoap = function(rmCnt){ // Calculate how many bars are distributed if the room count is not 0.
return checkCount(rmCnt) ? 0 : ((calculateLbsOfSoap(rmCnt) * 16) / 3);
}
var calculateBottles = function(rmCnt){ // Calculate how many bottles are distributed if the room count is not 0.
return checkCount(rmCnt) ? 0 : (((calculateLbsOfBottles(rmCnt) * 16) / estimatedBottleSize) * (2 / 3));
}
var calculatePrice = function(rmCnt){
return checkCount(rmCnt) ? 0 : (rmCnt * rate);
}
var checkCount = function(count){ //If the count is 0 or less than 0, the number is useless so just return 0 to prevent odd results.
return (count < 0 || count == 0) ? true : false;
}
var initializeRealTimeCalcToForm = function(){
if(window.attachEvent){
$(listenerFieldIDs["roomCountID"]).attachEvent("onkeydown",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).attachEvent("onkeyup",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).attachEvent("onkeypress",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).attachEvent("onchange",listenForNumbers,false);
} else{
//But if NOT IE... :-D
$(listenerFieldIDs["roomCountID"]).addEventListener("keydown",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).addEventListener("keyup",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).addEventListener("keypress",listenForNumbers,false);
$(listenerFieldIDs["roomCountID"]).addEventListener("change",listenForNumbers,false);
}
}
window.onload = function(){
initializeRealTimeCalcToForm();
}
If you only want to set a minimum value of 60 to the variable myvar, you can do
myvar=Math.max(60,myvar);
Edit:
Then, if you want the value returned by calculatePrice to be at least 60, use:
var calculatePrice=function(rmCnt){
return Math.max(60,checkCount(rmCnt) ? 0 : (rmCnt * rate));
}
Note 1:
Do you know that you can declare functions like this?
function calculatePrice(rmCnt){
return Math.max(60,checkCount(rmCnt) ? 0 : (rmCnt * rate));
}
It's shorter and this way you can call the function before declaring it!
Note 2:
If you want that value to be at least 60, I don't understand the following code:
checkCount(rmCnt) ? 0
Why 0?

Categories