Created
December 3, 2015 19:49
-
-
Save naepalm/2e2d0fb8ac302fa94a65 to your computer and use it in GitHub Desktop.
Contact Form for Umbraco with a Departments dropdown list. Assumes the dropdown list is NestedContent on the selected Email Template.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web.Mvc; | |
using Umbraco.Core.Models; | |
using Umbraco.Web; | |
namespace Forms.Web.Models | |
{ | |
public class ContactForm | |
{ | |
public int EmailTemplateId { get; set; } | |
public int ContentId { get; set; } | |
public string DepartmentEmail { get; set; } | |
public IEnumerable<IPublishedContent> Departments { get; set; } | |
public IEnumerable<SelectListItem> DepartmentsSelectList | |
{ | |
get | |
{ | |
return Departments != null ? Departments.Where(d => d.WillWork("email") && d.WillWork("headline")).Select(d => new SelectListItem() | |
{ | |
Value = d.GetPropertyValue<string>("email"), | |
Text = d.GetPropertyValue<string>("headline") | |
}) : null; | |
} | |
} | |
public string Name { get; set; } | |
public string Email { get; set; } | |
public string Phone { get; set; } | |
public string Message { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Forms.Web.Controllers | |
@using Forms.Web | |
@using Forms.Web.Models | |
@inherits UmbracoViewPage<ContactForm> | |
@{ | |
var msgs = (ValidationMessages)ViewBag.ValidationMessages; | |
@(msgs != null ? RenderValidationMessages(msgs) : RenderForm()) | |
} | |
@helper RenderValidationMessages(ValidationMessages msgs) | |
{ | |
if (!msgs.IsSuccessConfirmation) | |
{ | |
// these should be error messages | |
if (msgs.Messages.Any(x => !string.IsNullOrEmpty(x))) | |
{ | |
// Render the error summary | |
<ul class="errors application-errors"> | |
@foreach (var m in msgs.Messages) | |
{ | |
<li>@m</li> | |
} | |
</ul> | |
} | |
// Render the contact form again | |
@RenderForm() | |
} | |
else | |
{ | |
var template = Umbraco.TypedContent(Model.EmailTemplateId); | |
if (template.WillWork("confirmation")) | |
{ | |
@template.GetPropertyValue("confirmation") | |
} | |
else | |
{ | |
<p>Your message has been sent.</p> | |
} | |
} | |
} | |
@helper RenderForm() | |
{ | |
using (Html.BeginUmbracoForm<ContactFormController>("ContactFormSubmit", FormMethod.Post, new { @class = "contact-form", @id = "contactForm" })) | |
{ | |
if (Model.Departments != null) { | |
<div class="form-group half-size"> | |
@Html.LabelFor(m => m.DepartmentEmail, "Area of Interest") | |
@Html.DropDownListFor(m => m.DepartmentEmail, Model.DepartmentsSelectList, "Select your interest") | |
</div> | |
} | |
<div class="form-group half-size"> | |
@Html.LabelFor(m => m.Name, "Name") | |
@Html.TextBoxFor(m => m.Name) | |
</div> | |
<div class="form-group half-size"> | |
@Html.LabelFor(m => m.Email, "Email") | |
@Html.TextBoxFor(m => m.Email) | |
</div> | |
<div class="form-group half-size"> | |
@Html.LabelFor(m => m.Phone, "Phone") | |
@Html.TextBoxFor(m => m.Phone) | |
</div> | |
<div class="form-group"> | |
@Html.LabelFor(m => m.Message, "Message") | |
@Html.TextAreaFor(m => m.Message) | |
</div> | |
<div class="form-group"> | |
@Html.HiddenFor(m => m.ContentId) | |
@Html.HiddenFor(m => m.EmailTemplateId) | |
</div> | |
<button type="submit" class="button button--solid-red">Send us a Message</button> | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web.Mvc; | |
using ClientDependency.Core; | |
using Forms.Web.Helpers; | |
using Forms.Web.Models; | |
using Umbraco.Web; | |
using Umbraco.Web.Mvc; | |
namespace Forms.Web.Controllers | |
{ | |
public class ContactFormController : SurfaceController | |
{ | |
[ChildActionOnly] | |
public ActionResult RenderForm(ContactForm model) | |
{ | |
return PartialView("CourseApplicationForm", model); | |
} | |
[HttpPost] | |
[ActionName("ContactFormSubmit")] | |
public ActionResult ContactFormSubmit(ContactForm model) | |
{ | |
var messages = new ValidationMessages(); | |
messages.Messages = new List<string>(); | |
if (ModelState.IsValid) | |
{ | |
// Get the current page from the model | |
var current = Umbraco.TypedContent(model.ContentId); | |
// Set the e-mail template, selected on the form page | |
var emailTemplate = Umbraco.TypedContent(model.EmailTemplateId); | |
// Exclude non-string fields to enter manually | |
var excludedFields = new[] | |
{ | |
"ContentId", | |
"EmailTemplateId", | |
"Departments", | |
"DepartmentEmail", | |
"DepartmentsSelectList" | |
}; | |
// These fields may be empty on form submission and therefore not replaced | |
var optionalFields = new[] | |
{ | |
"Phone", | |
"Message" | |
}; | |
var fields = model.ToDictionary().Where(x => !excludedFields.Contains(x.Key)); | |
// Add the string type fields to the dictionary | |
var formFields = fields.ToDictionary(field => field.Key, field => field.Value.ToString()); | |
// Add the remaining, empty optional fields as empty strings | |
foreach (var key in optionalFields.Where(x => !formFields.ContainsKey(x))) | |
{ | |
formFields.Add(key, string.Empty); | |
} | |
// Replace the "%%{0}%%" fields in the e-mail template with their actual values | |
var bodyContent = EmailHelpers.ReplacePlaceholders(emailTemplate.GetPropertyValue<string>("emailTemplate"), formFields, "%%{0}%%"); | |
var mailVals = new EmailHelpers.MailVariables | |
{ | |
ToName = model.DepartmentsSelectList.FirstOrDefault(x => x.Value == model.DepartmentEmail) != null ? model.DepartmentsSelectList.FirstOrDefault(x => x.Value == model.DepartmentEmail).Text : "NuWay Website", | |
From = emailTemplate.WillWork("fromAddress") ? emailTemplate.GetPropertyValue<string>("fromAddress") : "no-reply@nuway.com", | |
FromName = emailTemplate.WillWork("fromName") ? emailTemplate.GetPropertyValue<string>("fromName") : "NuWay", | |
Subject = emailTemplate.WillWork("subject") ? emailTemplate.GetPropertyValue<string>("subject") : "Contact Form Email Submission", | |
BodyContent = bodyContent, | |
IsHtml = true | |
}; | |
//send the mail NuWay | |
mailVals.To = model.DepartmentEmail; | |
var mailSent = EmailHelpers.TrySendMail(mailVals); | |
if (mailSent) | |
{ | |
// set the confirmation flags | |
messages.IsSuccessConfirmation = true; | |
//add the validation messages to the ViewData | |
ViewData["ValidationMessages"] = messages; | |
//Add current form model to ViewBag | |
ViewData["Model"] = model; | |
return CurrentUmbracoPage(); | |
} | |
messages.IsSuccessConfirmation = false; | |
// pass the error back to the view | |
messages.Messages.Add("This form could not be submitted properly. Please contact us by phone and we'll be happy to help you."); | |
//add the validation messages to the ViewData | |
ViewData["ValidationMessages"] = messages; | |
//Add current form model to ViewBag | |
ViewData["Model"] = model; | |
return CurrentUmbracoPage(); | |
} | |
messages.IsSuccessConfirmation = false; | |
var modelErrors = ModelState; | |
//Add model errors to Validation Messages | |
foreach (var fieldError in modelErrors) | |
{ | |
foreach (var error in fieldError.Value.Errors) | |
{ | |
messages.Messages.Add(error.ErrorMessage); | |
} | |
} | |
//add the validation messages to the ViewData | |
ViewData["ValidationMessages"] = messages; | |
//Add current form model to ViewBag | |
ViewData["Model"] = model; | |
return CurrentUmbracoPage(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using Forms.Web | |
@using Forms.Web.Models | |
@inherits UmbracoTemplatePage | |
@{ | |
Layout = "TwoColumn.cshtml"; | |
var msgs = (ValidationMessages)ViewBag.ValidationMessages; | |
var formModel = (ContactForm)ViewBag.Model; | |
} | |
@Html.Partial("ContactForm", new ContactForm { ContentId = Model.Content.Id, EmailTemplateId = Model.Content.GetPropertyValue<int>("emailTemplate"), Departments = msgs == null ? Model.Content.GetPropertyValue<IEnumerable<IPublishedContent>>("departments") : formModel.Departments }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Web; | |
using HtmlAgilityPack; | |
using Umbraco.Core; | |
using Umbraco.Core.Logging; | |
namespace Forms.Web.Helpers | |
{ | |
/// <summary> | |
/// EmailMessage Helpers | |
/// </summary> | |
public static class EmailHelpers | |
{ | |
/// <summary> | |
/// Data structure for storing mail related items | |
/// </summary> | |
public class MailVariables | |
{ | |
public MailVariables() { this.IsReady = false; } | |
public string BodyContent { get; set; } | |
public string Subject { get; set; } | |
public string To { get; set; } | |
public string ToName { get; set; } | |
public string From { get; set; } | |
public string FromName { get; set; } | |
public string ReplyTo { get; set; } | |
public bool EnableSsl { get; set; } | |
public bool IsReady { get; set; } | |
public bool IsHtml { get; set; } | |
} | |
/// <summary> | |
/// Gets mail variables from EmailMessage document type | |
/// </summary> | |
/// <param name="id"> | |
/// The node id of the EmailMessage | |
/// </param> | |
/// <returns> | |
/// The <see cref="MailVariables"/>. | |
/// </returns> | |
public static MailVariables GetMailVariables(int id) | |
{ | |
var umbContentService = ApplicationContext.Current.Services.ContentService; | |
var emf = umbContentService.GetById(id); | |
MailVariables mailvars = new MailVariables(); | |
try | |
{ | |
mailvars.From = emf.GetValue<string>("from"); | |
mailvars.FromName = emf.GetValue<string>("fromName"); | |
mailvars.To = emf.GetValue<string>("to"); | |
mailvars.ToName = emf.GetValue<string>("toName"); | |
mailvars.Subject = emf.GetValue<string>("subject"); | |
mailvars.BodyContent = emf.GetValue<string>("content"); | |
mailvars.IsReady = true; | |
} | |
catch (Exception ex) | |
{ | |
var msg = string.Format("Error creating or MailVariables. Exception: {0}", ex.Message); | |
LogHelper.Error(typeof(EmailHelpers), msg, new Exception(msg)); | |
} | |
return mailvars; | |
} | |
/// <summary> | |
/// Attempts to send an email with mail variable package passed-in | |
/// </summary> | |
/// <param name="package"> | |
/// The The <see cref="MailVariables"/> package. | |
/// </param> | |
/// <returns> | |
/// <see cref="bool"/> indicating successful send. | |
/// </returns> | |
public static bool TrySendMail(MailVariables package) | |
{ | |
try | |
{ | |
var msg = new System.Net.Mail.MailMessage(); | |
msg.From = new System.Net.Mail.MailAddress(package.From, HttpUtility.HtmlEncode(package.FromName)); | |
msg.Subject = package.Subject; | |
msg.Body = package.BodyContent; | |
msg.IsBodyHtml = package.IsHtml; | |
msg.To.Add(new System.Net.Mail.MailAddress(package.To, package.ToName)); | |
var smtp = new System.Net.Mail.SmtpClient { EnableSsl = package.EnableSsl }; | |
smtp.Send(msg); | |
return true; | |
} | |
catch (Exception ex) | |
{ | |
var msg = string.Concat("TrySendMail: ", string.Format("Error creating or sending email, exception: {0}", ex.Message)); | |
LogHelper.Error(typeof(EmailHelpers), msg, new Exception(msg)); | |
} | |
return false; | |
} | |
/// <summary> | |
/// Using a dictionary of replacement keys with their corresponding values, | |
/// replace the placeholders in the Template content. | |
/// </summary> | |
/// <param name="templateContent">The email template content to process.</param> | |
/// <param name="placeholdersData">The placeholder data Dictionary</param> | |
/// <param name="templatePattern">The format pattern to indicate placeholders in the template content</param> | |
/// <param name="escapeHtml">Declare whether or not to escape the HTML</param> | |
public static string ReplacePlaceholders(string templateContent, Dictionary<string, string> placeholdersData, string templatePattern = "[{0}]", bool escapeHtml = false) | |
{ | |
StringBuilder templ = new StringBuilder(templateContent); | |
foreach (var kv in placeholdersData) | |
{ | |
var placeholder = string.Format(templatePattern, kv.Key); | |
var val = kv.Value; | |
if (escapeHtml) | |
{ | |
val = HttpContext.Current.Server.HtmlEncode(val); | |
} | |
templ.Replace(placeholder, val); | |
} | |
return templ.ToString(); | |
} | |
/// <summary> | |
/// Add an absolute path to all the img tags in the html of an e-mail. | |
/// </summary> | |
/// <param name="html"></param> | |
/// <returns></returns> | |
public static string AddImgAbsolutePath(string html) | |
{ | |
HtmlDocument doc = new HtmlDocument(); | |
doc.LoadHtml(html); | |
var uri = new Uri(HttpContext.Current.Request.Url.AbsoluteUri); | |
var domainUrl = string.Format("{0}://{1}", uri.Scheme, uri.Authority); | |
if (doc.DocumentNode.SelectNodes("//img[@src]") != null) | |
{ | |
foreach (HtmlNode img in doc.DocumentNode.SelectNodes("//img[@src]")) | |
{ | |
HtmlAttribute att = img.Attributes["src"]; | |
if (att.Value.StartsWith("/")) | |
{ | |
att.Value = domainUrl + att.Value; | |
} | |
} | |
} | |
return doc.DocumentNode.InnerHtml; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Forms.Web.Models | |
{ | |
using System.Collections.Generic; | |
public class ValidationMessages | |
{ | |
public string FormName { get; set; } | |
public bool IsSuccessConfirmation { get; set; } | |
public IList<string> Messages { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment