Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
v:2.0:snippets:updating_total_price_with_option_modifers [2023/06/22 15:19] adamv:2.0:snippets:updating_total_price_with_option_modifers [2023/07/12 10:38] (current) – [Dynamically triggering recalculation] adam
Line 10: Line 10:
 <code javascript> <code javascript>
 <script> <script>
-// Dynamic Price Calculation v3.2 +// Dynamic Price Calculation v3.3 
-var pricemod_regex=/[{\|]p([+\-:])([\d\.]+)(?:\D{3})?(?=[\|}])/,id_regex=/^(\d+):/,FC=FC||{};function initDynamicPrice(){ADJUST={},$("input,select").off("change.foxy-dynamic-price"),$('form[action*="'+FC.settings.storedomain+'"]').each((function(){var t=$(this),a="",e={products:{}};$(this).find("[name='name'],[name^='name||'],[name$=':name'],[name*=':name||']").each((function(){var r=getId(this.name),i=r?r+":":"",c=parseFloat(t.find("[name='"+i+"price'],[name^='"+i+"price||']").first().val()),s={id:r,code:"",base_price:isNaN(c)?0:c,quantity:1,attributes:{},has_quantity:!1},n=t.find("[name='"+i+"quantity'],[name^='"+i+"quantity||']"),o=t.find("[name='"+i+"code'],[name^='"+i+"code||']");if(o.length>0&&(s.code=clearHash(o.first().val()),""===a&&(a=s.code)),n.length>0){var h=0,d=getElementType(n);["select","text"].indexOf(d)>-1?(s.has_quantity=!0,h=parseFloat(clearHash(n.val()))):["radio","checkbox"].indexOf(d)>-1&&(s.has_quantity=!0,1==n.filter(":checked").length&&(h=parseFloat(clearHash(n.filter(":checked").val())))),isNaN(h)&&(h=0),s.quantity=h}e.products[r]=s}));t.attr("data-fc-form-code")&&(a=t.attr("data-fc-form-code")),""!==a&&($(this).find("input,select").each((function(){if(!this.disabled){var t=getId(this.name),r=getName(this.name),i=getElementType($(this));if("quantity"!=r)if("price"!=r||"hidden"==i){if("SELECT"==this.tagName){var c=!1;$(this).children("option").each((function(){this.value.search(pricemod_regex)>-1&&(c=!0)})),c&&($(this).data("fc-adjust-for",a),e.products[t].attributes[clearHash(this.name)]=clearHash(this.value),$(this).on("change.foxy-dynamic-price",(function(){ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value),recalcTotal()})))}else if(this.value.search(pricemod_regex)>-1)switch($(this).data("fc-adjust-for",a),$(this).attr("type")){case"checkbox":$(this).is(":checked")?e.products[t].attributes[clearHash(this.name)]=clearHash(this.value):e.products[t].attributes[clearHash(this.name)]="",$(this).on("change.foxy-dynamic-price",(function(){$(this).is(":checked")?ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value):ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]="",recalcTotal()}));break;case"radio":e.products[t].attributes.hasOwnProperty(clearHash(this.name))||(e.products[t].attributes[clearHash(this.name)]=""),$(this).is(":checked")&&(e.products[t].attributes[clearHash(this.name)]=clearHash(this.value)),$("[name='"+this.name+"']").data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value),recalcTotal()}))}}else $(this).data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){var a=0;(["select","text"].indexOf(i)>-1||["radio","checkbox"].indexOf(i)>-1&&$(this).is(":checked"))&&(a=parseFloat(clearHash(this.value))),isNaN(a)&&(a=0),ADJUST[$(this).data("fc-adjust-for")].products[t].base_price=a,recalcTotal()}));else $(this).data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){var a=0;(["select","text"].indexOf(i)>-1||["radio","checkbox"].indexOf(i)>-1&&$(this).is(":checked"))&&(a=parseFloat(clearHash(this.value))),isNaN(a)&&(a=0),ADJUST[$(this).data("fc-adjust-for")].products[t].quantity=a,recalcTotal()}))}})),ADJUST[a]=e)})),recalcTotal()}function clearHash(t){return t.replace(/\|\|[\d\w]+(?:\|\|open)?$/,"")}function getNameParts(t){return(t=clearHash(t)).match(/(?:(\d+):)?(.*)/)}function getId(t){var a=getNameParts(t);return id_regex.test(this.name)&&(prefix=parseInt(this.name.match(id_regex)[0])),void 0===a[1]?0:parseInt(a[1])}function getName(t){return getNameParts(t)[2]}function getElementType(t){if("SELECT"==t[0].tagName)return"select";if("INPUT"==t[0].tagName)switch(t.attr("type").toLowerCase()){case"text":case"number":case"tel":return"text";default:return t.attr("type").toLowerCase()}}function recalcTotal(){for(f in ADJUST){var t=0,e=0;for(p in ADJUST[f].products){var r=ADJUST[f].products[p].base_price,i=0;for(a in ADJUST[f].products[p].attributes){var c=ADJUST[f].products[p].attributes[a].match(pricemod_regex);if(c)switch(c[1]){case":":r=parseFloat(c[2]);break;case"+":i+=parseFloat(c[2]);break;case"-":i-=parseFloat(c[2])}}r+=i,t+=r*=ADJUST[f].products[p].quantity,e+=ADJUST[f].products[p].quantity}"function"==typeof fcFormatPrice&&(t=fcFormatPrice(t,f)),"function"==typeof fcFormatQuantity&&(e=fcFormatQuantity(e,f));var s="object"==typeof FC&&FC.hasOwnProperty("json")&&FC.json.config.hasOwnProperty("currency_format")?jQuery.trim(FC.util.money_format(FC.json.config.currency_format,t)):t.formatMoney(2);$("."+f+"_total").html(s),$("."+f+"_total_quantity").html(e)}}FC.onLoad=function(){FC.client.on("ready.done",initDynamicPrice)},Number.prototype.formatMoney=function(t,a,e){var r=this,i=(t=isNaN(t=Math.abs(t))?2:t,a=null==a?".":a,e=null==e?",":e,r<0?"-":""),c=parseInt(r=Math.abs(+r||0).toFixed(t))+"",s=(s=c.length)>3?s%3:0;return i+(s?c.substr(0,s)+e:"")+c.substr(s).replace(/(\d{3})(?=\d)/g,"$1"+e)+(t?a+Math.abs(r-c).toFixed(t).slice(2):"")};+var pricemod_regex=/[{\|]p([+\-:])([\d\.]+)(?:\D{3})?(?=[\|}])/,id_regex=/^(\d+):/,FC=FC||{};function initDynamicPrice(){ADJUST={},$("input,select").off("change.foxy-dynamic-price"),$('form[action*="'+FC.settings.storedomain+'"]').each((function(){var t=$(this),a="",e={products:{}};$(this).find("[name='name'],[name^='name||'],[name$=':name'],[name*=':name||']").each((function(){var r=getId(this.name),i=r?r+":":"",s=parseFloat(t.find("[name='"+i+"price'],[name^='"+i+"price||']").first().val()),c={id:r,code:"",base_price:isNaN(s)?0:s,quantity:1,attributes:{},has_quantity:!1},n=t.find("[name='"+i+"quantity'],[name^='"+i+"quantity||']"),o=t.find("[name='"+i+"code'],[name^='"+i+"code||']");if(o.length>0&&(c.code=clearHash(o.first().val()),""===a&&(a=c.code)),n.length>0){var d=0,h=getElementType(n);["select","text"].indexOf(h)>-1?(c.has_quantity=!0,d=parseFloat(clearHash(n.val()))):["radio","checkbox"].indexOf(h)>-1&&(c.has_quantity=!0,1==n.filter(":checked").length&&(d=parseFloat(clearHash(n.filter(":checked").val())))),isNaN(d)&&(d=0),c.quantity=d}e.products[r]=c}));t.attr("data-fc-form-code")&&(a=t.attr("data-fc-form-code")),""!==a&&($(this).find("input,select").each((function(){if(!this.disabled){var t=getId(this.name),r=getName(this.name),i=getElementType($(this));if("quantity"!=r)if("price"!=r||"hidden"==i){if("SELECT"==this.tagName){var s=!1;$(this).children("option").each((function(){this.value.search(pricemod_regex)>-1&&(s=!0)})),s&&($(this).data("fc-adjust-for",a),e.products[t].attributes[clearHash(this.name)]=clearHash(this.value),$(this).on("change.foxy-dynamic-price",(function(){ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value),recalcTotal()})))}else if(this.value.search(pricemod_regex)>-1)switch($(this).data("fc-adjust-for",a),$(this).attr("type")){case"checkbox":$(this).is(":checked")?e.products[t].attributes[clearHash(this.name)]=clearHash(this.value):e.products[t].attributes[clearHash(this.name)]="",$(this).on("change.foxy-dynamic-price",(function(){$(this).is(":checked")?ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value):ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]="",recalcTotal()}));break;case"radio":e.products[t].attributes.hasOwnProperty(clearHash(this.name))||(e.products[t].attributes[clearHash(this.name)]=""),$(this).is(":checked")&&(e.products[t].attributes[clearHash(this.name)]=clearHash(this.value)),$("[name='"+this.name+"']").data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){ADJUST[$(this).data("fc-adjust-for")].products[t].attributes[clearHash(this.name)]=clearHash(this.value),recalcTotal()}))}}else $(this).data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){var a=0;(["select","text"].indexOf(i)>-1||["radio","checkbox"].indexOf(i)>-1&&$(this).is(":checked"))&&(a=parseFloat(clearHash(this.value))),isNaN(a)&&(a=0),ADJUST[$(this).data("fc-adjust-for")].products[t].base_price=a,recalcTotal()}));else $(this).data("fc-adjust-for",a).on("change.foxy-dynamic-price",(function(){var a=0;(["select","text"].indexOf(i)>-1||["radio","checkbox"].indexOf(i)>-1&&$(this).is(":checked"))&&(a=parseFloat(clearHash(this.value))),isNaN(a)&&(a=0),ADJUST[$(this).data("fc-adjust-for")].products[t].quantity=a,recalcTotal()}))}})),ADJUST[a]=e)})),recalcTotal()}function clearHash(t){return t.replace(/\|\|[\d\w]+(?:\|\|open)?$/,"")}function getNameParts(t){return(t=clearHash(t)).match(/(?:(\d+):)?(.*)/)}function getId(t){var a=getNameParts(t);return id_regex.test(this.name)&&(prefix=parseInt(this.name.match(id_regex)[0])),void 0===a[1]?0:parseInt(a[1])}function getName(t){return getNameParts(t)[2]}function getElementType(t){if("SELECT"==t[0].tagName)return"select";if("INPUT"==t[0].tagName)switch(t.attr("type").toLowerCase()){case"text":case"number":case"tel":return"text";default:return t.attr("type").toLowerCase()}}function recalcTotal(){for(f in ADJUST){var t=0,e=0;for(p in ADJUST[f].products){var r=ADJUST[f].products[p].base_price,i=0;for(a in ADJUST[f].products[p].attributes){var s=ADJUST[f].products[p].attributes[a].match(pricemod_regex);if(s)switch(s[1]){case":":r=parseFloat(s[2]);break;case"+":i+=parseFloat(s[2]);break;case"-":i-=parseFloat(s[2])}}r+=i,t+=r*=ADJUST[f].products[p].quantity,e+=ADJUST[f].products[p].quantity}"function"==typeof fcFormatPrice&&(t=fcFormatPrice(t,f)),"function"==typeof fcFormatQuantity&&(e=fcFormatQuantity(e,f)),t=adjustDisplayPrice(t);var c="object"==typeof FC&&FC.hasOwnProperty("json")&&FC.json.config.hasOwnProperty("currency_format")?jQuery.trim(FC.util.money_format(FC.json.config.currency_format,t)):t.formatMoney(2);$("."+f+"_total").html(c),$("."+f+"_total_quantity").html(e)}}function adjustDisplayPrice(t){return"function"!=typeof fc_adjust_price_display||(adjusted_price=fc_adjust_price_display(t),void 0===adjusted_price||isNaN(parseFloat(adjusted_price)))?t:parseFloat(adjusted_price)}FC.onLoad=function(){FC.client.on("ready.done",initDynamicPrice)},Number.prototype.formatMoney=function(t,a,e){var r=this,i=(t=isNaN(t=Math.abs(t))?2:t,a=null==a?".":a,e=null==e?",":e,r<0?"-":""),s=parseInt(r=Math.abs(+r||0).toFixed(t))+"",c=(c=s.length)>3?c%3:0;return i+(c?s.substr(0,c)+e:"")+s.substr(c).replace(/(\d{3})(?=\d)/g,"$1"+e)+(t?a+Math.abs(r-s).toFixed(t).slice(2):"")};
 </script> </script>
 </code> </code>
Line 41: Line 41:
  
 <code javascript>initDynamicPrice();</code> <code javascript>initDynamicPrice();</code>
 +
 +==== Modify dynamically calculated total price ====
 +
 +If you need to dynamically modify the calculated price, for example if your product prices are tax exclusive, but you want to show the calculated price as tax inclusive, you can define a function on your page to achieve that result. The function has a name of ''fc_adjust_price_display'', and is passed a single argument which is the dynamically calculated total price. The function should return your modified price.
 +
 +As an example, let's say you want to account for a 25% inclusive tax on your product prices, that would look like this:
 +
 +<code javascript><script>
 +  function fc_adjust_price_display(price) {
 +    return price * 1.25;
 +  }
 +</script></code>
 ===== That's it! ===== ===== That's it! =====
  

Site Tools