I wanted to make a better Gift Aid calculator for UK charity websites—one that’s easier to use, more eye-catching, and better explains how Gift Aid actually works. So I built one for the University of York. This tutorial will help you to build one too.
(NB: this Gift Aid calculator script support all modern browsers as well as Internet Explorer 8 and above.)
the basic structure
Our script will need three main functions:
The first function,
calculateGiftAid(), performs a basic Gift Aid calculation and returns a set of amounts. The second,
updateGiftAidCalculator(), takes the values returned by the first and outputs them to the visible webpage. The third,
initGiftAidCalculator(), starts everything off when the page loads—it runs an initial Gift Aid calculation on the default gift amount and tax rate, and then begins listening for user input that should trigger a recalculation.
step 1: the calculation itself
Let’s begin with the heart of our script: the function that calculates how much Gift Aid can be claimed based on the gifted amount and the giver’s tax rate.
We need to account for a few subtleties of how Gift Aid works:
- The official value of Gift Aid to the charity is 20%. However, that’s not 20% of the original gift, it’s 20% of the sum of both original gift and Gift Aid. Which is actually 25%.1
- For most Gift Aid gifts, the only beneficiary of Gift Aid is the charity. The basic rate of 20% tax was paid on the gift, and the charity claims the entire 20% back. However, higher-rate taxpayers paid more than 20% tax on the gift so they can claim the rest back themselves. So both charity and taxpayer end up better off, but only if the taxpayer is on the higher rate.
- In 2015, there are two higher rates in the UK—40% and 45%—meaning some givers can claim back 20% of their gift and some can claim back 25% (and of course the majority can’t claim anything).
We’ll start with by calculating the Gift Aid amount that the charity can claim. By adding that to the original gift, we can also work out the net gift (i.e. the total amount the charity gains).
Note that before we begin any calculations, we multiply the gifted amount by 100 and use
The next step is to handle the extra amount claimable by higher-rate taxpayers. If the giver pays 40% tax, they can claim back ‘20%’ of the total gift (which, like the charity’s ‘20%’, really works out as 25%!). If they pay 45% tax, the official figure they can claim back goes up to 25% (which really works out at 33%)2.
This time we subtract the amount claimable from the original gift. This gives us the real-terms cost of the gift to the giver, after they’ve claimed back the amount they’re entitled to.
This allows us to pass all our results back to the calling function as expected. But there’s still one problem with our results: the amounts are all in pence, not pounds, since we multiplied the original gift by 100 to make our maths easier. So we need to convert our pence amounts back into pounds. We’ll do this with a simple function called
We now have a working calculator function! It works fine, but it isn’t very future proof. What if the Government adjusts tax rates? If the basic rate of tax changes, every bit of maths in this function will need to be reworked.
A better approach would be to store the basic rate in one variable, and then use that variable in every calculation within this function. Then we’d only need to update a single line of code when the basic rate changes. Unfortunately, this makes the maths rather more complicated3, but it’s worth it:
step 2: updating the DOM
Now that we have our calculating function, we need a way to (1) get the user’s chosen gift value and tax rate into it and (2) display the calculated results to the user. That’s where our DOM-updating function
updateGiftAidCalculator() comes in.
.js-, to mark the DOM elements that should be updated by our script. Specifically, we’ll use these classes:
||Container for all elements in a single Gift Aid calculator|
||The original gift amount (same as
||How much tax the giver is entitled to claim back|
||How much Gift Aid the charity can claim in addition to the gross gift|
||The real cost of the gift to the giver, once the amount they can claim has been subtracted|
||The real amount the charity gets from the gift, once Gift Aid has been added|
Because this function’s purpose is communicating between our calculator and the DOM, some parts of it are a little easier using jQuery. However, it would be wasteful to require jQuery on a webpage solely to make our Gift Aid calculator work. So I’ve included two versions of each example in this section: one that depends on jQuery and one with no dependencies.
Enough preamble—let’s get started by getting the user-inputted gift amount and tax rate and using them to calculate Gift Aid:
Note that the function accepts a single argument, called
$calc in the jQuery version or just
.js-giftaid-calculator wrapper element, or just the element itself in the non-jQuery version4.
We now have a
gift object containing all the data we need from this Gift Aid calculation. Next we will find and update the DOM elements that are used to display Gift Aid numbers to the user:
We use jQuery’s
textContent property) to update all the calculator fields on the page, so the user can see the results for their chosen gift.
Note that the property names of the object
charityClaims—match exactly the property names in the
gift object that contains our Gift Aid calculation results. This simplifies our script considerably:
This function has one more job to do. It’s likely that in the final design, we’ll want to hide the ‘tax you can claim back’ section of the calculator until the user chooses a higher tax rate. (Otherwise, basic-rate givers will see a field that is always £0 and wonder what it’s there for.)
So we’ll build in an extra class—
Now the only thing left to write is the function that initializes our Gift Aid calculator when the webpage loads.
step 3: initializing everything
All Gift Aid calculator code that runs when the page first loads is kept in a single function, which we’ll call
Our initializing function makes heavy use of event listeners, so our non-jQuery version has to work around the differences between the modern
addEventListener API and
attachEvent as used in old versions of Internet Explorer. MDN has a great polyfill for the event listener API, but we don’t need all of its features so we’ll use something much simpler instead:
We also need a way to call the initializing function when the DOM’s ready to be scripted, as a replacement for jQuery’s
$(document).ready(). Compare how
Now that the event-model housekeeping is out of the way, we can write the function itself. First let’s find our calculator elements in the DOM and run an initial Gift Aid calculation on them:
updateGiftAidCalculator(), we don’t assume there’s just one Gift Aid calculator on the page. We get all calculators in the DOM and set each of them up in term, using
Now we’ve run our calculations once, the visible part of the Gift Aid calculator is now ready. We just need to hook up
updateGiftAidCalculator() to the right DOM events, so the amounts in the calculator will update to match the user’s input.
Here we have a decision to make: when should the numbers in the calculator update?
- When the user clicks an ‘Update’ button or presses the Enter key? (This is the most common approach.)
- Immediately as the user types in new gift amounts or clicks a different tax rate?
I strongly believe Option 2 is better—in fact it is a principal reason why I started working on my own Gift Aid calculator. Updating while the user types makes the calculator feel much more responsive; the user instantly sees results as they make changes, which encourages them to experiment to see what happens. Instant changes can make the calculator feel almost fun to use. Option 1 adds an unnecessary action (and time delay) between the user’s actions and their receiving the results5.
To make Option 2 work, we need to update all values whenever the change event is called on the calculator’s
<select> element. We also have to capture individual keystrokes on the input, since its change event is only called when it loses focus. Lastly, we need to turn off the Gift Aid calculator form’s submit element, since we won’t be using it.
addEventListener() function we created earlier.
The most unexpected thing about our
initGiftAidCalculator() implementation is the addition of another tiny function:
updateGiftAidDelegate(). The point of this extra function (which itself just returns another function) is to create a closure around our call to
calc element to
updateGiftAidCalculator() when it is called by an event listener. By passing
calc in as an argument, we avoid having to traverse up the DOM to find the right ancestor element every single time an event is triggered.
All that’s left to do is our Gift Aid calculator design—coming soon in part two of this tutorial…
Don’t read this footnote if algebra gives you nightmares. But for the mathematically inclined among you, here’s why Gift Aid is officially 20% but really 25%. We’ll use a starting gift of £10 as an example.
The rule is that Gift Aid is worth 20% (i.e. a fifth) of the whole gift—that is, both the gift and its additional Gift Aid. If we make that into an equation (we’ll call the Gift Aid amount x to make things easier), Gift Aid appears on both sides of the equals sign:
x = (£10 + x) ÷ 5
So to ‘solve x’ and work out the Gift Aid, we must (in the words of a thousand GCSE Maths textbooks) simplify:
a: multiply each side by 5:
5x = £10 + x
b: take x (one Gift Aid) from each side:
4x = £10
c: divide each side by 4:
x = £10 ÷ 4
Therefore the Gift Aid amount is one-fourth (25%) of the original gift—in this case, £2.50. ↩
Why can higher-rate taxpayers claim money back, and why do 45% taxpayers get more than 40% taxpayers?
The short answer is, ‘because HMRC says so’, but we can give a slightly more helpful answer by looking at things this way:
- The basic principle of Gift Aid is that charitable giving should be tax-free. (This is an oversimplification, but it will do for now.)
- So HMRC agrees to refund all the income tax paid on a charitable gift via Gift Aid.
- If a gift comes from a higher-rate taxpayer, more income tax was paid on that gift; therefore there is a bigger amount for HMRC to refund.
- Then the only question is how that amount gets distributed between the charity and the giver. The answer is simple: the charity always gets the amount of tax a basic-rate taxpayer would have paid (i.e. 20%).
- Anything left after the charity’s cut goes back to the giver.
- Because the charity’s cut is the same as the basic rate, that means there is no tax left for basic-rate givers to get back, but there is tax left for higher-rate taxpayers to receive.
(Of course, all this depends on the giver and the charity actually claiming the refunds they’re entitled to from HMRC.)
So for a highest-rate taxpayer:
- Income tax paid was 45%
- Charity takes 20%
- Therefore 25% is left over for the taxpayer to claim.
Scary algebra part two. To make an equation that will work for any basic tax rate, we need to introduce the letter y to represent the basic rate (e.g. if the basic rate is 20%, y = 20):
x = (£10 + x) × (y / 100)
This equation is a pain to simplify, but it’s possible:
a: rearrange right-hand side:
x = ((£10 + x) × y) ÷ 100
b: multiply each side by 100:
100x = (£10 + x) × y
c: rearrange again:
x × 100 = (£10 × y) + (x × y)
d: subtract (x × y) from each side:
(x × 100) - (x × y) = £10 × y
e: simplify the multiplications on the left-hand side:
x × (100 - y) = £10 × y
f: divide each side by (100 - y):
x = (£10 × y) ÷ (100 - y)
And we’re done! Just replace y with the basic rate of tax to solve x:
x = (£10 × 20) ÷ (100 - 20) = £2.50
I doubt these workings are useful to anyone, but they took ages to figure out so I’m preserving them here for posterity…! ↩
We use the
calcwrapper element to scope the
updateGiftAidCalculator()function to a single Gift Aid calculator, by using
calcas the starting point for finding the other DOM elements we need. We do this to allow for the (probably only theoretical) possibility that there could be more than one Gift Aid calculator on the same page. If we didn’t do this scoping, and there were two Gift Aid calculators on a page, inputting the gift amount in one calculator would change both calculators’ totals. ↩
Are there downsides to instant updating? Possibly, but I haven’t come across any. Certainly there are no performance concerns in updating on every keystroke, since the script runs very quickly under normal conditions (easily quicker than a user can type), and there is no round-tripping to the server required. ↩