November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
What I can suggest you that you create an custom element called ConfirmEmail and a custom validator for validate that field. Then in the validate method of the validator, you will check if 2 email field are equal or not. You could look into sameple here: https://github.com/episerver/EPiServer.Forms.Samples to know how to create custom element and custom validator.
Hope this help.
Because you want cross field validation, you need to mark your orginal email field with a class, id, attribute. Then in the validate method of second field, query it out then do the validation. You also can override the method GetAttributes() of an element to return custom attributes which you may need for your query.
Sorry,
I'm new to episerver forms. Why do I need to mark my original email field with class, id, attribute. Don't you already mark the id by some guid value? Also, when you say query it out, are you saying I need to find it via jquery selector/client side? This seems to be a lot of work for a simple confim email. I would love to just do client side validation on this. Forms is slow enough as it is without adding additional server side validation which can be done client side.
What do you feel is the best way to add javascript validation to this. I feel I can use jquery to get the value of the original email box/confirm email but how do I go about putting a validation message under the confirm email box consistent with other validation messages?
Yes, I mean using jquery to find your element. The validator itself only validate for element which it associated with. So cross field validation need extra effort. You can see in the sample project (EPiServerFormsSample.js) you just return valiation result with message, it will be put on your element automatically.
"EPiServer.Forms.Samples.Implementation.Validation.RecaptchaValidator": function (fieldName, fieldValue, validatorMetaData) { // validate recaptcha element if (fieldValue) { return { isValid: true }; } return { isValid: false, message: validatorMetaData.model.message }; }
Hi i had the same "problem", this was my solution:
Add a custom element block with a custom validator:
[ContentType(GUID = "9d4e75c2-0e3f-4fa3-a907-4991fc0c4e0b")] public class VerifyEmailElementBlock : TextboxElementBlock, IElementCustomFormatValue, IElementRequireClientResources { [Display(GroupName = SystemTabNames.Content, Order = -6300)] public virtual string EmailLabel { get; set; } [Display(GroupName = SystemTabNames.Content, Order = -6400)] public virtual string VerifyEmailLabel { get; set; } [Display(GroupName = SystemTabNames.Content, Order = -5000)] public override string Validators { get { var theValidator = typeof(VerifyEmailValidator).FullName; var validators = this.GetPropertyValue(content => content.Validators); if (string.IsNullOrEmpty(validators)) { return theValidator; } else { return string.Concat(validators, EPiServer.Forms.Constants.RecordSeparator, theValidator); } } set { this.SetPropertyValue(content => content.Validators, value); } } public override void SetDefaultValues(ContentType contentType) { base.SetDefaultValues(contentType); if (string.IsNullOrEmpty(EmailLabel)) { EmailLabel = "Email"; } if (string.IsNullOrEmpty(VerifyEmailLabel)) { VerifyEmailLabel = "Confirm email";; } } public virtual object GetFormattedValue() { var submittedValues = GetSubmittedValue() as string[]; if (submittedValues == null) { return null; } var formattedValues = submittedValues.Select(value => { var valueString = value.ToString(); return valueString; }); return string.Join("|", formattedValues); } public IEnumerable<Tuple<string, string>> GetExtraResources() { return new List<Tuple<string, string>>() { //new Tuple<string, string>("script", "/ClientResources/Forms/jquery-ui.modified.js"), new Tuple<string, string>("script", "/ClientResources/Forms/VerifyEmailElementBlock.js") }; } }
Add custom validator:
public class VerifyEmailValidator : ElementValidatorBase { private Injected<LocalizationService> _localizationService; protected LocalizationService LocalizationService { get { return _localizationService.Service; } } public override bool? Validate(IElementValidatable targetElement) { var submittedValue = targetElement.GetSubmittedValue() as string; if (string.IsNullOrEmpty(submittedValue)) { return true; } string x = submittedValue.Split(',')[0]; string y = submittedValue.Split(',')[1]; if ((string) x == (string) y) { return true; } return false; } public override bool AvailableInEditView { get { return false; } } public override IValidationModel BuildValidationModel(IElementValidatable targetElement) { var model = base.BuildValidationModel(targetElement); if (model != null) { //Add error message model.Message = this.LocalizationService.GetString("/episerver/forms/validators/elementselfvalidator/unexpectedvalueisnotaccepted"); } return model; } }
Add custom forms view location:
[ServiceConfiguration(typeof(ICustomViewLocation))] public class FormsCustomViewLocation : CustomViewLocationBase { /// <summary> /// This will be loaded before path of Form.Core /// </summary> public override int Order { get { return 500; } set { } } public override string[] Paths => new string[] { "~/Views/Forms", GetDefaultViewLocation() }; }
Add element view:
@model VerifyEmailElementBlock @{ var formElement = Model.FormElement; var disabled = (Model.Disabled) ? "disabled = \"\"" : string.Empty; string defaultValue = Model.GetDefaultValue(); string email = string.Empty; string verifyEmail = string.Empty; if (!string.IsNullOrEmpty(defaultValue)) { email = defaultValue.Split(',')[0]; verifyEmail = defaultValue.Split(',')[1]; } string errorMessage = Model.GetErrorMessage(); string errorStryle = string.IsNullOrEmpty(errorMessage) ? "display:none" : ""; } <div class="Form__Element FormTextbox @Model.GetValidationCssClasses()" data-epiforms-element-name="@formElement.ElementName"> <label for="@string.Format("{0}_{1}", formElement.Guid, "email")" class="col-sm-2 control-label Form__Element__Caption">@Model.EmailLabel</label> <input name="@formElement.ElementName" @disabled id="@string.Format("{0}_{1}", formElement.Guid, "email")" type="text" class="FormTextbox__Input" placeholder="@Model.PlaceHolder" value="@email" @Html.Raw(Model.AttributesString) /> <label for="@string.Format("{0}_{1}", formElement.Guid, "verifyemail")" class="col-sm-2 control-label Form__Element__Caption">@Model.VerifyEmailLabel</label> <input name="@formElement.ElementName" @disabled id="@string.Format("{0}_{1}", formElement.Guid, "verifyemail")" type="text" class="FormTextbox__Input" placeholder="@Model.PlaceHolder" value="@verifyEmail" @Html.Raw(Model.AttributesString) /> <span data-epiforms-linked-name="@formElement.ElementName" class="Form__Element__ValidationError" style="@errorStryle">@errorMessage</span> @Model.RenderDataList() @if (!EPiServer.Editor.PageEditing.PageIsInEditMode) { <script type="text/javascript"> var __VerifyEmailElements = { emailId: "@formElement.Guid" + "_email", verifyEmailId: "@formElement.Guid" + "_verifyemail" } </script> } </div>
Add javascript validation:
(function ($) { $.extend(true, epi.EPiServer.Forms, { Validators: { "[INSERT NAMESPACE].VerifyEmailValidator": function validateAddress(fieldName, fieldValue, validatorMetaData) { if (typeof __VerifyEmailElements != "undefined") { if ($("#" + __VerifyEmailElements.emailId).val() === $("#" + __VerifyEmailElements.verifyEmailId).val()) { return {isValid: true} } } return { isValid: false, message: validatorMetaData.model.message }; } } }); })($$epiforms || $);
Would like two email boxes
How can I go about adding validation for box 2 like other typical email/confirm email validations?