umbraco/Umbraco.Forms.Issues

Workflows before "Submit message / Go to page"

Closed this issue · 1 comments

I want to create a custom workflow that can be placed between On Submit and Submit message / Go to page. The workflow could then be used to prevent the form from being submitted and return our own validation criteria.

This idea stems from a member registration form I'm building in Umbraco Forms, and I need the password and password confirmation fields to be the same. There is no way through the UI to accomplish this on the client or server side.

image

Although the UI doesn't make this very clear, actually all workflows on submit (and on approve if manual approval isn't set for the form) will run before the redirect or message is displayed. So what you are requesting is actually already the case. So I'll close this request.

In terms of the validation you are looking for, I think you could hook into the validation notification. You'll need to rely on some conventions to identify your fields, but something like this might work for you:

using Umbraco.Cms.Core.Events;
using Umbraco.Forms.Core.Models;
using Umbraco.Forms.Core.Services.Notifications;

namespace Umbraco.Forms.Testsite.Business;

public class FormValidateNotificationHandler : INotificationHandler<FormValidateNotification>
{
    public void Handle(FormValidateNotification notification)
    {
        List<Field> formFields = notification.Form.AllFields;
        Field? passwordField = GetField(formFields, "password");
        Field? confirmPasswordField = GetField(formFields, "confirmPassword");
        if (passwordField is not null && confirmPasswordField is not null)
        {
            var passwordValue = GetPasswordValue(passwordField);
            var confirmPasswordValue = GetPasswordValue(confirmPasswordField);

            if (!string.IsNullOrEmpty(passwordValue) && passwordValue != confirmPasswordValue)
            {
                notification.ModelState.AddModelError(confirmPasswordField.Id.ToString(), "Password does not match.");
            }
        }
    }

    private static Field? GetField(IEnumerable<Field> fields, string alias) => fields.SingleOrDefault(f => f.Alias == alias);

    private static string? GetPasswordValue(Field field) => field.Values.FirstOrDefault()?.ToString();
}