computer displaying code through a pair of glasses

Working with Episerver Forms submission data


User submitted form data can be very useful when integrated with CRM's or other 3rd party solutions. In this article, I will give you the tools you need to set that up with Episerver Forms

Estimated read time : 5 minutes

Jump to

Key takeaways

  • Event handling
  • Friendly names for Forms
  • Getting reference to form elements
  • Episerver Forms Samples

First of all - a background check

If you have not yet read the first article about Episerver form, you will find it here

Setting up an event handler

If we have other plans for our form data then just the standard Episerver Form functions (like sending standard mail and view submitted data) we need to inject to a form submission event (or another event, if you have other plans up your sleeve).

We do this in an initialization module. There are different events you can use for example FormsStepSubmitted but we are going to use the after form submission event.

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
[ModuleDependency(typeof(DependencyResolverInitialization))]
public class FormEventInitializer : IInitializableModule
{
    private static readonly ILogger _log = LogManager.GetLogger(typeof(FormEventInitializer));

    public void Initialize(InitializationEngine context)
    {
        var eventRegistry = ServiceLocator.Current.GetInstance<FormsEvents>();
        eventRegistry.FormsSubmissionFinalized += OnFormSubmissionFinalized;
    }
    private static void OnFormSubmissionFinalized(object sender, FormsEventArgs e)
    {
        if (e is FormsSubmittedEventArgs formSubmittedArgs)
        {
            var eventHandler = ServiceLocator.Current.GetInstance<IFormSubmissionEvents>();
            eventHandler.FormSubmissionFinished(formSubmittedArgs);
        }
        else
        {
            _log.Error("Unable to handle Form event");
        }
    }

    public void Uninitialize(InitializationEngine context)
    {

    }
}

I use dependency injection, so to resolve the interface - here is my dependency resolver for FormSubmission.

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class DependencyResolverInitialization : IConfigurableModule
{
    public void ConfigureContainer(ServiceConfigurationContext context)
    {
        context.StructureMap().Configure(ConfigureContainer);
    }

    private static void ConfigureContainer(ConfigurationExpression container)
    {
        container.For<IFormSubmissionEvents>().Singleton().Use<FormSubmission>();

        // singleton if the class do stuff in it's constructor that benefits from being done only once
        //container.For<IFormSubmissionEvents>().Singleton().Use<FormSubmission>();
    }

    public void Initialize(InitializationEngine context)
    {

    }

    public void Uninitialize(InitializationEngine context)
    {

    }
}

Cast object to our container wrapper block

To get the submission data we need to add the FormsSubmittedEventArgs as the parameter. In the FormsSubmittedEventArgs we get the form wrapper block content and we get the user input data. So from here, we can see what properties the form contains in the content object.

public class FormSubmission : IFormSubmissionEvents
{
    public void FormSubmissionFinished(FormsSubmittedEventArgs formContainer)
    {
        if (formContainer.FormsContent is FormContainerWrapperBlock currentFormBlock)
        {
            //currentFormBlock is now of type FormContainerWrapperBlock
        }
    }
}

Get content name to form element from submitted data

The user input is located in formsSubmittedEventArg.SubmissionData.Data. It comes in a KeyValuePair<string, object>.  The string (key) is for the form input field id and the object (value) is the value of the user input. If the value is a multiple option element the value will be separated with , (comma).

So now you got the field id and the user input value for all fields, all you need now is the name (or label) of the form element. You do this by getting the friendy names (this is the name of the element you created in the form container or the label which also is added in the element) for the form and comparing the field id's. This will look something like this:

if (formContainer.FormsContent is FormContainerWrapperBlock currentFormBlock)
{
    FormIdentity formIdentity = new FormIdentity(currentFormBlock.Content.ContentGuid, currentFormBlock.Content.LanguageBranch());
    IFormRepository formRepository = ServiceLocator.Current.GetInstance<IFormRepository>();
    IEnumerable<FriendlyNameInfo> nameInfoList = formRepository.GetDataFriendlyNameInfos(formIdentity);

    foreach (var userSubmittedData in formContainer.SubmissionData.Data)
    {
        var nameInfo = nameInfoList.FirstOrDefault(x => x.ElementId == userSubmittedData.Key);

        //nameInfo.FriendlyName is the content name
    }
}

Alternative code sample to get form container element reference and page reference

You can also get the content reference of the form element since the element id is placed in the key.

foreach (var userSubmittedData in formContainer.SubmissionData.Data)
{
    var contentRefId = userSubmittedData.Key.Split('_').Last();
    var contentref = new ContentReference(contentRefId);
}

Getting the page reference that the form was posted from can be collected from the SYSTEMCOLUMN_HostedPage key in the submitted data list.

if (userSubmittedData.Key == "SYSTEMCOLUMN_HostedPage")
{
    int.TryParse(userSubmittedData.Value.ToString(), out int id);

    if (id == 0)
    {
        continue;
    }

    //page form was submitted from
    var page = new PageReference(id);
}

 

Thanks for reading, and I hope you learned something about Episerver Form. Soon the third and last post regarding the Episerver forms will be published, in that post we will talk about the different actors for Episerver Forms.