Thursday, September 23, 2010

dotCMS form handler as a jQuery dialog with encrypted email

dotCMS 1.7 has fairly straight-forward form handling that makes it easy to write (in HTML) a form that will submit to dotCMS (action="/dotCMS/submitWebForm") and email the form contents to an email address you nominate. The purpose of this posting is to show the following.

  1. How to create a simple dotCMS form using this mechanism that emails the results to someone.
  2. How to encrypt the email addresses so that they do not appear in plain text within your HTML
  3. How to use some simple jQuery to make the form a "floating dialog" that can be triggered by clicking on a button.

Since I don't have a dotCMS server of my own, here are screen shots of the results.

This is what the form looks like.

Click the button and the form is displayed. It isn't a pop-up (those are evil); it's a hidden element that gets shown (less evil) when you click "Give Feedback". After the user has filled out the form and clicks "Submit", they are redirected back to the same page.

And this is the email you get from dotCMS containing details of the submitted form.

Next I will show the code in chunks, with a bit of discussion for each chunk.

The first things you need are imports for the jQuery theme, jQuery API itself and then jQuery UI.

<link href='http://robertmarkbram.appspot.com/content/global/css/jQueryUi/customThemeGreen/jquery-ui-1.8.4.custom.css' rel='stylesheet' type='text/css'/>
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAoDEIY_vXge_LQOEVgHyheBSvIISGg2D4cAMKlpvPZkPgQSL0sRRGyBerqkXeyllTDvkGdlqzeYPWKA" ></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"></script>

What's with the jsapi?key and the imports from ajax.googleapis.com? Google (being the thoroughly non-evil company that they are) offer several well known Javascript APIs for public use on websites other than their own i.e. they host them so you don't have to. They ask that you register for (free) and use an API key specific to your site so they know ... whatever it is they want to know. Read more about this on the Google Libraries API - Developer's Guide. This is perfect for things like Blogger i.e. services for which you cannot upload your own scripts or other arbitrary files.

Here is the HTML for the visible portion of the page.

<div style="border:1px solid;padding:10px;margin:10px;width:200px;">
   <p>My very interesting page.. </p>
   <button id="opener">Give Feedback</button>
</div>

This is the HTML for the dialog that will appear when the user clicks the button.

<form method="post" id="feedbackForm" name="feedbackForm" action="/dotCMS/submitWebForm" style="display:none;">
   <input type="hidden" name="from" id="from" value="noreply@example.com">
   #encrypt('robertmarkbram@gmail.com') #set ($to = $encryptedStr)
   <input type="hidden" name="to" id="to" value="$to"/>
   <input type="hidden" name="subject" id="subject" value="Feedback on your cool site"/>
   <input type="hidden" name="returnUrl" id="returnUrl" value=""/>
   <input type="hidden" name="errorURL" id="errorURL" value="/error/page" />
   <input type="hidden" name="html" id="html" value="1" />
   <input type="hidden" name="order" id="order" value="referrer,reason,feedback" />
   <input type="hidden" name="formType" id="formType" value="feedbackForm" />
   <fieldset>
      <h1>Feedback Form</h1>
      <p>Please use this form to provide feeback.</p>
      <input type="hidden" id="referrer" name="Referrer URL" value="" />
      <p>Reason for feeback</p>
      <select id="reason" name="Reason for Feedback">
         <option value="Your site is awesome!">Your site is awesome!</option>
         <option value="Are you my father?">Are you my father?</option>
      </select>
      <p>Comments</p>
      <textarea id="feedback" name="Feedback"></textarea>
      <p><input type="submit" value="Submit" /></p>
   </fieldset>
</form>

Notes about this code.

This form submits to /dotCMS/submitWebForm - which is the dotCMS code that will process the data and email it out to whoever is specified in the hidden to field.

It is very easy to encypt the email address that will appear in the hidden to field. Do it with the code below.

#encrypt('robertmarkbram@gmail.com') #set ($to = $encryptedStr)
<input type="hidden" name="to" id="to" value="$to"/>

This is how the HTML looks on the browser:

<input type="hidden" value="aJ8pVupCRaDYMRzM8qXtCS4IGXAInnAtgKPynQZNDe4=" id="to" name="to">

dotCMS's /dotCMS/submitWebForm automagically decrypts it to get the actual email address(es).

The hidden returnUrl field specifies what URL the browser will go to after the form is submitted (shown below). The jQuery discussed further down sets this value.

<input type="hidden" name="returnUrl" id="returnUrl" value=""/>

This jQuery Javascript sets up the dialog and sets up a button to open it. Plus it initialises data for the form - specifically what URL this form is hosted on.

<script language="javascript">
  $(document).ready(function() {
     // Creates a dialog from element with ID "feedbackForm"
    var $dialog = $("#feedbackForm").dialog({
      autoOpen: false,
      title: 'Feedback Form',
      height: "auto",
      width: "auto"
    });
      // If you click the button (ID "opener") it will open the form dialog.
    $('#opener').click(function() {
      $dialog.dialog('open');
      // prevent the default action, e.g., following a link
      return false;
    });
    // Redirect back to the same page after the form is submitted.
      $("#returnUrl").val(window.location.href);
    // To inform email recipient of the URL the form was from.
      $("#referrer").val(window.location.href);
  });
</script>

Note that the hidden returnUrl field is given the value of window.location.href - so after clicking the button to submit the form, the browser will go back to the same page (the dialog form will not be visible again though; just like what happens if you refresh the page).

For a more detailed code example showing what options you can specify in the form, see the dotCMS Wiki page on Sample Form Code. See the dotCMS documentation page, Form Handling for an explanation of the different options. For example, you can even provide an alternate email template.

Current Form Handling. In dotCMS 1.9, there is a new way to build forms that means you don't need knowledge of HTML and makes the forms more re-usable as dotCMS Form entities. See the new Form Handling documentation for instructions on this.

I am not sure if the approach outlined in this post still works in 1.9. I am also not sure if the new approach hides emails. Or how easy it is to apply the jQuery touch.

My dotCMS notes.