diff --git a/Add-ons/UmbracoForms/Developer/Extending/Adding-a-Fieldtype.md b/Add-ons/UmbracoForms/Developer/Extending/Adding-a-Fieldtype.md index 2b2ccc72e95..49f9a2f0679 100644 --- a/Add-ons/UmbracoForms/Developer/Extending/Adding-a-Fieldtype.md +++ b/Add-ons/UmbracoForms/Developer/Extending/Adding-a-Fieldtype.md @@ -160,3 +160,106 @@ To reference the file you should override the `RenderView` property, e.g.: ```csharp public override string RenderView => "~/App_Plugins/UmbracoFormsCustomFields/backoffice/Common/RenderTypes/mycustomrenderfield.html"; ``` + +## Validation + +If using [jQuery validate](https://jqueryvalidation.org/) it is possible to use various methods in a custom field type, e.g. `equalTo`, `digits` or `remote`. + +For example a Compare field type to compare another field. + +```csharp +public class CompareField : Umbraco.Forms.Core.FieldType +{ + public CompareField() + { + this.Id = new Guid("b83dddc2-bdf3-4a0b-b9ad-f7bba83080df"); + this.Name = "Compare field"; + this.Description = "Compare input to another field."; + this.Icon = "icon-legal"; + this.FieldTypeViewName = "FieldType.Compare.cshtml"; + this.DataType = FieldDataType.String; + this.SortOrder = 20; + this.SupportsRegex = true; + } + + [Setting("Field to compare", + Description = "Alias of field to compare.", + View = "textfield")] + public string FieldToCompare { get; set; } + + /// + /// Gets or sets a value indicating whether the field label should be shown. + /// PreValues are a single element, a boolean indicating whether the default for the the checkbox is "checked". + /// + [Setting("Show Label", Description = "Indicate whether the field's label should be shown when rendering the form.", View = "checkbox", PreValues = "true", DisplayOrder = 20)] + public string ShowLabel { get; set; } = string.Empty; + + /// + public override bool HideLabel => ShowLabel == "False"; // Checking explicitly for false so the backward compatible default is to show the label. + + public override string GetDesignView() => + "~/App_Plugins/UmbracoForms/backoffice/Common/FieldTypes/Textfield.html"; + + public override IEnumerable ValidateField(Form form, Field field, IEnumerable postedValues, HttpContext context, IPlaceholderParsingService placeholderParsingService) + { + var baseValidation = base.ValidateField(form, field, postedValues, context, placeholderParsingService); + var value = postedValues.FirstOrDefault(); + + var fieldToCompare = GetPostFieldValue(form, context, FieldToCompare); + + if (fieldToCompare == null) + return baseValidation; + + if (value != null && value.ToString() == fieldToCompare) + { + return baseValidation; + } + + var custom = new List(); + custom.AddRange(baseValidation); + custom.Add("Not equal to."); + + return custom; + } + + private static string GetPostFieldValue(Form form, HttpContext context, string key) + { + Field? field = GetPostField(form, key); + if (field == null) + { + return string.Empty; + } + + return context.Request.HasFormContentType && context.Request.Form.Keys.Contains(field.Id.ToString()) + ? context.Request.Form[field.Id.ToString()].ToString().Trim() + : string.Empty; + } + + private static Field? GetPostField(Form form, string key) => form.AllFields.SingleOrDefault(f => f.Alias == key); +} +``` + +```csharp +@using Umbraco.Forms.Web +@model Umbraco.Forms.Web.Models.FieldViewModel + +@inject Umbraco.Forms.Web.Services.IFormRenderingService FormRenderingService + +@{ + var maxLength = Model.GetSettingValue("MaximumLength", 255); + var fieldType = Model.GetSettingValue("FieldType", "text"); + var autocompleteAttribute = Model.GetSettingValue("AutocompleteAttribute", string.Empty); + var fieldToCompare = Model.GetSettingValue("FieldToCompare", string.Empty); + + var form = FormRenderingService.GetForm(Guid.Parse("0638c6f0-f6db-460d-b462-6dc393a8ae0c")); + var field = form?.AllFields.SingleOrDefault(x => x.Alias == compareField); +} + + placeholder="@Model.PlaceholderText" }} + @{if (string.IsNullOrEmpty(autocompleteAttribute) == false) { autocomplete="@autocompleteAttribute" }} + @{if (string.IsNullOrEmpty(fieldToCompare) == false) { data-val-equalto="Not equal to @field?.Caption" data-val-equalto-other="@field?.Id" }} + @{if (Model.Mandatory || Model.Validate) { data-val="true" }} + @{if (Model.Mandatory) { data-val-required="@Model.RequiredErrorMessage" }} + @{if (Model.Validate) { data-val-regex="@Model.InvalidErrorMessage" data-val-regex-pattern="@Html.Raw(Model.Regex)" }} /> +```