Using default values in Kentico MVC Forms
17/08/2020In Kentico Portal Engine, the Form Builder functionality allows you to create forms for collecting data from your visitors. You can embed these forms on pages across your website using the on-line form webpart, on-line form widget, or using the embed tool within a rich text area.
A nice feature that comes with the form builder is having the ability to configure default values, or prepopulate field values through query strings using query string macros (e.g. or {? firstName ?}). You can then direct visitors to these pages using carefully constructed URLs, so that text boxes are prepopulated with specific text, or dropdowns have default values that are set based on data being passed through from the previous page.
However, when it comes to Kentico MVC, the Form widget no longer resolves query string macros and therefore cannot be used to dynamically prepopulate field values out of the box. To work around this, I've found that the simplest way to replicate this feature is to add data attributes to fields and then use JavaScript to carry out the prepopulating of values. The approach I have taken is documented below in four simple steps.
Step 1 - Add a module class to the MVC project (e.g. GlobalEvents/FormBuilderConfigurationModule.cs)
using CMS;
using CMS.DataEngine;
using DancingGoat.GlobalEvents;
using Kentico.Forms.Web.Mvc;
using Kentico.Forms.Web.Mvc.Widgets;
using System;
[assembly: RegisterModule(typeof(FormBuilderConfigurationModule))]
namespace DancingGoat.GlobalEvents
{
public class FormBuilderConfigurationModule : Module
{
public FormBuilderConfigurationModule() : base("DancingGoat.FormBuilderConfigurationModule")
{
}
protected override void OnInit()
{
base.OnInit();
}
}
}
Step 2 - Customise the form markup by using the new global events, and adding data attributes for all fields within Kentico forms
using CMS;
using CMS.DataEngine;
using DancingGoat.GlobalEvents;
using Kentico.Forms.Web.Mvc;
using Kentico.Forms.Web.Mvc.Widgets;
using System;
[assembly: RegisterModule(typeof(FormBuilderConfigurationModule))]
namespace DancingGoat.GlobalEvents
{
public class FormBuilderConfigurationModule : Module
{
public FormBuilderConfigurationModule() : base("DancingGoat.FormBuilderConfigurationModule")
{
}
protected override void OnInit()
{
base.OnInit();
FormFieldRenderingConfiguration.GetConfiguration.Execute += InjectMarkupIntoKenticoComponents;
}
private static void InjectMarkupIntoKenticoComponents(object sender, GetFormFieldRenderingConfigurationEventArgs e)
{
// Only injects additional markup into default Kentico form components
if (!e.FormComponent.Definition.Identifier.StartsWith("Kentico", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
// Assigns additional attribute to fields for the field's codename.
AddFieldCodenameMarkup(e);
}
private static void AddFieldCodenameMarkup(GetFormFieldRenderingConfigurationEventArgs e)
{
e.Configuration.EditorHtmlAttributes["data-name-field"] = e.FormComponent.BaseProperties.Name;
}
}
}
Step 3 - Customise the Form widget's wrapper element by adding a target JavaScript class
using CMS;
using CMS.DataEngine;
using DancingGoat.GlobalEvents;
using Kentico.Forms.Web.Mvc;
using Kentico.Forms.Web.Mvc.Widgets;
using System;
[assembly: RegisterModule(typeof(FormBuilderConfigurationModule))]
namespace DancingGoat.GlobalEvents
{
public class FormBuilderConfigurationModule : Module
{
public FormBuilderConfigurationModule() : base("DancingGoat.FormBuilderConfigurationModule")
{
}
protected override void OnInit()
{
base.OnInit();
SetGlobalRenderingConfigurations();
FormFieldRenderingConfiguration.GetConfiguration.Execute += InjectMarkupIntoKenticoComponents;
}
private static void SetGlobalRenderingConfigurations()
{
FormWidgetRenderingConfiguration.Default = new FormWidgetRenderingConfiguration
{
// Elements wrapping the Form element
FormWrapperConfiguration = new FormWrapperRenderingConfiguration
{
ElementName = "section",
HtmlAttributes = { { "class", "js-bizform" } },
}
};
}
private static void InjectMarkupIntoKenticoComponents(object sender, GetFormFieldRenderingConfigurationEventArgs e)
{
// Only injects additional markup into default Kentico form components
if (!e.FormComponent.Definition.Identifier.StartsWith("Kentico", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
// Assigns additional attribute to fields for the field's codename.
AddFieldCodenameMarkup(e);
}
private static void AddFieldCodenameMarkup(GetFormFieldRenderingConfigurationEventArgs e)
{
e.Configuration.EditorHtmlAttributes["data-name-field"] = e.FormComponent.BaseProperties.Name;
}
}
}
Step 4 - Bundle JavaScript with the out of the box Form widget to prepopulate fields based on query string values, this file should be added to Content/Widgets/KenticoForm/KenticoFormWidget.js
const bizform = document.querySelector('.js-bizform');
// If there is a Kentico Form instance on the page
if (bizform) {
// Get all query string values
const searchParams = new URL(document.location).searchParams;
// Loop over query strings
searchParams.forEach(function (value, key) {
// Check if the query string key matches a field name
const field = bizform.querySelector(`[data-name-field="${key}"]`);
// If there is a match, store the value against the field
if (field) {
field.value = value;
}
});
}
With all this in place on the Dancing Goat sample site, you can now visit the URL http://localhost:8080/en-US/Contacts?UserFirstName=Liam&UserLastName=Goldfinch and my name will be prepopulated into the first name and last name fields of the contact form. If you inspect the form using your browser's devtools or view page source, you should be able to see the data attributes on each field that you can use to generate your own URLs.
You might also be interested in...
How to Easily Extend Xperience by Kentico UI Pages with Page Extenders
13/09/2024UI page extenders in Xperience by Kentico allow you to customise existing UI pages without modifying their source code. In this post, we’ll walk through a simple example of reordering columns in a listing layout to better suit your needs.
Enable Quick Page Editing from Your Xperience by Kentico Website Channels
23/08/2024Simplify content management with this new package for Xperience by Kentico. It adds an "Edit Page" button to your website channels, allowing editors to quickly access the Kentico administration interface and make updates effortlessly. Enhance your workflow and keep your content fresh with ease.
Boost Site Speed Using Image Processing for Xperience by Kentico
05/08/2024Discover how the XperienceCommunity.ImageProcessing package can significantly enhance your website's performance in Xperience by Kentico. This integration allows for resizing images and converting them to modern formats like WebP, resulting in faster page loads and improved user experience.