In this blog post I’ll show you how you can create a custom Episerver Forms form container block. Then I will extend it having custom properties to enter the Google Tag Manager related form submit event information.
This is another approach to my previous GTM blog post where I needed to be able to add the information to already existing forms – in that case I created new Episerver Forms block element to add the information.
First thing is to install the Episerver Forms NuGet package from Episerver NuGet feed to your project. At the time of writing the latest Episerver Forms NuGet package version is 4.24.0 so I’ll be using that in this sample.
Episerver has instructions to create the custom form container block on their instructions page but the instructions currently make some assumptions and skip the information what you should copy as the base for the customized view file. Related to this is also the instruction to create a two column form container block.
So when you install the Episerver Forms package it will add its files to your project under the ‘modules/_protected‘ folder. The package adds two folders: ‘EPiServer.Forms‘ and ‘EPiServer.Forms.UI‘.
In the EPiServer.Forms folder will be a zip package ‘EPiServer.Forms.zip‘ which contains the embedded language files, resources for the view templates and more importantly the default Episerver Forms view templates (.ascx files) to render the container and form elements. This zip file contains the ‘FormContainerBlock’ view file that should be copied as the base for our custom view. The folder also contains the ‘Forms.config‘ file that can be used to configure Episerver Forms.
I use the Alloy MVC (the one you can create from the Episerver Visual Studio extension) site in the sample, so its default project structure is used.
Create block, controller and view for the custom form container
We need to implement a custom block to be the container for Forms element blocks. We also need to have a custom controller for our new container block and then a view that renders our container.
Container block implementation
Our custom Forms container block needs to inherit the Episerver base class ‘EPiServer.Forms.Implementation.Elements.FormContainerBlock’.
Create a new folder called ‘Forms‘ under the ‘Models‘ folder. Then add a new Episerver ‘Block Type‘ (using VS add new item) there called ‘SiteFormsContainerBlock‘. Add using statement ‘EPiServer.Forms.Implementation.Elements‘ to the code file and change your block to inherit the ‘FormContainerBlock‘ class. Next edit the ContentType attribute, add a description for your block (info to editors) and then also set this blocks group to be the same as the default container blocks group is (GroupName = EPiServer.Forms.Constants.FormElementGroup_Container).
We also need to tell Episerver about our custom container, so we need to add the ServiceConfiguration attribute to our class: [ServiceConfiguration(typeof(IFormContainerBlock))]. You need to add using statements for ‘EPiServer.Forms.Core’ and ‘EPiServer.ServiceLocation’.
Next we add two custom properties to the container: Google Tag Manager form name and category name. In this sample I will have just two string properties where the editor enters the values but for example for the category a list of possible values could be used (like I used in the previous post the GtmSelectionFactory).
Next step is to implement the controller for our custom container block. Episerver has a base class for this, so our controller should inherit the ” class.
Add new controller under folder ‘Controllers’ using the Episerver ‘Block Controller (MVC)’ template and name the new controller ‘SiteFormsContainerBlockController’. Add using statements: ‘EPiServer.Forms.Implementation.Elements‘ and ‘EPiServer.Forms.Controllers‘. Switch the new controller to inherit FormContainerBlockController class and change the type for the index method to ‘FormContainerBlock’ currentBlock. Change the Index method implementation to use ‘return base.Index(currentBlock);’
So here comes the part where we implement our custom view for the container. First step is to get our “base” view implementation. This is the hacky part, we need to extract the Episerver implementation from the EPiServer.Forms.zip file and then copy paste it as our implementation.
I’ll use the default location for custom Forms view files which is defined in the ‘modules\_protected\EPiServer.Forms\Forms.config‘, see the ‘formElementViewsFolder‘ value. So next create folder ‘~/Views/Shared/ElementBlocks’ and add new view file named ‘FormContainerBlock’, use the Episerver ‘Block Template (Web Forms)‘ to add the view file. Delete the created .ascx.cs and .ascx.designer.cs files for the FormContainerBlock.ascx.
Extract the default implementation to a temporary location: open the EPiServer.Forms.zip file in your favorite archiving tool and extract the ‘Views\ElementBlocks\FormContainerBlock.ascx‘ to temporary location. Open the extracted file in a text editor, copy the file content and paste the text to the just created .ascx file in Visual Studio. Next change the ViewUserControl<FormContainerBlock> to use our custom class: SiteFormsContainerBlock and add using statement for the SiteFormsContainerBlock namespace.
So this is how it looks in action
In browser console we can see the values taken from data-* attributes and the GTM form submission event triggered.
Wrapping it up
As can be seen from the sample, it is quite easy to implement your own custom Episerver Forms container block but it is hack as you need to copy paste the orginal view code to your implementation and modify it. In the long run maintaining the Episerver Forms updates to the view code and synching those back to your custom code might become a nightmare or at least an extra step each time you update the Episerver Forms NuGet package(s).