Sometimes, we need to save some additional information when a user submits a Sitecore form. This can include information about an authenticated user, or some other form of data not present in the fields on the form. Static data can be bound to hidden fields, of course, but in our case, we needed dynamic data pulled in real-time and appended as values on the form submission.

Let’s take a quick look at this example. This post simply shows how this can be achieved, but you’ll need to update it with your own needs.

For our purposes, we wanted to create a copy of the “Save Data” submit action, and create a new one that had the additional data. This way, authors can choose what they wish to happen when a form is submitted.

We begin by duplicating the “Save Data” submit action located here:
/sitecore/system/Settings/Forms/Submit Actions/Save Data and named it “Save Data and User” . On the newly created item, you’ll want to change the “ModelType” field to point to your code.

Let’s take a look at the code:

You’ll need to reference “Sitecore.ExperienceForms.Mvc” in your project and to simply things, add these using statements:

using Sitecore.ExperienceForms.Models;
using Sitecore.ExperienceForms.Mvc.Models.Fields;

Let’s start at the top and explain each section. Our class needs to inherit from ” Sitecore.ExperienceForms.Processing.Actions.SaveData” which is simply the class used by the out of the box “Save Data” submit action.

public class SaveFormDataWithCurrentUser: Sitecore.ExperienceForms.Processing.Actions.SaveData {
  public SaveFormDataWithCurrentUser(ISubmitActionData submitActionData) : base(submitActionData) {

  }
}

This next part will obviously need to change depending on what you’re attempting to save. In our case, we had authenticated user, and we’re trying to extract some information from the xConnect facet.

Here, we’re simply overriding the SavePostedData method in the original code. As an example, the contact facet is retrieved (which has been previously populated with the user’s information). We then add the first name, last name, and birth date as fields to the form submission

protected override bool SavePostedData(Guid formId, Guid sessionId, IList < IViewModel > postedFields) {
  try {
    var user = Sitecore.Context.User;
    var source = Sitecore.Context.Site.Name;
    var contactId = Sitecore.Analytics.Tracker.Current.Contact.ContactId.ToString();

    var contactExpandOptions = new ContactExpandOptions(PersonalInformation.DefaultFacetKey, EmailAddressList.DefaultFacetKey);

    using(var client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) {
      var contact = client.Get(
      new IdentifiedContactReference(source, contactId), contactExpandOptions);

      if (contact == null) {
        Sitecore.Diagnostics.Log.Debug($ "No xDB Contact exists for identifier: {contactId}", this);
        return false;
      }

      var personaltInformationFacet = contact.GetFacet < PersonalInformation > (PersonalInformation.DefaultFacetKey);

      if (postedFields.Any()) {
        postedFields.Add(CreateCurrentUserTextField(personaltInformationFacet.LastName, "Last Name"));
        postedFields.Add(CreateCurrentUserTextField(personaltInformationFacet.LastName, "Last Name"));
        postedFields.Add(CreateCurrentUserTextField(personaltInformationFacet.Birthdate.ToString(), "Birthdate"));
      }
    }
  }
  catch(XdbExecutionException ex) {
    Sitecore.Diagnostics.Log.Error(
    $ "Error retrieving xDB Contact", ex, this);
  }

  return base.SavePostedData(formId, sessionId, postedFields);

}

The actual “form field” for which the value is stored is generated on the fly using the “CreateCurrentUserTextField” method:

private IViewModel CreateCurrentUserTextField(string value, string name) {
  var userField = new InputViewModel < string > {
    Value = value,
    Name = name,
    ItemId = Guid.NewGuid().ToString(),
    AllowSave = true,
    IsTrackingEnabled = false
  };
  return userField;
}

That’s all there is to it. The form submissions will now have the values from the form, plus our additional fields that we injected.

To use this, we simply assign our new submit action to the submit button on the form. Upon submission of a form by a website user, the reports will show the additional fields.