Send Snazzy Email Confirmations using Form Wizard Pro

Posted by Steve Railsback Sunday, January 29, 2012 5:00:00 PM Categories: MojoPortal

Since the mojoPortal Team released support for Form Submission Handlers I've been in programming heaven. Form submission handlers have changed the way my clients do business on their sites. I've written handlers to send confirmation emails, receive applications and push data to other databases, and even schedule events in mojoPortals Event Calendar Pro. I really see the possibilities of form submission handlers as endless and one of the best attributes of mojoPortal.

This article will demonstrate how I use form submission handlers along with mojoPortal's Newsletter tool to send HTML formatted email confirmations. If you have not developed a submission handler before I encourage you to read Implementing a Custom Form Submission Handler before getting started. This article will give you a foundation before jumping into this article. Once you are ready, download the MySubmissionHandler solution. It contains all the information and resources you need for this article. Here's a preview of the end product. Let's begin!

Step 1: Email Newsletter

Use mojoPortal's Newsletter Administration tool create an email template. If you find that you are at loss for ideas, head over to MailChimp or Campaign Monitor for ideas. If you do not want to design a template at this time you will find an example email template in the solution. There are two images references in the template. You will need to upload these to your server and change the references (or just leave them the same and reference mine). After creating the template add a [::FormData::] placeholder somewhere in the email body. We will later replace this placeholder with the actual form data. Lastly note the letter GUID, this appears the url. Save it to a text file. We will use it later as well.


Step 2: Build the Form

Using mojoPortal's Form Wizard Pro module, create a simple form. On the form settings check Enable Question Alias and and Allowed Uploads to 1 or more files. This is a simple graphic design request form. We don't need much, just the client's contact information and graphic design need. Below are the form questions, question types, and question alias. If you want to skip developing the form, just import the form-definitions.txt file found in the solution. Make sure to change the file's extension to .config before importing the definitions. 

Question Type Question Alias Required
First Name Text FirstName Yes
Last Name Text LastName Yes
Email Text Email Yes
Phone Number Text Phone No
Due Date DateTime DueOn Yes
Graphic Design Detail Paragraph Detail Yes
Prefer HTML Email Confirmation?
isHtml Yes


Step 3: Submission Handler

Okay, let's write the submission handler. Create a new Class Library project in Visual Studio and copy the example form submission handler from mojoPortal. Add the below references to the project; set the mojoPortal and sts references to copy local in the reference properties.

using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using mojoPortal.Business;
using mojoPortal.Business.WebHelpers;
using sts.FormWizard.Web.UI;
using sts.Business;
using mojoPortal.Net;
using mojoPortal.Web;
using sts.FormWizard;
using System.Text.RegularExpressions;
using System.Web;

Replace the FormSubmittedEventHandler method with the code below: 

        public override void FormSubmittedEventHandler(object sender, FormSubmissionEventArgs e)
            if (e == null) return;
            if (e.ResponseSet == null) return;
            log.Info("MySubmissionHandlerProvider called");

            // Generic dictionaries that will be used to store form data
            Dictionary<string, string> data = new Dictionary<string, string>();
            List<WebFormQuestion> questions = WebFormQuestion.GetByForm(e.ResponseSet.FormGuid);
            List<WebFormResponse> responses = WebFormResponse.GetByResponseSet(e.ResponseSet.Guid);

            // build the data collection
            foreach (WebFormQuestion question in questions)
                data.Add(question.QuestionAlias, GetResponse(e.ResponseSet.Guid, question.Guid, responses));

            // Get any file attachments
            string[] fileAttachmentPaths = new string[0];
            string[] fileAttachmentNames = new string[0];
            data.Add("FileAttachments", "0");
            if( e.ResponseSet.UploadCount > 0) {
                List<FileAttachment> attachments = FileAttachment.GetListByItem(e.ResponseSet.Guid);
                fileAttachmentPaths = new string[attachments.Count];
                fileAttachmentNames = new string[attachments.Count];
                data["FileAttachments"] = attachments.Count.ToString();

                int i = 0;
                foreach (FileAttachment a in attachments)
                    string downLoadPath = e.AttachmentBaseBath + a.ServerFileName;
                    fileAttachmentPaths[i] = HttpContext.Current.Request.MapPath(downLoadPath);
                    fileAttachmentNames[i] = a.FileName;
                    i += 1;


            // Send the confirmation email
            SendConfirmationEmail(data, fileAttachmentPaths, fileAttachmentNames);


In the above method we create three dictionaries. The questions and responses dictionaries are question and response collections from our form. The data dictionary merges the questions and responses collections using the question.QuestionAlias the key and response for the value.

After building the data dictionary we check for any file attachments and build two additional string arrays for the file paths and file names. We also create a new key value pair in the data dictionary, FileAttachments. This serves as an indicator in the email reader that there are (or not) attachments.

Lastly, this method sends the confirmation email.

        private void SendConfirmationEmail(Dictionary<string, string> data, string[] fileAttachmentPaths, string[] fileAttachmentNames)
            // Get the eletter - get the guid from the LetterEdit.aspx, querstring key is letter
            Letter letter = new Letter(new Guid("b36c7e6-269d-4494-8147-f1c83e29e7db"));
            // replace the [::FormData::]] placeholder with the submitted data;
            letter.HtmlBody = letter.HtmlBody.Replace("[::FormData::]", FormData(data, true));
            letter.TextBody = letter.TextBody.Replace("[::FormData::]", FormData(data, false));

            // Html email?
            bool isHtml = data["isHtml"] == "false" ? false : true;
            string emailBody = isHtml ? letter.HtmlBody : letter.TextBody;

            string emailFrom = ""; // change to your email
            string emailTo = data["Email"]; // change to your email
            string subject = "Project Request";

            // send the email
                   subject, emailBody,

The SendConfirmationEmail assembles all parts of the email and sends it -- I know, a major paradigm shift. First we get the email template using the letter GUID that we previous saved when creating the letter. Then we replace the instance of the [::FormData::] placeholder in the email template using the FormData method.

        private string FormData(Dictionary<string, string> data, bool isHtml)
            string formData = "<table>";
            formData += "<tr><td>Name</td>\r\n<td>[::FirstName::] [::LastName::]</td></tr>\r\n";
            formData += "<tr><td>Email</td>\r\n<td>[::Email::]</td></tr>\r\n";
            formData += "<tr><td>Phone</td>\r\n<td>[::Phone::]</td></tr>\r\n";
            formData += "<tr><td>Due Date</td>\r\n<td>[::DueOn::]</td></tr>\r\n";
            formData += "<tr><td>Detail</td>\r\n<td>[::Detail::]</td></tr>\r\n";
            formData += "<tr><td>File Attachments</td>\r\n<td>[::FileAttachments::]</td></tr>\r\n";
            formData += "</table>";

            // find and place the placeholder, [::key::], with the value
            foreach (KeyValuePair<string, string> pair in data)
                string field = string.Format("[::{0}::]", pair.Key);
                string value = pair.Value;
                formData = formData.Replace(field, value);

            // remove the html tags if this is plain text
            if (!isHtml)
                return Regex.Replace(formData, "<.*?>", string.Empty);

            return formData;


The FormData method builds an HTML string that contains additional placeholders. These placeholders match the keys in our data dictionary; which really are the question alias that we created when building the form. Using a simple loop we find and replace the placeholder, [::key::], with the value. I should note that we also strip out the HTML for the plain text email if the isHtml boolean value is false. Lastly the SendConfirmationEmail method checks the HTML email preference, sets the sender and recipient email address, subject, and send the email. That's it! All that we have to do now is create the submission handler config file. Add a new application config file to the project.

<?xml version="1.0" encoding="utf-8" ?>
    <add name="MySubmissionHandler" type="MySubmissionHandler.MySubmissionHandlerProvider, MySubmissionHandler" description="Custom form submission handler" />

Step 4: Copy the files to mojoPortal Installation

Okay build the project. Copy the compiled dll, in this case MySubmissionHandler.dll, to your mojoPortal installation's bin folder. Copy the config file to the your installation's Formwizard/SubmissionHandlers folder.  We're almost done. Now edit the form settings. Select the handler you just uploaded.


There you have it. With some simple work you too can send 'pretty' emails confirmations. Some of you may ask, "Why even use the Newsletter Tool? Why not just code the email in the class library project?" Yes, you could do this; but, I've always found hard-coded emails difficult to edit and manage for the long term. With the letter GUID we can get the email body with out having hard-code it. In addition, the mojoPortal's Newsletter Tool  makes is easy to design, edit, test, and even swap out your confirmation emails -- so why not use it!

Comments are closed on this post.