Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Script to equip and operate a discount code input field on a storefront page. The discount allows a purchaser to provide one of a set of valid discount codes. If the submitted code is valid, then this script applies it. If the submitted code is not valid, then the attempt is ignored.
<!-- Put discounts here. The general format is "DISCOUNT_NAME is NUMBER%". For example "DVSAP16 is 50%".
Put a comma between each discount code description. Invalid discount codes are ignored. -->
<div id="valid-codes" style="display: none">
Mountain Goat is 50%, metric is 10%, tomato is 15%
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
(function() {
$(document).ready(function() {
// This script is restricted to storefront checkout pages.
if (RegExp('checkOut.jsp\\?storefront_KEY=').test(window.location.href)) {
// Parse discount codes.
var terms = document.querySelector('#valid-codes')
.innerHTML
.split(',')
.filter(function(t) { return t.trim().length > 0; })
.reduce(reducer, {});
console.log("terms: " + JSON.stringify(terms));
// Update the total by getting the page shipping charge and
// formatting the subtotal, shipping and total fields.
function updateTotal() {
var sub = parseFloat($('*[name=sub]').val());
var discount = 0.0;
var discountCode = $('#discount_code').val();
if (Object.keys(terms).indexOf(discountCode) == -1) {
console.log("Invalid discount code in checkout, '" + discountCode + "'");
} else {
console.log("Valid discount code in checkout, '" + discountCode + "', rate is " + terms[discountCode]);
var discountRate = terms[discountCode];
discount = -1 * sub * discountRate;
}
if (discount != 0.0) {
$('#discount').val(discount.toFixed(2));
} else {
$('#discount').val('');
}
var shipping = parseFloat($('[name=shipping]').val());
shipping = shipping !== null ? shipping : 0;
$('*[name=shipping]').val(shipping.toFixed(2));
var amountDisplay = sub + shipping + discount;
$('*[name=amountDisplay]').val(amountDisplay.toFixed(2));
// Just A Number. Cannot be fancy.
$('*[name=amount]').val(amountDisplay.toFixed(2));
}
// Add the discount code and amount fields.
$('td:contains("Shipping/Handling")').filter(':last').parent().before($('#discount_row'));
$('#apply_discount').click(updateTotal);
}
// Parse the discount codes into a name and an amount.
// @param [Object] a reduction target
// @param [String] t String to parse. Should be "DISCOUNT_NAME is DISCOUNT_AMOUNT%"
function reducer(a, t) {
m = /\s*(.+?)\s+is\s+(\d+)%/.exec(t);
if (m == null) {
console.log("Unable to derive a discount rate from '" + t + "'.");
} else {
try {
var v = parseFloat(m[2]);
a[m[1]] = v / 100.00;
} catch (e) {
console.log(e + " parsing discount rate from '" + t + "'.");
}
}
return a;
}
});
})();
</script>
<!-- Style changes to make the totals look better. -->
<style type="text/css">
/* Make the subtotals and totals right-justified. */
#sub,
#discount,
#shipping,
#amountDisplay {
padding-right: 15px;
text-align: right;
}
#discount_code {
font-family: Droid Sans;
font-size: 11pt;
text-align: left;
}
td input {
text-align: right;
}
#shoppingCart a {
font-size: 18pt;
font-weight: 600;
font-family: Arial;
color: forestgreen;
padding-left: 20px;
padding-right: 20px;
}
</style>
<div style="display:none" class="discount">
<table>
<thead/>
<tbody>
<tr id="discount_row">
<td></td>
<td>
Discount code:
<!-- Change "discount_code" to the API name of the donation custom field for the discount name. -->
<input size="14" id="discount_code"></td>
<td align="right">Discount:</td>
<td></td>
<td align="right">
<!-- Change "discount_amount" to the API name of the donation custom field for the discount amount (not percentage!). -->
<input id="discount" value="" size="7" readonly name="discount_amount"></td>
<td>
<input type="button" value="Apply" id="apply_discount" />
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.