Sitecore 9 Forms: How to Create a Unique Auto-Incremental ID Field

This title is pretty clear.

creating form field 6

What if you could have a unique ID for each form submitted that increments itself each time you read it?

If you never created a custom field on Sitecore forms you may be asking yourself how long it would take and if it’s worth spending the time trying it.

Don’t worry buddy, I’m here to share with you how easy it is if you know exactly what to do before starting. It should not take more than 5 minutes. Trust me.

giphy

This is a pretty common requirement actually. Clients may want to keep a unique ID for each submitted form and still be able to export this ID when exporting the form on Sitecore.

This ID may be a GUID or a random number (which by the way would have made our lives easier). But it can also be a unique auto-incremental integer if the order of submission matters for the client.

The Strategy

giphy-1

We have no choice other than creating a custom Sitecore Forms field and make it available on the Forms editor.

Besides that, we need to ensure that this field’s value is an integer and that each time we read it, the next retrieved value will be { previous value + 1}. To do that, the current value must be stored somewhere.

I decided to pick the so famous Properties database table to store this value. Initially, the core database was my chosen one, but since CDs may not have access to it (since 9.1 this may be the case) it wouldn’t work. To cover this case, the web database was the final decision since it’s reachable from CDs and CMs.

giphy-2

Creating the Custom Sitecore Form Field

I’m taking for granted that you will be using the Sitecore FormsExtension module from Bart Verdonck since not using it is pretty much sacrilege. Seriously, this module is awesome, try it.

giphy-3

Firstly we need to create the AutoIncrementalNumberViewModel.cs. If you are following the Helix principles you should have a Feature.FormsExtensions project. Open it, go to Fields folder and create the bellow class.

public class AutoIncrementalNumberViewModel : InputViewModel<string>
{
    private readonly IFormIdGeneratorService _formIdGeneratorService;

    public AutoIncrementalNumberViewModel()
    {
        this._formIdGeneratorService = new FormIdGeneratorService();
    }

    protected override void InitItemProperties(Item item)
    {
        base.InitItemProperties(item);
        Value = this._formIdGeneratorService.GenerateUniqueFormId();
    }

    protected override void UpdateItemFields(Item item)
    {
        base.UpdateItemFields(item);
    }

    protected override void InitializeValue(object value)
    {
        Value = value?.ToString();
    }
}

Nothing fancy. All it does is call the IFormIdGeneratorService which is where the real magic is done.

public interface IFormIdGeneratorService
{
    string GenerateUniqueFormId();
}
public class FormIdGeneratorService : IFormIdGeneratorService
{
    private const string INCREMENTAL_NUMBER_PROPERTY_NAME = "FORM_INCREMENTAL_ID_NUMBER";
    private const string PROPERTIES_DATABASE = "web";

    private static readonly Object obj = new Object();
    
    public string GenerateUniqueFormId()
    {
        return GetNextNumber().ToString();
    }

    private int GetNextNumber()
    {
        var nextNumber = 0;

        lock (obj)
        {
            var currentNumber = GetIntPropertyValue(INCREMENTAL_NUMBER_PROPERTY_NAME);
            nextNumber = currentNumber + 1;
            SetIntPropertyValue(INCREMENTAL_NUMBER_PROPERTY_NAME, nextNumber);
        }

        return nextNumber;
    }

    private void SetIntPropertyValue(string propertyName, int value)
    {
        Database database= Sitecore.Configuration.Factory.GetDatabase(PROPERTIES_DATABASE);
        if (database== null)
            return;

        using (new DatabaseSwitcher(database))
        {
            Sitecore.Context.Database.PropertyStore.SetIntValue(propertyName, value);
        }
    }

    private int GetIntPropertyValue(string propertyName)
    {
        Database database= Sitecore.Configuration.Factory.GetDatabase(PROPERTIES_DATABASE);
        if (database== null)
            return 0;

        using (new DatabaseSwitcher(database))
        {
            return Sitecore.Context.Database.PropertyStore.GetIntValue(propertyName, 1);
        }
    }
}

As you can see we have a lock on the main method GetNextNumber(). It ensures that we can keep consistency even with multiple simultaneous calls.

Other than that we have SetIntPropertyValue() and GetIntPropertyValue(). Nothing special here besides the DatabaseSwitcher(database) to guarantee that we are reading from the right database.

Now we need to create the razor view.

Guess what? Visually, we are creating another hidden field, right? Just go ahead and copy and paste the already existing Hidden.cshtml. 

Rename it to AutoIncrementalNumber.cshtml, change its model type to AutoIncrementalNumberViewModel and we are good to go here.

The last thing here is to build and publish everything.

Time to Open your Sitecore Content Editor

One item on the core database and two on the master. That’s all the work to be done here.

The Template (master)

/sitecore/templates/Feature/FormsExtensions/Fields/AutoIncrementalNumberField

Simply go ahead and create the above template.

Make sure it inherits from those two base templates: /sitecore/templates/System/Forms/Fields/Field and /sitecore/templates/System/Forms/Save Settings.

Don’t add any additional fields to it.

On its StandardValues set the value of Field Type to Field Types/Basic/Single-line text.

The Property Editor Setting (core)

/sitecore/client/Applications/FormsBuilder/Components/Layouts/PropertyGridForm/PageSettings/Settings/AutoIncrementalNumberField

This item represents the editing sections you are going to see on the Forms editor as soon as you add an Auto Increment Number field.

The easiest way to create this one is by copying and pasting the Hidden item in the same folder, rename it to AutoIncrementalNumberField and delete its Binding child item (we don’t need it at all).

creating form field 3.PNG

Now go to its Details child item and remove all ControDefinitons except the FieldName one.

creating form field 4.PNG

Finally, open the Advanced child item and do the same, just leaving the AllowSave option.

creating form field 5.PNG

The New Field Type (master)

/sitecore/system/Settings/Forms/Field Types/Basic/Auto Incremental Number

This item represents the new field you will see on the Forms Editor once our job is done here.

Set the View Path and Model Type so that you are using the values we created previously:

creating form field

After doing that, time to change the value of those three fields. Here we are going to link the other two Sitecore items we created with this one. You may want to define an icon as well since it will be shown on the Forms editor.

creating form field 2.PNG

Time to Test Everything!

Pick you one of your forms and open it on the Forms Editor.

Guess who will be there?

creating form field 6.PNG

Go ahead and put an Auto Increment Number field on your form (it’s hidden anyway so don’t worry too much about its place).

creating form field 7.PNG

Save it. That’s it, you made it.

Now you can test it by adding this form on a page and using it.

After that, you can either export your form to a CSV file to see this field’s value or even go directly on the Sitecore_ExperienceForms database if you know how to do it.

If you guys have any questions or doubt about this entire process feel free to reach me out on twitter @hsantos_x and I’ll be more than happy to help you.

Have a nice week you all!

giphy-4

Leave a comment