SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Enthusiast
    Join Date
    May 2012
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    JavaScript to calculate shopping cart

    This is my first shot at writing a JavaScript to calculate a shopping cart. Naturally, it doesn't work. I was hoping someone out there would be able to offer some suggestions as to how to fix it.

    Thanks in advance for your help!!

    Code:
    /* I built this script based on the guidance and examples I found 
    
    here: 
    
    http://www.javascript-coder.com/javascript-form/javascript-calcul
    
    ator-script.phtml
    */
    
    
    
    <script>
    var theForm = document.forms["order"];
    
    var bakery_prices= new Array();
    bakery_prices["None"]=0;
    bakery_prices["sourdough"]=5;
    bakery_prices["bread"]=3;
    
    var mns_prices= new Array();
    mns_prices["None"]=0;
    mns_prices["filet"]=5;
    mns_prices["fish"]=5;
    
    var produce_prices= new Array();
    produce_prices{["None"]=0;
    produce_prices["asparagus"]=3;
    produce_prices["pineapple"]=2;
    
    var cnd_prices= new Array();
    cnd_prices["None"]=0;
    cnd_prices["cheddar"]=3;
    cnd_prices["milk"]=4;
    
    var wine_prices= new Array();
    wine_prices["None"]=0;
    wine_prices["chardonnay"]=25;
    wine_prices["merlot"]=20;
    
    
    function getbakeryPrice()
    {
        var bakeryPrice=0;
        var theForm = document.forms["order"];
        var selectedbakery = theForm.elements["bakery"];
        bakeryPrice = bakery_prices[selectedbakery.value];
        
        return bakeryPrice;
    }
    function getmnsPrice() 
    {
        var mnsPrice=0;
        var theForm = document.forms["order"];
        var selectedmns = theForm.elements["mns"];
        mnsPrice = mns_prices[selectedmns.value];
        
        return mnsPrice;
    }
    function getproducePrice()
    {
        var producePrice=0;
        var theForm = document.forms["order"];
        var selectedproduce = theForm.elements["produce"];
        mnsPrice = produce_prices[selectedproduce.value];
        
        return producePrice;
    }
    function getcndPrice()
    {
        var cndPrice=0;
        var theForm = document.forms["order"];
        var selectedcnd = theForm.elements["cnd"];
        mnsPrice = cnd_prices[selectedcnd.value];
        
        return cndPrice;
    }
    function getwinePrice()
    {
        var winePrice=0;
        var theForm = document.forms["order"];
        var selectedwine = theForm.elements["wine"];
        mnsPrice = wine_prices[selectedwine.value];
        
        return winePrice;
    }
    
    function calculateTotal()
    {
        var totalPrice = getbakeryPrice() + getmnsPrice() + 
    
    getproducePrice() + getcndPrice() + getwinePrice();
    
    var divobj = document.getElementById('totalPrice');
    divobj.style.display="block";
    divobj.innerHTML = "Your Order Total is $"+totalPrice;
    }
    
    function hideTotal()
    {
        var divobj = document.getElementById('totalPrice');
        divobj.style.display='none';
    }
        
    </script>

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,696
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Rick Sebastian View Post
    This is my first shot at writing a JavaScript to calculate a shopping cart. Naturally, it doesn't work. I was hoping someone out there would be able to offer some suggestions as to how to fix it.
    Here's an update to the code, where the arrays or prices have been removed and had the prices put in to the select field.
    I've also refactored the functions so that they all perform very simple tasks, and as such they become much easier to modify and maintain.

    You'll also find that there's a demo page with this code up at http://jsfiddle.net/pmw57/NcLuG/3/

    Code javascript:
    function getPrice(itemField) {
        return itemField.value || 0;
    }
     
    function getQuantity(quantityField) {
        return parseInt(quantityField.value, 10) || 0;
    }
     
    function updateItemQuantity(itemField, quantityField) {
        var quantity = getQuantity(quantityField);
        if (quantity < 1) {
            quantity = 1;
        }
     
        if (getPrice(itemField)) {
            quantityField.value = quantity;
        } else {
            quantityField.value = quantityField.defaultValue;
        }
    }
     
    function getItemTotal(itemField, quantityField) {
        return getPrice(itemField) * getQuantity(quantityField);
    }
     
    function hide(el) {
        el.className = 'hidden';
    }
     
    function show(el) {
        el.className = '';
    }
     
    function updateTotal(el, amount) {
        hide(el);
        if (amount > 0) {
            show(el);
            el.innerHTML = "Your Order Total is $" + amount;
        }
    }
     
    function forEachFormItem(form, items, func) {
        var i,
            item,
            itemField,
            quantityField,
            result = 0;
        for (i = 0; i < items.length; i += 1) {
            item = items[i];
            itemField = form.elements[item],
            quantityField = form.elements[item + 'quantity'],
            result += func(itemField, quantityField);
        }
        return result;
    }
     
    function calculateTotal() {
        var form = this,
            items = ['bakery', 'mns', 'produce', 'cnd', 'wine'],
            total = 0,
            priceField = form.priceField;
     
        forEachFormItem(form, items, updateItemQuantity);
        total = forEachFormItem(form, items, getItemTotal);
     
        updateTotal(priceField, total);
    }
     
    var theForm = document.getElementById('order');
    theForm.priceField = document.getElementById('totalPrice');
    theForm.onchange = calculateTotal;
    &#8203;
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Enthusiast
    Join Date
    May 2012
    Posts
    28
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Paul - Thanks so much for all your help!! As I said earlier, it was my first attempt to write a shopping cart script. Obviously still a lot of practice required.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,696
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Rick Sebastian View Post
    Paul - Thanks so much for all your help!! As I said earlier, it was my first attempt to write a shopping cart script. Obviously still a lot of practice required.
    One of the updates that I made is to set the quantity field to 1 when someone chooses an item.

    Because we don't want functions that get values (such as to get the item totals) to also set the quantity as a side effect, it's better to set the quantity first, and then to get the item totals. That would normally mean though creating two early identical loops in separate functions, one to set the quantity, and another function to get the item totals.

    So instead, there is one single function that loops through the items, and passes those item and quantity fields on to whichever function is given.

    Code javascript:
    function forEachFormItem(form, items, func) {
        var i,
            item,
            itemField,
            quantityField,
            result = 0;
        for (i = 0; i < items.length; i += 1) {
            item = items[i];
            itemField = form.elements[item],
            quantityField = form.elements[item + 'quantity'],
            result += func(itemField, quantityField);
        }
        return result;
    }

    Which allows us to update the quantity fields of the form with:

    Code javascript:
    forEachFormItem(form, items, updateItemQuantity);

    Or to get the item totals with:

    Code javascript:
    total = forEachFormItem(form, items, getItemTotal);

    If we want to push things further than that, we can rewrite the forEachFormItem function using more modern JavaScript, so that it is:

    Code javascript:
    function forEachFormItem(form, items, func) {
        var result = 0;
        items.forEach(function (item) {
            var itemField = form.elements[item],
                quantityField = form.elements[item + 'quantity'];
            result += func(itemField, quantityField);
        });
        return result;
    }

    Or, we can make the function even smaller still by using the reduce method, but at the cost of understanding what's going on:

    Code javascript:
    function forEachFormItem(form, items, func) {
        return items.reduce(function (result, item) {
            return result + func(form.elements[item], form.elements[item + 'quantity']);
        }, 0);
    }

    So that's getting the the point of being too compact to easily understand, which makes the previous function or the code from earlier ends up being a better choice, due to how much easier it is to understand what they're doing.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •