简体   繁体   中英

Javascript Custom Price Calculator

I have this below code to calculate a custom price based upon selection. It works for stretched canvas, but i was wondering how to make it work for other options if a user selects it. (eg Canvas Boards). If option equals "Canvas Boards" calculate custom price. Many thanks, Deryn.

 function calculate_total() {
     var ttl = 0;
     var len = eval(document.forms['calc']['length'].value);
     var wid = eval(document.forms['calc']['width'].value);
     var thick = document.forms['calc']['frame'].value;
     var strOptions = e.options[e.selectedIndex].text;
     if(len.length == 0) {
         return;
     }
     if(wid.length == 0) {
         return;
     }
     if(thick == 0) {
         return;
     }
     ttl = (len + wid) * 2;
     //inches
     if((ttl >= 24) && (ttl <= 36)) {
         ttl *= .19;
     }
     if((ttl >= 37) && (ttl <= 56)) {
         ttl *= .20;
     }
     if((ttl >= 57) && (ttl <= 76)) {
         ttl *= .21;
     }
     if((ttl >= 77) && (ttl <= 92)) {
         ttl *= .22;
     }
     if((ttl >= 93) && (ttl <= 100)) {
         ttl *= .23;
     }
     switch(thick) {
     case "1.5":
         ttl;
         break;
     case "2":
         ttl;
         break;
     case "3":
         ttl;
         break;
     }
     document.getElementById('total').value = ttl.toFixed(2);
 } // end function definition
<form name="calc" id="calc">
    Length: <input type="text" name="length" id="length" onchange="calculate_total()" /> Inches <br />
    Width: <input type="text" name="width" id="width" onchange="calculate_total()" /> Inches <br />

    <select name="frame" onchange="calculate_total()">
        <option value="0" selected>Select below</option>
        <option value="1.5">Streched Canvas</option>
        <option value="2">Canvas Boards</option>
        <option value="3">Canvas Rolls</option>
        <option value="4">Primed Boards</option>
        <option value="5">Paintings/Printing Streching</option>
    </select>
    <br /><br />
    <b>Total:</b> $ <input id="total" name="total" readonly=true style="border: none" />
</form>

Complete edit:

Example on jsfiddle

In the link provided above, you can see the example, with other function for every option picked from the list. For now they just shows alert window, but you should know what to put there, to count it.

function check_which_selected() {
    selectedOption = document.forms['calc']['frame'].options;
    thick = +selectedOption[selectedOption.selectedIndex].value;
    ttl = 0;
    len = +document.forms['calc']['length'].value;
    wid = +document.forms['calc']['width'].value;

    if (len.length <= 0) return;
    if (wid.length <= 0) return;
    if (thick <= 0) return;

    if (thick == "0") return;
    if (thick == "1.5") calculate_total();
    if (thick == "2") calculate_total_canvas_boards();
    if (thick == "3") calculate_tota_canvas_rolls();
    if (thick == "4") calculate_total_primed_boards();
    if (thick == "5") calculate_total_paintings();
}

This function lets you check, what option is chosed, what values are put into text boxes. If some textbox is empty, or option is not picked, it wont call any function, otherwise, it will call proper function depending on the option chosed. Variables taken from tetboxes, are scoped for both of these function, so their value is assigned in check_which_selected() and then they can be used inside other functions.

You can also use your switch/case to define which function will be called.

Is that something you was looking for?

It's great that you are learning JavaScript. Keep at it!

Are you sure it's working for stretched boards? I see some areas that can be improved, and others that are just plain broken.

First, you are referencing a variable, e , but that variable is never defined. That will cause an error. It looks like e is meant to refer to the frame selector. But, since e is only used to create strOptions , and strOptions is never used, we can just delete that whole line and not even worry about e .

Next, the use of eval is discouraged, especially the way you intend to. It looks like you are trying to get a number from a string. Several points here:

  • There are many easier, safer ways of turning a string into a number. Personally, I'd just use the + operator to do it. Eg, var n = +"10" . parseFloat() is another good option.
  • If the user does not enter a number, you will most likely get an error. For example, if the user enters "n/a", eval() will try to interpret that as script. Assuming n and a are not actual variable names, that will cause an error. But actually, it could be valid JavaScript: If you have variables n and a defined, and they are numbers, this actually will run and not return an error. It will however give unexpected results - it will proceed as if the user entered the actual value that is n divided by a .
  • The user can use your form to execute arbitrary script. Try entering alert("hello world") into one of your form fields. Of course, the user can also just use the address bar or the browser's JavaScript console to execute arbitrary script, so this isn't really a security hole, but still, you don't want that.

The way you are accessing your form is more verbose than you need. Instead of:

document.forms['calc']['length'].value;

You can skip the square bracket notation and the reference to forms :

document.calc.length.value;

I'd go one further and just store a reference to document.calc in a variable:

var f = document.calc;
var len = +f.length.value;
var wid = +f.width.value;
var thick = +f.frame.value;

(Notice how I used + to get a number, as I mentioned earlier)

Guessing here, it looks like you are applying a discount with your ttl *= .19 code, but it looks like you are applying it backwards. Eg, the more canvas your user purchases the higher the cost per inch. Shouldn't it be cheaper per inch the more you purchase? You know, like breakfast cereal?

Either way, there are some flaws in the logic. You are always using less than or equal to and greater than or equal to. Never just plain less than or greater than. So you are missing some values. If I enter length 5 and width 5, my price is $20. But, if I enter length 6 and width 6 my prices is just $4.56. If I enter 8 x 10, I get $6.84, but if I enter 8x10.25, I get $36.50. That can't be right, can it? Instead, do it like this:

if (ttl > 92) {
    ttl *= .23;
}
else if (ttl > 76) {
    ttl *= .22;
}
else if (ttl > 56) {
    ttl *= .21;
}
else if (ttl > 36) {
    ttl *= .20;
}
else {
    ttl *= .19;
}

Your switch statement does absolutely nothing. You can just remove that whole code block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM