[Sitecore Forms] How to group forms by sites in Sitecore 9.0 update 1

In Sitecore, forms are created using Sitecore Forms, found in the path “/sitecore/Forms“. However, if our website has many various forms, this might lead to some issues:

  1. It’s a bit difficult to find a specific form in the content tree especially if there are many websites (multi-sites) under a single Sitecore instance and each site has many forms. Sometimes, we remember. But sometimes, we forget.
  2. If there are a lot of items with same level under the parent item (e.g. “/sitecore/Forms“) then when expanding the parent item, performance may be affected because, as recommended by Sitecore, a parent item should have maximum of 100 same-level children.

In this blog, I want to share with you an approach to address this problem. The idea is:

  1. Create folders as containers against sites under “/sitecore/Forms“.
  2. When CMS users create forms, we will move them to appropriate folders above so that whenever we determine a form under a single site, we just go to the folder accordingly under “/sitecore/Forms“.
  3. Functionality to filter forms by sites under Sitecore Forms will be configured.

Firstly, we create folders for sites, for examples: SiteA, SiteB, SiteC.

To move forms to appropriate sites, we can leverage Sitecore Event Handler with the method “OnItemSaved” to trigger the event of form creation. In Visual Studio, create a class named “FormsHandler” as below:

public class FormsHandler
{
	public void OnItemSaved(object sender, EventArgs args)
	{
		// Get the item
		var item = Event.ExtractParameter(args, 0) as Item;

		Assert.IsNotNull(item, "item");
		if (item == null)
			return;

		// Check if the item template is not form template then no action
		if (item.TemplateID != TemplateIds.FormTemplateId)
			return;
		
		// Move the form to appropriate folders (sites)
		FormsService.MoveForm(item);
	}
}

The method MoveForm looks like below. We get the form item name and check if it starts with any folders we created above. From that, we get the destination item and to which move the form item using ItemManager.MoveItem.

public static class FormsService
{
	private static readonly Database MasterDatabase = Factory.GetDatabase("master");

	public static void MoveForm(Item formItem)
	{
		var formItemName = formItem.Name.Replace(" ", "");
		var siteName = formItemName.StartsWith("SiteA") ? "SiteA" : (formItemName.StartsWith("SiteB") ? "SiteB" : (formItemName.StartsWith("SiteC") ? "SiteC" : string.Empty));

		if (string.IsNullOrEmpty(siteName))
			return;

		var destinationFormFolderItem = MasterDatabase.GetItem($"/sitecore/Forms/{siteName}");
		if (destinationFormFolderItem != null)
		{
			try
			{
				using (new SecurityDisabler())
				{
					ItemManager.MoveItem(formItem, destinationFormFolderItem);
				}
			}
			catch (Exception ex)
			{
				Log.Error($"Could not move form item {formItem.Name} to destination folder.", ex, typeof(FormsService));
			}
		}
	}
}

Create the Sitecore Patch as below for “OnItemSaved” event:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"  xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore>
    <events>
      <event name="item:saved">
        <handler patch:before="*[1]" type="[YOUR_NAMESPACE].FormsHandler, [YOUR_ASSEMBLY]" method="OnItemSaved" />
      </event>
    </events>
  </sitecore>
</configuration>

Deploy the code changes. Navigate to Sitecore Forms in Sitecore Launchpad and create a form named SiteA Testing Form and Save.

Go to Sitecore Content Editor, and under “/sitecore/Forms/SiteA“, we should see that form. Repeat the steps above with SiteB Testing Form and SiteC Testing Form, the result will be:

Now, we will make some changes to create a flexibility for CMS users to filter forms by sites on the left hand-side of Sitecore Forms :

Switch to Core database and navigate to the item “/sitecore/client/Applications/FormsBuilder/Pages/Forms/PageSettings/DataSource/MyFormsSearchConfig“. Duplicate it and name it as AllFormsSiteA. Switch to “Raw values” view and update:

  1. DisplayText: Site A
  2. Root: the ID of the item “/sitecore/Forms/SiteA” on Master database

Save and do the same steps for AllFormsSiteB and AllFormsSiteC.

Next, duplicate the item “/sitecore/client/Applications/FormsBuilder/Components/Navigation/Menu/Forms/My forms” and name it as Site A then update the field:

  • NavigateUrl: replace the value of parameter “sc” with the ID of item “/sitecore/client/Applications/FormsBuilder/Pages/Forms/PageSettings/DataSource/AllFormsSiteA

Do the same steps for Site B and Site C. Now, back to Sitecore Forms and we should see the filter by sites. Clicking on sites, the forms are displayed accordingly.

More enhancements/checks:

  1. You can use Sitecore built-in functions to get your sites dynamically to avoid hard-coding.
  2. Should check the Sitecore functionalities in the newer version to see whether Sitecore supports already. For my side, I saw that in Sitecore 9.3, Sitecore allows users to select the location before saving the form as below. This means we no need the custom code for event “OnItemSaved“.

Got issues?

Please leave a comment below or drop me an email at [email protected].

Thanks for reading and happy Sitecore coding!

Related Articles:

Leave a Comment