Motivation

A common customization scenario we hear about is performing an action after a user donates. When a donation comes in you may want to alert someone, update a report, or log the donation to a 3rd party system. The most obvious way to do this is by writing a custom donation form with the NetCommunity API, but that’s an awful lot of work just to tack something onto the end of the donation process. In this article I’ll show you an easy way to take action after a constituent donates online. We’ll be relying on the custom confirmation screen feature of the donation form, but all the techniques will work with the event and membership forms as well.

Technique

To perform an action after a donation, we need to answer two questions:

1.       How do we know a user has just donated? The URL of the donation form doesn’t change after a completed donation.

2.       How do we access the transaction data? To do anything interesting after a donation, we will need some information about the transaction. The amount donated, for instance.

The answers are to be found in custom confirmation screens. Custom confirmation screens let you design the page (using the NetCommunity WYSIWYG editor and merge fields) that shows after a donation. You have complete control over the markup. We’re going to take advantage of that to introduce some special markup that will make it easy for JavaScript to read values from the confirmation screen. Then we can determine if we are on a confirmation screen and get any relevant transaction values.

Enough talk. Let’s code.

Simple Example

I’m going to use jQuery to pull values off of the confirmation screen. You can use whatever JavaScript technique you like, but I recommend jQuery because it’s easy to write, it’s fast, and it’s already included on every NetCommunity page.

First, I’ll create a donation form with a really simple custom confirmation screen. Here’s the HTML for my screen (I’ve abbreviated the merge field markup for readability):

<div>

 <img src=”...” (Individual.Begin Section)>

</div>

<div>

 Name:<span class="TSName"><img src="..." (First Name)></span>

</div>

<div>

 <img src="..." (Individual.End Section)>

</div>

<div>

 Amount:<span class="TSAmount"><img src="..." (Gift Amount)></span>

</div>

This just displays the first name of the donor and the amount of the donation. If you look carefully though, I’ve added a “class” attribute to the span tags that hold the merge fields. jQuery loves class attributes, and makes it super easy to get data from elements with unique classes. If you feel more comfortable using document.GetElementById, then by all means give the span tags an Id attribute.

Now that we have our custom confirmation screen all set to go, we have to write some script to parse it. Create a new formatted text and images part, switch to HTML mode and enter this script:

<script type=”text/javascript”>

function AfterDonation() {

       if ($(".TSName").length > 0) {

              fname = $(".TSName).children(":first").text();

              alert("Thanks " + fname + "!");

       }

}

$(document).ready(

    function() {

        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(AfterDonation);

    }

);

</script>

This script defines a function (AfterDonation) that will pop a “Thank you” alert after a donation. The second part of the script registers that function to fire after the donation form updates (See Footnote #1 for a technical explanation). The first line of AfterDonation verifies that our custom confirmation screen is loaded by looking for an element with the class we defined, and then grabs the first name field value from the confirmation screen and pops the alert. Cool!
 
Technical NoteThe NetCommunity donation form uses an asp.net UpdatePanel when processing a donation. The sys.webforms… line of code tells asp.net to fire the AfterDonation function whenever the updatepanel completes an update. The AfterDonation function checks to make sure it is actually on a confirmation screen by verifying that our custom confirmation screen markup is present, and then fires off the alert. We need to verify that it is actually a confirmation screen because the update panel could update with a validation message instead of a successful donation, which would cause the AfterDonation function to fire, but in that case we are not actually on a confirmation screen. Finally, to get the Name value out of the confirmation screen, we select the span element containing the merge field, and then get the value of the next child span tag. This is because merge fields render as span tags, so we wind up with another span tag inside the original span tag that we decorated with the class name.
 
 
Disclaimer: This script is a bit "fragile". If we decided at some point to change how merge fields are rendered, then this will stop working. The way merge fields render has remained the same for a long time and, while we don't anticipate changing them, this is not a 100% future-proof solution. As always, test all mission critical site functionality before upgrading.
 
Now that we have the technique down, we can use it for all kind of cool things. Here are two examples.
 

Example 1 – Google eCommerce Integration

About Google Analytics & eCommerceGoogle eCommerce is an advanced set of tools inside Google Analytics that gives deep insight into the behavior of your visitors and some really handy reports and metrics about your monetization efforts. Digging into all the features of Google eCommerce tracking and how to use them is beyond the scope of this footnote, but for those of you who have a handle on the basic functionality in GA, I definitely encourage you to explore the eCommerce features. Here’s a link to get you started: http://www.epikone.com/blog/2008/06/25/google-analytics-e-commerce-tracking-pt-3-why-everyone-should-use-it/
 
I use this script in my site tracking box to send data over to Google eCommerce (See Footnote #2 for information about Google Analytics' eCommerce features) after a user has donated. The new parts are in red, the rest is the default Google Analytics code that you probably have in your site tracking box already:

<script type="text/javascript">

var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));

</script>

<script type="text/javascript">

function GetValue(className) {

       val = $("." + className).children(":first").text();

      

       //if there are any currency symbols, strip them out. GA doesn't like them.

       m = /^"$|"£|"€/g;

       return val.replace(m, "");

}

try {

       var pageTracker = _gat._getTracker("UA-4094862-3");

       pageTracker._trackPageview(BBNCAnalyticsURL);

       if ($(".TSConfirmation").length > 0) {

              //Generate a fake order ID, thanks to http://www.epikone.com

              var d = new Date;

              var unixTime = parseInt(d.getTime / 1000);

              var orderID = pageTracker._visitCode() + '-' + unixTime;

             

              //Only Order ID and Total are required

              //Feel free to track more information if you want

              pageTracker._addTrans(

                  orderID,                       // Order ID

                  "",                            // Affiliation

                  GetValue("TSAmount"),          // Total

                  "",                            // Tax

                  "",                            // Shipping

                  "",                            // City

                  "",                         // State

                  ""                             // Country

               );

               

               pageTracker._addItem(

                  orderID,                        // Order ID

                  "",                             // SKU

                  "",                             // Product Name

                  "",                             // Category

                  GetValue("TSAmount"),           // Price

                  "1"                             // Quantity

               );

               pageTracker._trackTrans();

       }

} catch(err) {}</script>

This is really just the code that Google provides for eCommerce integration (See: http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=55528). All I did was rip some values out of the confirmation screen. I also wrote a bit of code to generate a unique order ID and a function to get a merge field value and remove any currency symbols. NetCommunity already takes care of firing the tracking code after a donation form update, so this is all I had to do. You can easily pull some other data points off the confirmation screen to fill out other values you find useful in your reports. Easy!

 

Example 2 – Twitter Updates

What would a sample be without Twitter integration? Here’s a custom part that I’ve named TweetStream that sends an alert to Twitter whenever someone donates, using the 3rd party TweetSharp library. You can use this part to generate a live feed of donations as they come in. Here’s a screenshot of an integrated Twitter account after a few donations (you can see this live at http://www.twitter.com/DemoOrg):
 
 

And here’s the editor for the part:
 

Once you’ve download and installed the part (don’t forget to put TweetStream.js in your Client"Scripts folder!), create a new TweetStream part, fill out the settings, and place it on a page with a donation form. The part is invisible, but will detect a completed donation and update the Twitter account you specified in the editor. The code is heavily commented and should be easy to understand and expand. This is a little different than previous examples because it actually makes an Ajax request (via the asp.net ICallBackHandler, though you could use any Ajax technique you like) back to the server after the donation, and the Twitter update is performed server side. From the server you could update a database, call out to a 3rd party system (as I did here) or perform analysis on transactions as they come in. Now that’s really powerful!

That’s it for today! I hope you’ll find some awesome new uses for this technique!