Search code examples
jqueryquery-optimization

jQuery - how to calculate a product price from a table of product names, quantity ranges and price ranges


I have 3 products A, B, C

Then I have 2 addons for those products, : 1, 2

Then I have table of price ranges vs quantity ranges. See below

PRODUCT vs QUANTITY PRICES

+---------------+--------+----------+
|    Product    |  Qty   |  Price   |
+---------------+--------+----------+
|       A       | 0-10   |    $2    |
|       A       | 10-20  |    $1    |
+---------------+--------+----------+
|       B       | 0-10   |    $3    |
|       B       | 10-20  |    $2    |
+---------------+--------+----------+
|       C       | 0-10   |    $4    |
|       C       | 10-20  |    $3    |
+---------------+--------+----------+

PRODUCT VS ADDON PRICES

+---------------+----------+----------+
|    Product    |  AddOn   |  Price   |
+---------------+----------+----------+
|       A       | 1        |    $2    |
|       A       | 2        |    $1    |
+---------------+----------+----------+
|       B       | 1        |    $3    |
|       B       | 2        |    $2    |
+---------------+----------+----------+
|       C       | 1        |    $4    |
|       C       | 2        |    $3    |
+---------------+----------+----------+
  • Products are setup as radio buttons
  • Addonons are setup as radio buttons
  • Quantity is setup as an input field

My question

How do I calculate the cost of a product based on what people select from above. I currently have a very long script that does this, but I want to optimise and use arrays or maybe 2d arrays and do it the proper way. The current script is here .

And this is the webpage I have setup with this functionality.

Thanks A LOT in advance!


Solution

  • Having an array of quantities OB.qtty and radios name="product" and name="style" you can find which ones are :checked and combine both values i.e: p1 (for the product 1) and s2 (for the style 2) and get the OB["p1s2"] array of prices pric.

    Now (see example below) pric holds this array

    [2.10, 2.00, 1.80, 1.60, 1.40]
    

    and we have the predefined quantity ranges OB.qtty:

    [  50,  100,  150,  200,  250]
    

    now all you need to do is to: get the user's desired quantity of items; find out what's the OB.qtty respective range key.
    Say the user enters 160 items quantity, to find out the OB.qtty key index use .some().some() MDN Docs (or create a for loop if you need to support IE<9) and use that key index to get the pric[qIdx] into itemPrice (results in: 1.8).
    To add decimals $1.80 use .tofixed(2)

    var OB = {
      wrap : 0.05,
      // quantities
      qtty : [  50,  100,  150,  200,  250],
      // product 1
      p1s1 : [2.00, 1.80, 1.60, 1.40, 1.20],
      p1s2 : [2.10, 2.00, 1.80, 1.60, 1.40],
      p1s3 : [2.25, 2.15, 2.05, 1.95, 1.75],
      // product 2
      p2s1 : [3.00, 2.80, 2.60, 2.40, 2.20],
      p2s2 : [3.10, 3.00, 2.80, 2.60, 2.40],
      p2s3 : [3.50, 3.30, 3.00, 2.80, 2.50]
    };
    
    function calculate() {
      
      var pVal = $("[name=product]:checked").val();           // "p1", "p2" ?
      var sVal = $("[name=style]:checked").val();             // "s1", "s2", "s3" ?
      var qVal = parseInt($("[name=quantity]").val(), 10)||0; // quantity input
      var wVal = $("[name=wrap]:checked").val();              // (wrap) "yes", "no" ?
      var pric = OB[pVal+sVal]; // i.e: OB["p1s3"]            // (returns: array of prices)
    
      var qIdx = 0;
      OB.qtty.some(function(v, i) {
        qIdx = i;
        return v >= qVal;
      });
      
      var itemPrice = pric[qIdx];
      var wrapPrice =  wVal==="yes" ? (qVal * OB.wrap) : 0;
      var total = (qVal * itemPrice) + wrapPrice;
      
      $("[name=total]").val( total.toFixed(2) );
      
    }
    
    $("[name=product], [name=style], [name=wrap]").on("change", calculate);
    $("[name=quantity]").on("input", calculate);
    calculate();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h3>Products</h3>
    
    <label>
      <input type="radio" name="product" value="p1" checked> Product 1
    </label>
    <label>
      <input type="radio" name="product" value="p2"> Product 2
    </label>
    
    <h3>Styles</h3>
    
    <label>
      <input type="radio" name="style" value="s1" checked> Style 1
    </label>
    <label>
      <input type="radio" name="style" value="s2"> Style 2
    </label>
    <label>
      <input type="radio" name="style" value="s3"> Style 3
    </label>
    
    <h3>Quantity</h3>
    
    <input type="number" name="quantity" value="150">
    
    <h3>Wrap individually</h3>
    <label>
      <input type="radio" name="wrap" value="no" checked> No
    </label>
    <label>
      <input type="radio" name="wrap" value="yes"> Yes (+ $0.05 per item)
    </label>
    
    <h3>Price</h3>
    $<input name="total" value="" readonly>

    Note that the above is not ideal, I'd rather ask the client what are the mathematical relations between product vs style vs quantity. (That's what was confusing me from the start...). Otherwise you'll find your-self creating load of price/style Arrays.

    Hope that helped...