Forms In Episerver
For implementing forms in Episerver, We need to create a form as Episerver section so that we can add forms in any page using ContentArea.
Following are the steps to create a form in Episerver
1) Create an Episerver Web site
Create an Episerver Web site Application and add a name(eg:FormApplication), Click on Ok and select empty website.
2) Create a page model for adding a form block.
Right click on Pages in Models folder, click on Episerver and select page type and give any name(eg:FormPage) and click Add.
3) In FormPage.cs add content properties
In FormPage.cs add content properties, here two properties are added such as Title as a string for adding page title and FormSection ContentArea for adding form section.
namespace FormApplication.Models.Pages { [ContentType(DisplayName = "Form Page", GUID = "a0a0c9f1-1aa7-4b4a-a08e-886a6f0ae99a")] public class FormPage : PageData { [CultureSpecific] [Display( GroupName = SystemTabNames.Content, Order = 1)] public virtual string Title { get; set; } [CultureSpecific] [Display( GroupName = SystemTabNames.Content, Order = 2)] public virtual ContentArea FormSection { get; set; } } }
4) Now add a view for page
Now add a view for page, Right click on Views folder->Add Folder FormPage->In that folder->Add new Item->Select Page Partial View(MVC Razor)->add a name as Index.cshtml->Click Ok
5) Add two properties in Index.cstml of FormPage View
@using FormApplication.Models.Pages @model FormPage <div> @Html.PropertyFor(m => m.Title) <div> @Html.PropertyFor(m => m.FormSection) </div> </div>
6) Now we need to create a section for form
- Right click on Sections->Add->New Item->Add name as TestFormSection->click Add
- In TestFormSection.cs
namespace FormApplication.Models.Sections { [SiteContentType( GroupName = GroupNames.Section, GUID = "27ccbcf0-cda1-46ad-8014-768e480f5743")] [SiteImageUrl] public class TestFormSection : TestFormSectionData { } }
7) Create a TestFormSectionData.cs
Create a TestFormSectionData.cs in Section Folder which consists of Success and Error Message Properties
namespace FormApplication.Models.Sections { public abstract class TestFormSectionData : SiteSectionData { [CultureSpecific] [Display( GroupName = GroupNames.Configuration, Order = 10)] public virtual XhtmlString SuccessMessage { get; set; } [CultureSpecific] [Display( GroupName = GroupNames.Configuration, Order = 20)] public virtual XhtmlString ErrorMessage { get; set; } } }
8) First Create a base class Model For any forms
- Right click on Forms-> Add -> New Item-> BlockType->Add Name as BaseFormModel->Click Add
- And add following lines
namespace FormApplication.Models.Forms { public class BaseFormModel where T : BlockData { private T _currentBlock = null; public FormStatus Status { get; set; } public PageReference CurrentPageLink { get; set; } public ContentReference CurrentBlockLink { get; set; } public string CurrentLanguage { get; set; } public T CurrentBlock { get { if (_currentBlock == null && this.CurrentBlockLink!=null) { _currentBlock = this.CurrentBlockLink.GetContent(); } return _currentBlock; } } } }
9) Now Create a model for Form
Now Create a model for Form in Forms Folder of Models as a TestFormModel.cs which will inherit the BaseFormModel
- In TestFormModel.cs
namespace FormApplication.Models.Forms { public class TestFormModel : BaseFormModel { [DisplayName("First Name")] [Required] public string FirstName { get; set; } [DisplayName("Last Name")] [Required] public string LastName { get; set; } [DisplayName("Email")] [Required] public string Email { get; set; } } }
And also create a Test Model which inherits from IDyanmicData
- In Test.cs
namespace FormApplication.Models.Forms { [EPiServerDataStore(AutomaticallyCreateStore = true, AutomaticallyRemapStore = true)] public class Test : IDynamicData { public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } } }
10) Create an Enum as FormStatus
namespace FormApplication.Enums { public enum FormStatus { [Display(Name = "None")] None = 0, [Display(Name = "Success")] Success = 1,c [Display(Name = "Error")] Error = 2 } }
11) Now we need to create a BaseFormController
Right Click on Controller->Add New Item-> Page Controller->BaseFormController->click Add
namespace FormApplication.Controllers { public class BaseFormController : BlockController where T : BlockData { protected virtual void SaveModelState(ContentReference blockLink) { TempData[StateKey(blockLink)] = ViewData.ModelState; } protected virtual void LoadModelState(ContentReference blockLink) { var key = StateKey(blockLink); var modelState = TempData[key] as ModelStateDictionary; if (modelState != null) { ViewData.ModelState.Merge(modelState); TempData.Remove(key); } } private static string StateKey(ContentReference blockLink) { return "FormBlock_" + blockLink.ID; } } }
12) Create a TestFormController which will inherit BaseFormController
namespace FormApplication.Controllers { public class TestFormController : BaseFormController { private const string STATUS_KEY = "status"; public override ActionResult Index(TestFormSection currentBlock) { var pageRouteHelper = ServiceLocator.Current.GetInstance(); var currentBlockLink = ((IContent)currentBlock).ContentLink; LoadModelState(currentBlockLink); var model = new TestFormModel() { CurrentPageLink = pageRouteHelper.PageLink, CurrentBlockLink = currentBlockLink, CurrentLanguage = ContentLanguage.PreferredCulture.Name, Status = FormStatus.None }; var statusValue = Request.QueryString[STATUS_KEY]; if (!string.IsNullOrEmpty(statusValue)) { model.Status = (FormStatus)Enum.Parse(typeof(FormStatus), statusValue); return PartialView("Status", model); } return PartialView(model); } public virtual ActionResult Submit(TestFormModel formModel) { var returnUrl = UrlResolver.Current.GetUrl(formModel.CurrentPageLink); if (ModelState.IsValid) { //save to store var formData = new Test { FirstName = formModel.FirstName, LastName = formModel.LastName, Email = formModel.Email, Created = DateTime.Now }; SaveToStore(formData); returnUrl = UriSupport.AddQueryString(returnUrl, STATUS_KEY, FormStatus.Success.ToString()); } else { returnUrl = UriSupport.AddQueryString(returnUrl, STATUS_KEY, FormStatus.Error.ToString()); } SaveModelState(formModel.CurrentBlockLink); return Redirect(returnUrl); } } }
13) Create a view for Form Section
Create a New Folder as TestForm and add Index.cshtml
@using EPiServer.Core @using EPiServer.Web.Mvc.Html @using FormApplication.Models.Forms @model TestFormModel <div class="col-md-6"> @using (Html.BeginForm("Submit", null, FormMethod.Post)) { @Html.AntiForgeryToken() HtmlHelper.UnobtrusiveJavaScriptEnabled = false; @Html.HiddenFor(m => m.CurrentBlockLink) @Html.HiddenFor(m => m.CurrentPageLink) @Html.HiddenFor(m => m.CurrentLanguage) <div class="row"> <div class="col-md-6"> <div class="form-group"> <label>FirstName</label> <input class="form-control" type="text" name="FirstName" value="@Model.FirstName" /> </div> <div class="form-group"> <label>LastName</label> <input class="form-control" name="LastName" type="text" value="@Model.LastName" /> </div> <div class="form-group"> <label>Email</label> <input class="form-control" name="Email" type="email" value="@Model.Email" /> </div> <div class="submit-form" data-dismiss="modal"> <button type="submit">Submit</button> </div> </div> </div> } </div>
14) Create a view as a Status.cshtml for showing success and error message
<div class="text-center"> @if (Model.Status == FormStatus.Success) { @Html.PropertyFor(m => Model.CurrentBlock.SuccessMessage) } else { @Html.PropertyFor(m => Model.CurrentBlock.ErrorMessage) } </div>
15) Go to CMS Edit View
Create a FormPage and add a TestFormSection in FormSection ContentArea
16) In TestForm Section go to edit and add success and error messages
17) In view Add the following details in form and click on submit button
18) After clicking submit button it redirects to Status.cshtml which shows success message
19) Add to check whether data is posted go to Admin In CMS Page
Add to check whether data is posted go to Admin In CMS Page and click on Form Data Export,Select the type as Test and click show, Here we will able to see the data which is posted and also we can export the data which will be saved as Excel file with .xls
20) Apart from all this we can also use email configuration in Episerver Forms
Following can be added in web.config for email settings
<system.net> <mailSettings> <smtp from="[email protected]"> <network host="smtp.gmail.com" port="587" userName="[email protected]" password="MamtaA@123" enableSsl="true" /> </smtp> </mailSettings> </system.net>
And add the following method in controller
protected void SendEmail(object formModel) where TSection : SiteFormSectionData { SiteFormSectionData formSection = ((BaseFormModel)formModel).CurrentBlock; //send admin email PageReference adminEmailPageReference = formSection.AdminEmailPage; if (adminEmailPageReference != null) { var adminEmailPage = adminEmailPageReference.GetContent(); string subject = adminEmailPage.EmailSubject; string body = ParseContent(adminEmailPage.EmailContent.ToHtmlString(), formModel); string[] recipients = adminEmailPage.EmailTo; if (recipients != null && recipients.Length > 0) { EmailService.SendMail(recipients, subject, body); } }