Two Step Registration Form using AJAX

For many nonprofit organizations increasing their email list recruitment is the principle goal for their online marketing initiatives. There are numerous tactics and best practices that can help grow an organic opt-in list. One popular best practice is to offer a simple two-step registration form that persists throughout the organization's web site.

Why use a two step registration?

As an organization recruiting new supporters you are building a relationship, and just like with any personal relationship the interactions and amount of information sharing often starts with the bare minimum and then grows over time. For some organizations the bare minimum information extends beyond the email address, which is fine, but keep in mind that for every additional click and for every additional piece of data you are requesting they provide, you are losing some subscribers. The debate of quality vs. quantity will come in to play for many groups. However, for those who are seeking to minimize the hurdles for list recruitment, cultivate additional information over time and provide a simple and easy experience for new subscribers, the two step registration form may be a tactic to consider.

Here's how it works (from the perspective of the subscriber)

  • Embedded in the web site navigation, page header, footer or other persistent area is a very simple "Join our email list" form with a single form field to collect the email address. This form includes a "submit" button and nothing more. Visit http://www.care.org/ to see a live example. Note the CARE example does not use AJAX.
  • Web site visitor "Isaac B. Nimble" enters his email address ibnimble@gmail.com and clicks submit.
  • On the resulting page, Isaac is presented with another form that includes his email address as a non-editable value. This form asks Isaac for additional information (e.g. First and Last name, address, topical interests, etc.). When Isaac completes and submits this second form he is then presented with a final "Thank You" page that includes additional opportunities for getting involved.
  • Isaac then receives an automated welcome email and is now part of the organization's subscription list.

Here's how it works (behind the scenes)

  • When Isaac submits his email address in step 1 he is automatically registered with the organization; however, to attempt to capture additional information on Isaac, an additional step is added. This initial registration is accomplished by using the createOrUpdate method of the Convio Constituent Management API.
  • If Isaac is motivated to provide more information on step 2, the "update" portion of the API fulfills it's mission by adding these additional values to his record where previously only his email address exists.
  • If Isaac abandon's step 2 the organization has at least collected his valuable email address and will seek to update his record through other methods in future engagements.
Test it out!

 

For the purpose of demonstration this form will not actually capture the information, but you can view the two step process by entering and submitting a value in the email field.

Here's how to make it work for your web site

The following code snippet uses Javascript and AJAX to present the two step form. For the purpose of this example we tried to write code that would not be dependent on any existing Javascript libraries, but we did use Prototype (download Prototype.js here) to make our Ajax calls in the regSubmit() function. If you choose to keep our regSubmit(), the Prototype library will need to be loaded. If you decide to not use Prototype, regSubmit() will need to be modified.

Notes:

  1. Prototype is already installed on any Convio PageBuilder powered web site
  2. For Convio CMS, you will need to upload the Prototype.js file to an appropriate folder and modify the reference path in the code accordingly.
  3. Prototype may conflict with other Javascript libraries/frameworks. Form.serialize(form_id) is a Prototype function that takes a form ID as a parameter and returns a string containing all the form parameters.

Example:

<form id="myform">
  <input type="text" name="fname" value="John" />
  <input type="text" name="lname" value="Smith" />
</form>
Form.serialize('myform');  ==>  "fname=John&lname=Smith"

 

Step 1 - Setting required variables

  1. Copy the code below and paste into Notepad or your preferred HTML editor in code view.
  2. You must modify the url at the top per your specific site.  This is the url of our server where the Ajax calls will be made. Located within the loadRegVars() function, near the top of the Javascript block.
  3. If the form id's conflict with your existing web site code, you will need to modify the id tags in both the script and the HTML. However, in most cases there will not be any conflict.
<script type="text/javascript">
  // Variables need to be set in this function
  function loadRegVars() {
    // URL where the server request will be sent to
    url = 'https://secure2.convio.net/organization/site/CRConsAPI';

    // Registration html form
    reg_form = getEl('reg-form');

    // Box where error messages are displayed
    msg_box = getEl('reg-msg');

    // Rest of registration form (other than email)
    reg_long = getEl('reg-long');

    // Email form field
    email_field = getEl('email');

    // Convio's internal ID for each user
    cons_id = getEl('cons_id');
  }

  var reg_form, msg_box, reg_long, email_field, method_field, cons_id, json, url;


  /* Short for GET ELEMENT
   * If arg is a string, returns the element with id == arg
   * If arg is an element, returns arg */
  function getEl(arg) {
    if (typeof arg == 'string') {
      return document.getElementById(arg);
    } else {
      return arg;
    }
  }


  // Sets the json variable, used in parsing the callback from the server
  function setJSON(str) {
    str = 'json = ' + str;
    eval(str);  // only real way in converting string --> json (or js literal)
  }


  /* Sets the content of a message box, used for error messages.
   * By default, the message box has id == 'reg-msg' */
  function setMsg(str) {
    msg_box.innerHTML = str;
  }

  function clearMsg() {
    msg_box.innerHTML = '';
  }


  // Makes an Ajax call to the server
  function regSubmit() {
    // Validation for email field
    if (!email_field.value && !cons_id.value) {
      setMsg('Error: Must enter an email address!');
      return;
    }

    new Ajax.Request(url, {
      parameters: Form.serialize(reg_form),
      onSuccess: function(trans) {
        setJSON(trans.responseText);
        var resp = json.createOrUpdateConsResponse || json.createConsResponse;
        clearMsg();

        // If creating (vs updating)
        if (!cons_id.value) {
          loadUpdateForm(resp);
        }
      },
      onFailure: function(trans) {
        setJSON(trans.responseText);
        setMsg(json.errorResponse.message);
      }
    });
  }


  // Changes the state of the form from creating to updating
  function loadUpdateForm(resp) {
    // cons_id is Convio's id for the new user, this sets it in the form
    cons_id.value = resp.cons_id;
  
    // Makes the email field read-only
    email_field.disabled = 'true';
    email_field.className = 'read-only';
  
    // Show long form and change method from 'create' to 'update'
    reg_long.style.display = 'block';
  }


  /* Cross-browser event handling object
   * If using a Javascript library with event handling, the cvEvent
   * object and the call below it can be replaced. The Prototype version
   * of the window.onload call is commented out below. */
  var cvEvent = {
    add: function(obj,type,fn) {
      if (obj.attachEvent) {
        obj['e'+type+fn] = fn;
        obj[type+fn] = function() { obj['e'+type+fn](window.event); }
        obj.attachEvent('on'+type,obj[type+fn]);
      } else
      obj.addEventListener(type,fn,false);
    }
  }

	// Sets variables after the html is loaded
  cvEvent.add(window, 'load', loadRegVars);  

  // Prototype version
  // Event.observe(window, 'load', loadRegVars);

</script>

 

Step 2 - Customize the HTML

For the purpose of this example we have provided very basic HTML that uses CSS to control display properties with only basic form fields. Your organization may desire to modify the HTML to conform to your site design, or modify the form fields to collect additional information during the registration. Additionally, two form variables must be modified below to match your unique Convio site instance.

  1. API_KEY: This is your unique API key. Located in a hidden input field near the top of the registration form html.
  2. V: This is Convio's internal API version number. Located in a hidden input field near the top of the registration form html.
<form id="reg-form" action="#" method="post" onsubmit="regSubmit();return false;">
  <!-- Set the following 2 input variables -->
  <input type="hidden" name="api_key" value="convio" />
  <input type="hidden" name="v" value="1.0" />

  <input type="hidden" name="response_format" value="json" />
  <input type="hidden" name="method" id="method" value="createOrUpdate" />
  <input type="hidden" name="cons_id" id="cons_id" />
  [[S86]]<!-- Authentification key -->

  <p id="reg-msg"> </p>

  <!-- The email field is the only visible field when the page first loads -->
  <p>
    <label for="email.primary_address">Email:</label> 
    <input type="text" name="email.primary_address" id="email" />
  </p>

  <!-- The full registration form is shown after the email is submitted -->
  <fieldset id="reg-long" style="display:none;">
    <p>
      <label for="name.first">First Name:</label> 
      <input type="text" name="name.first" />

    </p>
    <p>
      <label for="name.last">Last Name:</label> 
      <input type="text" name="name.last" />
    </p>
    <p>

      <label for="primary_address.street1">Address:</label> 
      <input type="text" name="primary_address.street1" maxlength="128" />
    </p>
    <p>
      <label for="primary_address.city">City:</label> 
      <input type="text" name="primary_address.city" maxlength="64" />

    </p>
    <p>
      <label for="primary_address.state">State:</label> 
      <select name="primary_address.state">
        <option value="CA">CA</option>

        <option value="TX">TX</option>
      </select>
    </p>
    <p>
      <label for="primary_address.zip">Zip Code:</label> 
      <input type="text" name="primary_address.zip" />

    </p>
  </fieldset>

  <p><input id="reg-submit" type="submit" value="Submit" /></p>
</form>

 

Step 3 - Upload the code

  1. The <script> code in step 1 must be inserted within the <head> tags of your web page. If you intend to use this form throughout your site, it is considered a best practice to add the <script> to your page wrapper or use a server-side include to consistently place the code within the <head> tags of all pages, which can dramatically simplify future modifications.
  2. Add the <form> code to the section of your web site where you want the form to appear. This may be part of your site wrapper or navigation file, depending on your specific design implementation and preferences.

 

Step 4 - Use a CSS file to control the appearance (optional)

Using CSS instead of inline style formatting is a consider another web design best practice. Below is a sample snippet of CSS that references the HTML above. Use "as is" or modify to fit within the design of your site. Either add this CSS file to your existing CSS library or place at the top of the page where this form will appear.


<style type="text/css" media="screen">
  #reg-form {
    margin: 20px;
    width: 250px;
    padding-bottom: 10px;
    border: 1px solid #CCC;
    font: 12px Verdana, Arial, Helvetica, sans-serif;
  }

  #reg-form p {
    margin: 0;
    padding: 5px 0;
  }

  #reg-long {
    margin: 0;
    padding: 0;
    border: none;
  }

  #reg-form label {
    display: block;
    float: left;
    width: 85px;
    text-align: right;
  }

  #reg-form input, #reg-form select {
    display: block;
    margin-left: 90px;
  }

  #reg-form input {
    width: 145px;
  }

  #reg-form input.read-only {
    border: none;
    background: none;
    font-size: 1.1em;
    font-weight: bold;
    color: black;
  }

  #reg-msg {
    color: #F00;
    font-size: 0.9em;
  }

  #reg-form #reg-submit {
    width: 5em;
  }
</style>

 

And that's all there is to creating a simple, yet elegant two step registration form for your web site.