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 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, 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, 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 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 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,

        [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 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="mamta.alle@dxred.com">
        <network host="smtp.gmail.com" port="587" userName="mamta.alle@dxred.com" 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);
                }

            }