Issues with my First calculation script

Please see attachment of user view, followed by html code relevant to 3 areas and my first poor attempt at writing my very first usable script.

What Im trying to achieve is when a user selects a value/bedroom quantity,a price relating to however many rooms they`ve choosen appears in the EPC total price input field, then if the user also wants a floorplan, they check this box and this adds another £20 to the outstanding bedroom total which is already being displayed. The user then ends up seeing a total price with both the bedroom value and IF selected the checkbox values added together. Hope that makes sense.

<div>
<label for=“bedrooms”>Number of bedrooms</label>
<select name=“bedrooms” id=“bedrooms” onclick=“main()”>
<option value=“1”>1</option>
<option value=“2”>2</option>
<option value=“3”>3</option>
<option value=“4”>4</option>
<option value=“5”>5</option>
<option value=“6”>6</option>
<option value=“7 or More”>7 or More</option>
</select>
</div>

<div>
<label for=“floorplan”>Tick if a floorplan is required</label>
<input type=“checkbox” name=“floorplan” id=“floorplan” value=“Yes”/>
</div>

<div>
<label for=“output”>EPC Total Price</label>
<input class=“output” name=“output” id=“output”/>
</div>

Please dont laugh at my first javascript attempt, I know its not looking too healthy…:blush:

Using the above values in select area, 1-4 = 37.50 /// 5-6 = 45 /// 7 or more = Price on agreement.

price = new Array(37.50,37.50,37.50,37.50,45,45,“Price on agreement”);

floor = new Array(20);

bedrooms = document.getElementById(“bedrooms”).value;
floorplan = document.getElementById(“floorplan”).value;
output = document.getElementById(“output”);

var first = “”;
var second = “”;

function main(){

first += bedrooms[price];
second += floorplan[floor];

var total = first + second;

output.innerHTML = total.value;

}

Once again any help will be greatly appreciated

There are many problem here, so let’s go through them one by one fixing things as we go.

The onchange event is a more reliable one to use for select fields than the onclick event.


<select name="bedrooms" id="bedrooms" onchange="main()">

It’s also better to separate content and behaviour, in much the same way that CSS separates content and presentation. But we can get in to that later.

Setting these values won’t work for you, because they only get the value at the time the page is loaded, which is not very useful later on when you run the main function.


bedrooms = document.getElementById("bedrooms").value;
floorplan = document.getElementById("floorplan").value;

So instead, you can get things working by assigning not the field value, but the field itself. That way from within the main function you can access bedrooms.value to retrieve the value of the moment that you’re interested in.


bedrooms = document.getElementById("bedrooms");
floorplan = document.getElementById("floorplan");

Next up, this array notation doesn’t do what you think it does.


price = new Array(37.50,37.50,37.50,37.50,45,45,"Price on agreement");
floor = new Array(20);

When only one value is given to the array constructor, it creates an array with that many empty items in it.
Instead of using the array constructor, you’re far better off using the array notation instead:


price = [37.50,37.50,37.50,37.50,45,45,"Price on agreement"];
floor = [20];

Your method of accessing array items look to be completely backwards too.

first += bedrooms[price];

The value inside of the square brackets should be the index of the array item that you wish to retrieve. Also, arrays start counting from 0, so you need to knock one off from the bedroom number, to retrieve the correct array item.


first = price[bedrooms.value - 1];

Then with the floorplan price, there’s the same array trouble:

second += floorplan[floor];

In this case too, floor is an array, and floorplan is the value from the checkbox.
The checkbox value doesn’t change, no matter whether the checkbox is checked or not.
Instead, you need to find out if the checkbox is checked, and if it is, to assign an appropriate price.

That can be done with:


if (floorplan.checked) {
    second = floor[0];
} else {
    second = 0;
}

Which can be condensed down to:


second = 0;
if (floorplan.checked) {
    second = floor[0];
}

Or even more condensed:


second = (floorplan.checked) ? floor[0] : 0;

Lastly, your code for updating the form field with the price has some problems.

output.innerHTML = total.value;

The output is a form field, so innerHTML is no good there. You need to set output.value instead. Secondly, the total is a number that you’ve calculated earlier. The total is not a form field. This will work instead:


output.value = total.value;

With those changes, the form will be partially working. Problems still exist though such as when choosing 7 bedrooms, or with how nothing happens when you tick the checkbox, until after you’ve chosen a different number of bedrooms.

Fixes for those things follow in my next post.

Let’s get that checkbox working as you expect it to work. It needs to run the same event that the select box triggers when it’s changed. Instead of adding these events to those form elements, we’ll remove them from the form elements completely:


<select name="bedrooms" id="bedrooms">
...
<input type="checkbox" name="floorplan" id="floorplan" value="Yes" />

Now we can add the events to those form elements from the script. Load the script code from the end of the body, which speeds up the loading of your web page, and allows you to easily work with page elements from your script.


<body>
...
<script src="script.js"></script>
</body>


bedrooms = document.getElementById("bedrooms");
floorplan = document.getElementById("floorplan");
output = document.getElementById("output");

bedrooms.onchange = main;
floorplan.onclick = main;

Now the price automatically updated whenever the checkbox is ticked as well.

We still need to fix the seven bedrooms situation though. When that’s chosen, instead of being a number you have that text message there instead. So the rest of the calculations after that need to only occur if the bedroom price is still a number.

But there’s another problem. The value of the 7th bedroom is not a valid number that we can use to retrieve an item from your array:

<option value="7 or More">7 or More</option>

So instead of using the select value to choose from the array, we can instead completely ignore those values and use the index number of the option that’s selected instead.


first = price[bedrooms.selectedIndex];

After that, you can check to see if the first variable is still a number, and carry on from there.


first = price[bedrooms.selectedIndex];
if (Number(first)) {
    second = (floorplan.checked) ? floor[0] : 0;
    total = first + second;
    output.value = total;
} else {
    output.value = first;
}

Hey Paul,

Really appreciate your time taken to look over this. Im going to look at in depth what you have done this morning as I have been out all weekend, and then I will get back to you via this post once Ive gone through each step.

Thankyou once again :slight_smile:

Ben

Ive had a look through Paul and understand some parts but other sections Im completely lost. (I forgot to mention in the original post, I only started learning javascript 3 weeks ago, and this is literally my first piece of JS to be applied to a working website. I have made little programs, but the issues I have at the moment although I know the very very basics, Im still not very confident how to apply certain programs to certain circumstances, obviously Im hoping this will come with time)

Back to your threads though…

I understand the following:

bedrooms = document.getElementById(“bedrooms”);
floorplan = document.getElementById(“floorplan”);
output = document.getElementById(“output”);

And…

price = [37.50,37.50,37.50,37.50,45,45,“Price on agreement”];
floor = [20];

And…

if (floorplan.checked) {
second = floor[0];
} else {
second = 0;
}

Ive read through all of post 1 and 2 of your step by step processes, but I am completely confused as to what code goes into what script (externally linked or directly after the closing body tag). Forgive me for not being the brightest of people, like I said Im only 3 weeks into JS so its all blowing my head off at the moment (Think I need some vallium) :slight_smile:

Can I ask how long you have studied JS as you seem to be extremely proficient in explaining and writing the code ?

Look forward to hearing from you

Ben

Sometimes people use inline scripts as a shortcut when developing. Most scripts should be in an external script file though, which allows the web browser to cache those scripts in the same way that they cache CSS files and other content.

so its all blowing my head off at the moment (Think I need some vallium) :-)[/quote]

Just take it step by step. If there’s anything that you’re not sure about, just ask. We’ll be here to help advise you about things.

The worst thing to do is to just throw completely solved fully-working code at you. That’s not respecting you, or the learning that you are doing.
I was even told by someone yesterday that I’ll teach them to fish yet, which I take as a high compliment.

It was on-and-off up until 2005. Then things ramped up Xmas 2007 (here’s my first JavaScript post. Squee!) when I realized that I can learn more effectively by helping others with their own issues.

Im in complete agreement with you about not dishing all the code out to a newbie “like myself” as that is the incorrect way of how to grasp and learn new material, just a shunt in the right direction is the best way to go about things… :slight_smile:

Sorry for prying Paul, but do you work as a developer then ?

So far I have the following then:

In my script.js which is an external JS I have:

function main(){

/Creates 2 separate arrays for values to be selected from/
price = [37.50,37.50,37.50,37.50,45,45,“Price on agreement”];
floor = [0];

/Creates the instance of the variable called “Second” for later use/
var second = “”;

first = price[bedrooms.value - 1];

first = price[bedrooms.selectedIndex];
if (Number(first)) {
if (floorplan.checked) {
second = floor[0];
} else {
second = 0;
}
total = first + second;
output.value = “£” + total;
} else {
output.value = “£” + first;
}//ends else
}// ends main function

And internally I have:

/Obtains all element ID`s/
bedrooms = document.getElementById(“bedrooms”);
floorplan = document.getElementById(“floorplan”);
output = document.getElementById(“output”);

bedrooms.onchange = main;
floorplan.onclick = main;

As you will see from the External JS file I have placed “£” in the value for the output, but all Im getting in the output field is diamond shape with a ? in it.

From doing a little research I now know anything in quotes must be proceeded and ended by a \“example”\ but even with this in place I still get this diamond shape and a ? … Am I placing this \“£”\ in the wrong place ?

Secondly the value in the price array being 37.50, is only showing in the output field as 37.5, I undertand certain JS conversion code snippets such as parseInt and parseFloat and eval but again have tried to insert these into the area of code that I thought would make the conversion but it did not work.

Lastly when selecting the checkbox, it is supposed to add an additional £20 to the overall total, but this does not seem to to work either ?

I was also stumped at what : if (Number(first)) means, as Ive never come across this before and have just tried searching on the net for a meaning but found nothing. ?

The Number constructor convert whatever is passed to it in to a number. If it can’t convert it to a number, it return NaN which stands for Not a Number.

The reason why it’s used here, is that one of your array items is a string, so it’s a useful way to deal with that situation.

If that variable called first is a number, perform one set of tasks. Otherwise it can’t be a number, so it must be that string that you have in the array instead which requires different behaviour to occur.

We can make that code even clearer by changing it to:


if (!isNaN(Number(first))) {
    ... is a number
} else {
    ... not a number
}

Or by switching them around, even clearer still:


if (isNaN(Number(first))) {
    ... not a number
} else {
    ... is a number
}

Pernultimate update:

I now have all the calculations working including the checkbox, but the last issue Im trying to sort is how to add the 0 of the 37.5"0" into the total box…

I think it could be math.round… ? so will give this ago, and hopefully post the full working code for you to see - I cant believe Ive spent 6 hours on this now! dont think Ill ever get upto your standards Paul…! :slight_smile:

function main(){

/Creates 2 separate arrays for values to be selected from/
price = [“37.50”,“37.50”,“37.50”,“37.50”,“45.00”,“45.00”,“Price on agreement”];
floor = [“20”];

/Creates the instance of the variable called “Second” for later use/
var second = “”;

first = parseFloat(price)[bedrooms.value - 1];

first = price[bedrooms.selectedIndex];

if (Number(first)) {
if (floorplan.checked) {
second = floor[0];
} else {
second = 0;
}//ends else for second value of 0 and NOT 20.
total = parseFloat(first) + parseFloat(second);
output.value = parseFloat(total);
} else {
output.value = parseFloat(first);
}//ends else

}// ends main function

Ignore that last block of code, as there was something Id missed out with it, and that was upon checking on the 7 or more option, I got the NaN error, so I have removed all parseFloats from the code and I am now trying to find another alternative…

Im seriously going round the twist now after spending 4+ hours on trying to achieve something I can well imagine is ever so simple to rectify, so Im pleading for help as Ive got to the point now where its actually starting to stress me out lol

the 2 problems I have:

  1. when the select box is checked the value that is assigned to the checkbox that being 20 should add to the ongoing total to produce either 57.50 OR 65.00, but all its doing is making a total of 37.520 AND 45.020.

  2. I need a £ sign to be at the front of the total figure, and again I have tried creating a variable with this as its value and then concatenating the variable with the numeric variable together but it just isnt working.

Heres my JS code so far :(external script)

function main(){

/Creates 2 separate arrays for values to be selected from/
price = [“37.5”,“37.5”,“37.5”,“37.5”,“45.0”,“45.0”,“Price on agreement”];
floor = [20];

/Creates the instance of the variable called “Second” for later use/

first = parseInt(price)[bedrooms.value - 1];

first = price[bedrooms.selectedIndex];

if (Number(first)) {
if (floorplan.checked) {
second = floor[0];
}//ends floorplan if statement
else {
second = 0;
}//ends else for second value of 0 and NOT 20.
total = first + second;
output.value = total;
} //ends Number first if statement
else {
output.value = first;
}//ends last else statement

}// ends main function

/=======internal script=========/

/Obtains all element ID`s/
bedrooms = document.getElementById(“bedrooms”);
floorplan = document.getElementById(“floorplan”);
output = document.getElementById(“output”);

bedrooms.onchange = main;
floorplan.onclick = main;

If you dont actually want to give me the full blown answer, could some one at least point me in the right direction as to the type of code Im to be writing in and in relation to what…(I havnt got the knowledge/experience, so sorry for keep harping on, as like 2 of my previous threads have said in this post, Ive literally only started using JS 3 weeks ago, playing with alerts/prompts/confirms etc so this piece of script is well out of my league at the moment)

My head has been on the pillow for the past 8 hours, so get a grip there.

Your script is concatenating the two values together because one of them starts as a string. Bring those array values back to numbers as they were before.

The pound sign issue may be due to the content-type that your web page is set at. No amount of scripting can do anything about that, so attention instead needs to be on how the page is setting its content-type. Your page might be doing nothing in that regard, or it may be setting it to an inappropriate type. Typically setting the content-type to UTF-8 ends up being an effective solution.

That last post wasnt directed at you Paul, so I hope you didnt take offence.Sorry if you did.

I have just tried numerous characters across the whole row of my keyboard starting with the exclamation mark and finishing at the right sided rounded bracket, and guess what… the only symbol that doesnt display without JS producing a default void symbol is the £ symbol, which for the life of me I cannot get my head around…

Ive checked and double checked my character encoding this being :

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<title></title>
<meta name=“description” content=“”/>
<meta name=“keywords” content=“”/>
<meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”/>
<link rel=“stylesheet” href=“mhp_css.css” type=“text/css” media=“screen”/>
<link rel=“stylesheet” href=“fonts/font.css” type=“text/css”/>
<link rel=“shortcut icon” href=“home.ico”/> <link rel=“shortcut icon” href=“home.ico” type=“image/x-icon”/>

I have now also managed to get the last 0 to display in the grand total converting the values in the array data back to integers from strings, by using the to.Precision(3) code : (See below)

function main(){

/Creates 2 separate arrays for values to be selected from/
price = [37.5,37.5,37.5,37.5,45.0,45.0,“Price on agreement”];
floor = [20.0];

var total = “”;

var first = price[bedrooms.selectedIndex];

if (Number(first)) {
if (floorplan.checked) {
second = floor[0];
}//ends floorplan if statement
else {
second = 0;
}//ends else for second value of 0 and NOT 20.

total += first.toPrecision(3) + second;
output.value = total;

} //ends Number first if statement
else {
output.value = first;
}//ends last else statement

}// ends main function
<script type=“text/javascript” src=“script.js”></script>
</head>

The last thing Im still trying to work out is how to add the the 2 values together when the checkbox is ticked as the value in the output field is still being displayed as either 37.520 or 45.520, I have tried adding .value to the end of the second variable but that didnt work so ill keep on it and persevere :slight_smile:

THe pound sterling was a relatively tricky one to solve.
A combination of the unicode documentation for javascript and the [url=“http://en.wikipedia.org/wiki/Pound_sign#Codepoints”]unicode for pound sterling is used to come to a solution there.
Use ‘\u00A3’ for the pound sterling symbol.

With the second issue, the toPrecision(3) is resulting in a string, which when the second variable is added just results in concatenation occurring for you once again.
Instead, get the toPrecision(3) of the final end result once the numbers have been added.

Hi Paul,

I cant thank you enough for your time and effort, I really do appreciate you helping me out, and especially cracking that £ symbol issue.

After Id posted my last lot of code on here, I actually managed to sort the decimal concatenation issue out by using the following code :

function main(){

/Creates 2 separate arrays for values to be selected from/
price = [37.5,37.5,37.5,37.5,45.0,45.0,“Price on agreement”];
floor = [20.0];

var first = price[bedrooms.selectedIndex];

if (Number(first)) {
if (floorplan.checked) {
second = floor[0];
}//ends floorplan if statement
else {
second = 0;
}//ends else for second value of 0 and NOT 20.
total = first + second;
output.value = ‘\u00A3’ + total.toPrecision(4);
} //ends Number first if statement
else {
output.value = first;
}//ends last else statement

}// ends main function

Im not sure If I should feel proud of myself, but Ive actually managed to write a wee program that actually works or at least I think it does, but could I ask if you could check it over for me to see if there are any issues or possible shortcuts ,as and when time permits.
The job of the code is to present the user with 3 options, and in order for the user to carry on with the form they must select “Yes” otherwise the program (while loop) will run indefinatley.
What I also wanted and achieved as to not confuse the user was if they selected either “No” or the “empty” option but then agree to the terms and condition confirmation box, the value inside the checkbox changes to show that of the “Yes” answer. I also managed to make the terms and condition select box mandatory in my PHP file when its to be answered upon clicking submit for the form, so the user Must select Yes, to now submit their form.

My Internal JS for value changing is :

tandc = document.getElementById(“tandc”);
tandc.onchange = accept;

My External JS for value changing is :

function accept(){

while(tandc.value != “yes”){
var agree = confirm(“Please agree to our terms and conditions to continue”);
if(agree == true){
document.getElementById(‘tandc’).options[1].selected=true;
break;
}else{
confirm(“Please agree to our terms and conditions to continue”);
}
}//ends while loop
}//ends accept function

My HTML for the select box is :

<div>
<label for=“tandc”>Select Terms and Conditions</label>
<select name=“tandc” id=“tandc”>
<option value=“”></option>
<option value=“yes”>Yes</option>
<option value=“no”>No</option>
</select>
</div>

My HTML for the submit buttons are :

<div class=“epcSubmitReset”>
<input id=“submit” name=“submit” type=“submit” value=“Submit”/>
<input id=“out” name=“reset” type=“reset” value=“Reset”/>
</div><!–submitReset ends–>

My External JS for the submit button is :

submit =document.getElementById(“submit”);
submit.onclick = accept;

It’s looking good, but one problem is that the while loop continually demands the person agree with the terms and conditions, until they actually agree.
If a person forgets to tick the box, how is a person to then read your terms and conditions without first being forced to agree with them by the prompt?

Good point Paul,

I think what I will have to do is:

Re-write the program so that they still have to say “Yes” in order to submit the form, but as you quite righty said, if the user forgets to select an answer, give that user the chance to read the terms and cons rather than forcing them to accept and then submitting the form.

Either way the terms and cons must have “Yes” selected in order for the form to be submitted, as the user must agree to the companies terms and conditions.

Ill update the thread as and when Ive re-written the program.

Cheers once again Paul.

Think Ive cracked it…

External JS script:

function sendForm(){
if(tandc.value != “yes”){
alert(“Please make sure you have read and agreed to our terms and conditions”)
window.location.hash=“terms”;
}
}

Internal JS script:

submit =document.getElementById(“submit”);
submit.onmouseover = sendForm;

HTML code :

<label name=“terms”>Terms & Conditions</label>

By using onmouseover it now wont submit the form untill the terms and cons has “yes” selected after the re-direct. If the user now forgets to make a selection, the role of “onmouseover” produces an alert box informing the user to read the terms and cons and agree to them, once agreed too, the form is then able to be submitted.
Would you say that this approach is more approapriate or can it be tweaked in anyway ?

Just changed onmouseover for onmousedown.