An article series by Dirk Schäfauer.

I am now able to identify a contact and save its preferences as described in Part 3 - Custom Marketing Preference Submit Action.

This topic is some kind of cherry on top of the concept. As I am now able to identify the contact and play around with its preferences, why not do something similar like the preference center?

The links in the newsletter are personalized for the contact and when a contact hits the link to update his preferences, his current preferences are selected in the marketing preference center.

I WANT TO HAVE THAT TOO!

Selecting the contact's preferences is already done in the fields view model:

var knownContact = _exmContactService.GetKnownXConnectContactByEmailAddress();
var marketingPreferences = new List<MarketingPreference>();
if (knownContact != null)
{
    marketingPreferences = _marketingPreferencesService.GetPreferences(knownContact, managerRoot.Id);
}

var marketingCategoryGroups = managerRoot.Settings.MarketingCategoryGroups.Select(database.GetItem).ToList();
if (!marketingCategoryGroups.Any())
{
    _logger.LogWarn("no marketing groups are associated to the manager root!");
    return;
}

foreach (var marketingCategoryGroup in marketingCategoryGroups)
{
    var marketingCategories = marketingCategoryGroup.Children;
    foreach (Item marketingCategory in marketingCategories)
    {
        var categoryListItem = new ListFieldItem();
        categoryListItem.ItemId = categoryListItem.Value = marketingCategory.ID.ToString();
        categoryListItem.Text = marketingCategory.DisplayName;
        categoryListItem.Selected = IsSelected(marketingPreferences, marketingCategory);
        Items.Add(categoryListItem);
    }
}

using (new SecurityDisabler())
{
    base.UpdateDataSourceSettings(item);
}

But, I just have a form and I don't want to have the possibility to manipulate the contact's preferences by just entering an email address. That would be a bad security vulnerability!

Hey! Sitecore Forms has the possibility to use conditions! Yay!

I created another custom field to get back a value if the contact is a known contact:

public class IsKnownExmContactViewModel : InputViewModel<string>
{
    private readonly IExmContactService _exmContactService;

    public IsKnownExmContactViewModel() : this(ServiceLocator.ServiceProvider.GetService<IExmContactService>())
    {
    }

    public IsKnownExmContactViewModel(IExmContactService exmContactService)
    {
        Condition.Requires(exmContactService, nameof(exmContactService)).IsNotNull();
        _exmContactService = exmContactService;
    }

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

    protected override void InitItemProperties(Item item)
    {
        base.InitItemProperties(item);
        Value = IsKnownContact().ToString();
    }

    private bool IsKnownContact()
    {
        return _exmContactService.GetKnownXConnectContactByEmailAddress() != null;
    }

    protected override void UpdateItemFields(Item item)
    {
        base.UpdateItemFields(item);
        var field = item.Fields["Default Value"];
        field?.SetValue(Value, true);
    }
}

To use conditions and actions you have to add your custom field to the operators and actions you want to use.
They are located at "/sitecore/system/Settings/Forms/Meta Data/Conditions/Operators" and "/sitecore/system/Settings/Forms/Meta Data/Conditions/Action Types".

In my case I want to hide a section which is already possible with the hide action. But I need to compare if my custom field has a boolean value so I have to add my field in the "Editor Settings" of the "is equal to"-operator.

is-equal-to-operator

Holy crap! Things are going to get epic!

Now we have to put it all together. Continue our adventure here Part 5 - The "Magic" Subscription Form.

Happy identifying!
Dirk

The author

dirk-autor
Dirk Schäfauer
Dirk bei LinkedIn