Adding PasswordField and improving validation API.

This commit is contained in:
Sipke Schoorstra
2014-10-16 00:53:04 -07:00
parent d096bc206c
commit ea2d3a6c4b
35 changed files with 510 additions and 110 deletions

View File

@@ -0,0 +1,69 @@
using Orchard.DynamicForms.Elements;
using Orchard.Forms.Services;
using Orchard.Layouts.Framework.Drivers;
using DescribeContext = Orchard.Forms.Services.DescribeContext;
namespace Orchard.DynamicForms.Drivers {
public class PasswordFieldDriver : FormsElementDriver<PasswordField>{
public PasswordFieldDriver(IFormManager formManager) : base(formManager) {}
protected override EditorResult OnBuildEditor(PasswordField element, ElementEditorContext context) {
var autoLabelEditor = BuildForm(context, "AutoLabel");
var passwordFieldValidation = BuildForm(context, "PasswordFieldValidation", "Validation:10");
return Editor(context, autoLabelEditor, passwordFieldValidation);
}
protected override void DescribeForm(DescribeContext context) {
context.Form("PasswordFieldValidation", factory => {
var shape = (dynamic)factory;
var form = shape.Fieldset(
Id: "PasswordFieldValidation",
_IsRequired: shape.Checkbox(
Id: "IsRequired",
Name: "IsRequired",
Title: "Required",
Value: "true",
Description: T("Tick this checkbox to make this password field a required field.")),
_MinimumLength: shape.Textbox(
Id: "MinimumLength",
Name: "MinimumLength",
Title: "Minimum Length",
Classes: new[] { "text", "medium", "tokenized" },
Description: T("The minimum length required.")),
_MaximumLength: shape.Textbox(
Id: "MaximumLength",
Name: "MaximumLength",
Title: "Maximum Length",
Classes: new[] { "text", "medium", "tokenized" },
Description: T("The maximum length allowed.")),
_RegularExpression: shape.Textbox(
Id: "RegularExpression",
Name: "RegularExpression",
Title: "Regular Expression",
Classes: new[] { "text", "large"},
Description: T("The regular expression the password must match with.")),
_CompareWith: shape.Textbox(
Id: "CompareWith",
Name: "CompareWith",
Title: "Compare With",
Classes: new[] { "text", "medium", "tokenized" },
Description: T("The name of another field whose value must match with this password field.")),
_CustomValidationMessage: shape.Textbox(
Id: "CustomValidationMessage",
Name: "CustomValidationMessage",
Title: "Custom Validation Message",
Classes: new[] { "text", "large", "tokenized" },
Description: T("Optionally provide a custom validation message.")),
_ShowValidationMessage: shape.Checkbox(
Id: "ShowValidationMessage",
Name: "ShowValidationMessage",
Title: "Show Validation Message",
Value: "true",
Description: T("Autogenerate a validation message when a validation error occurs for the current field. Alternatively, to control the placement of the validation message you can use the ValidationMessage element instead.")));
return form;
});
}
}
}

View File

@@ -0,0 +1,9 @@
using Orchard.DynamicForms.Validators.Settings;
namespace Orchard.DynamicForms.Elements {
public class PasswordField : LabeledFormElement {
public PasswordFieldValidationSettings ValidationSettings {
get { return State.GetModel<PasswordFieldValidationSettings>(""); }
}
}
}

View File

@@ -13,11 +13,11 @@ namespace Orchard.DynamicForms.Handlers {
_formService = formService;
}
void IFormElementEventHandler.RegisterClientValidation(RegisterClientValidationAttributesEventContext context) {
var validators = _formService.GetValidators(context.Element).ToArray();
void IFormElementEventHandler.RegisterClientValidation(FormElement element, RegisterClientValidationAttributesContext context) {
var validators = _formService.GetValidators(element).ToArray();
foreach (var validator in validators) {
validator.RegisterClientValidation(context);
validator.RegisterClientValidation(element, context);
}
}
@@ -27,10 +27,16 @@ namespace Orchard.DynamicForms.Handlers {
if (element == null)
return;
var registrationContext = new RegisterClientValidationAttributesEventContext { Element = element };
var registrationContext = new RegisterClientValidationAttributesContext {
FieldName = element.Name
};
if (element.Form.EnableClientValidation == true) {
_formService.RegisterClientValidationAttributes(registrationContext);
_formService.RegisterClientValidationAttributes(element, registrationContext);
if (registrationContext.ClientAttributes.Any()) {
registrationContext.ClientAttributes["data-val"] = "true";
}
}
context.ElementShape.ClientValidationAttributes = registrationContext.ClientAttributes;

View File

@@ -17,12 +17,12 @@ namespace Orchard.DynamicForms.Handlers {
foreach (var validator in validators) {
var validateContext = new ValidateInputContext {
Element = element,
ModelState = modelState,
AttemptedValue = attemptedValue,
FieldName = element.Name
FieldName = element.Name,
Values = values
};
validator.Validate(validateContext);
validator.Validate(element, validateContext);
}
}
}

View File

@@ -0,0 +1,9 @@
using System;
namespace Orchard.DynamicForms.Helpers {
public static class StringExtensions {
public static string WithDefault(this string value, string defaultValue) {
return !String.IsNullOrWhiteSpace(value) ? value : defaultValue;
}
}
}

View File

@@ -137,8 +137,10 @@
<Compile Include="Controllers\SubmissionAdminController.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\FormController.cs" />
<Compile Include="Drivers\PasswordFieldDriver.cs" />
<Compile Include="Drivers\ValidationMessageDriver.cs" />
<Compile Include="Drivers\ValidationSummaryDriver.cs" />
<Compile Include="Elements\PasswordField.cs" />
<Compile Include="Elements\ValidationMessage.cs" />
<Compile Include="Elements\ValidationSummary.cs" />
<Compile Include="Handlers\ClientValidationRegistrationCoordinator.cs" />
@@ -146,15 +148,27 @@
<Compile Include="Handlers\FormSubmissionCoordinator.cs" />
<Compile Include="Helpers\FormControllerExtensions.cs" />
<Compile Include="Helpers\FieldValidatorsExtensions.cs" />
<Compile Include="Helpers\StringExtensions.cs" />
<Compile Include="Services\ElementValidator.cs" />
<Compile Include="Services\FormEventHandlerBase.cs" />
<Compile Include="Services\IValidationRuleFactory.cs" />
<Compile Include="Services\ITempDataAccessor.cs" />
<Compile Include="Services\IElementValidator.cs" />
<Compile Include="Services\Models\RegisterClientValidationAttributesEventContext.cs" />
<Compile Include="Services\Models\RegisterClientValidationAttributesContext.cs" />
<Compile Include="Services\Models\ValidationContext.cs" />
<Compile Include="Services\ValidationRuleFactory.cs" />
<Compile Include="Services\IValidationRule.cs" />
<Compile Include="ValidationRules\Mandatory.cs" />
<Compile Include="ValidationRules\Compare.cs" />
<Compile Include="ValidationRules\RegularExpression.cs" />
<Compile Include="ValidationRules\StringLength.cs" />
<Compile Include="Validators\CheckBoxValidator.cs" />
<Compile Include="ValidationRules\Required.cs" />
<Compile Include="Services\ValidationRule.cs" />
<Compile Include="Validators\Settings\CheckBoxValidationSettings.cs" />
<Compile Include="Validators\Settings\PasswordFieldValidationSettings.cs" />
<Compile Include="Validators\Settings\TextFieldValidationSettings.cs" />
<Compile Include="Validators\Settings\ValidationSettingsBase.cs" />
<Compile Include="Services\Models\ValidationSettingsBase.cs" />
<Compile Include="Services\Models\FormEventContext.cs" />
<Compile Include="Drivers\ValidationElementDriver.cs" />
<Compile Include="Drivers\BindingsElementDriver.cs" />
@@ -181,7 +195,7 @@
<Compile Include="ImportExport\FormsExportStep.cs" />
<Compile Include="ImportExport\FormsExportHandler.cs" />
<Compile Include="ImportExport\FormsImportHandler.cs" />
<Compile Include="Services\IFormEventHandler.cs" />
<Compile Include="Services\IDynamicFormEventHandler.cs" />
<Compile Include="Services\Models\FieldValidatorDescriptor.cs" />
<Compile Include="Services\Models\FormSubmittedEventContext.cs" />
<Compile Include="Services\Models\FormValidatedEventContext.cs" />
@@ -190,6 +204,7 @@
<Compile Include="Services\Models\ContentFieldBindingDescriptor.cs" />
<Compile Include="Services\Models\ContentPartBindingDescriptor.cs" />
<Compile Include="Services\Models\ValidateInputContext.cs" />
<Compile Include="Validators\PasswordFieldValidator.cs" />
<Compile Include="Validators\TextFieldValidator.cs" />
<Compile Include="ViewModels\FieldValidationSettings.cs" />
<Compile Include="ViewModels\FormBindingSettings.cs" />
@@ -345,6 +360,12 @@
<ItemGroup>
<Content Include="Views\FormElement.Wrapper.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Element-Form-PasswordField.Design.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\Element-Form-PasswordField.cshtml" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@@ -1,18 +1,36 @@
using System.Collections.Generic;
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public abstract class ElementValidator<TElement> : Component, IElementValidator where TElement : FormElement {
public void Validate(ValidateInputContext context) {
OnValidate((TElement) context.Element, context);
public void Validate(FormElement element, ValidateInputContext context) {
OnValidate((TElement)element, context);
var rules = GetValidationRules((TElement)element);
foreach (var rule in rules) {
rule.Validate(context);
if (!context.ModelState.IsValid)
break;
}
}
public void RegisterClientValidation(RegisterClientValidationAttributesEventContext context) {
OnRegisterClientValidation((TElement)context.Element, context);
public void RegisterClientValidation(FormElement element, RegisterClientValidationAttributesContext context) {
OnRegisterClientValidation((TElement)element, context);
var rules = GetValidationRules((TElement)element);
foreach (var rule in rules) {
rule.RegisterClientAttributes(context);
}
}
protected virtual IEnumerable<IValidationRule> GetValidationRules(TElement element) {
yield break;
}
protected virtual void OnValidate(TElement element, ValidateInputContext context) {}
protected virtual void OnRegisterClientValidation(TElement element, RegisterClientValidationAttributesEventContext context) {}
protected virtual void OnRegisterClientValidation(TElement element, RegisterClientValidationAttributesContext context) {}
}
}

View File

@@ -4,6 +4,6 @@ using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public abstract class FormElementEventHandlerBase : IFormElementEventHandler {
public virtual void GetElementValue(FormElement element, ReadElementValuesContext context) {}
public virtual void RegisterClientValidation(RegisterClientValidationAttributesEventContext context) {}
public virtual void RegisterClientValidation(FormElement element, RegisterClientValidationAttributesContext context) {}
}
}

View File

@@ -1,7 +1,7 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public abstract class FormEventHandlerBase : Component, IFormEventHandler {
public abstract class FormEventHandlerBase : Component, IDynamicFormEventHandler {
public virtual void Submitted(FormSubmittedEventContext context) {}
public virtual void Validating(FormValidatingEventContext context) {}
public virtual void Validated(FormValidatedEventContext context) {}

View File

@@ -10,7 +10,6 @@ using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Settings;
using Orchard.Data;
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Handlers;
using Orchard.DynamicForms.Helpers;
using Orchard.DynamicForms.Models;
using Orchard.DynamicForms.Services.Models;
@@ -32,7 +31,7 @@ namespace Orchard.DynamicForms.Services {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IBindingManager _bindingManager;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IFormEventHandler _formEventHandler;
private readonly IDynamicFormEventHandler _formEventHandler;
private readonly Lazy<IEnumerable<IElementValidator>> _validators;
public FormService(
@@ -44,7 +43,7 @@ namespace Orchard.DynamicForms.Services {
IContentDefinitionManager contentDefinitionManager,
IBindingManager bindingManager,
IHttpContextAccessor httpContextAccessor,
IFormEventHandler formEventHandler,
IDynamicFormEventHandler formEventHandler,
Lazy<IEnumerable<IElementValidator>> validators) {
_serializer = serializer;
@@ -272,8 +271,8 @@ namespace Orchard.DynamicForms.Services {
return _validators.Value.ToArray();
}
public void RegisterClientValidationAttributes(RegisterClientValidationAttributesEventContext context) {
_elementHandlers.RegisterClientValidation(context);
public void RegisterClientValidationAttributes(FormElement element, RegisterClientValidationAttributesContext context) {
_elementHandlers.RegisterClientValidation(element, context);
}
private static void InvokePartBindings(

View File

@@ -2,7 +2,7 @@
using Orchard.Events;
namespace Orchard.DynamicForms.Services {
public interface IFormEventHandler : IEventHandler {
public interface IDynamicFormEventHandler : IEventHandler {
void Submitted(FormSubmittedEventContext context);
void Validating(FormValidatingEventContext context);
void Validated(FormValidatedEventContext context);

View File

@@ -1,8 +1,9 @@
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public interface IElementValidator : IDependency {
void Validate(ValidateInputContext context);
void RegisterClientValidation(RegisterClientValidationAttributesEventContext context);
void Validate(FormElement element, ValidateInputContext context);
void RegisterClientValidation(FormElement element, RegisterClientValidationAttributesContext context);
}
}

View File

@@ -5,6 +5,6 @@ using Orchard.Events;
namespace Orchard.DynamicForms.Services {
public interface IFormElementEventHandler : IEventHandler{
void GetElementValue(FormElement element, ReadElementValuesContext context);
void RegisterClientValidation(RegisterClientValidationAttributesEventContext context);
void RegisterClientValidation(FormElement element, RegisterClientValidationAttributesContext context);
}
}

View File

@@ -30,6 +30,6 @@ namespace Orchard.DynamicForms.Services {
IEnumerable<IElementValidator> GetValidators(FormElement element);
IEnumerable<IElementValidator> GetValidators(Type elementType);
IEnumerable<IElementValidator> GetValidators();
void RegisterClientValidationAttributes(RegisterClientValidationAttributesEventContext context);
void RegisterClientValidationAttributes(FormElement element, RegisterClientValidationAttributesContext context);
}
}

View File

@@ -0,0 +1,9 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public interface IValidationRule {
string ErrorMessage { get; set; }
void Validate(ValidateInputContext context);
void RegisterClientAttributes(RegisterClientValidationAttributesContext context);
}
}

View File

@@ -0,0 +1,8 @@
using System;
namespace Orchard.DynamicForms.Services {
public interface IValidationRuleFactory : IDependency {
T Create<T>(Action<T> setup = null) where T : ValidationRule, new();
T Create<T>(string errorMessage = null, Action<T> setup = null) where T : ValidationRule, new();
}
}

View File

@@ -1,13 +1,10 @@
using System.Collections.Generic;
using Orchard.DynamicForms.Elements;
namespace Orchard.DynamicForms.Services.Models {
public class RegisterClientValidationAttributesEventContext {
public RegisterClientValidationAttributesEventContext() {
public class RegisterClientValidationAttributesContext : ValidationContext {
public RegisterClientValidationAttributesContext() {
ClientAttributes = new Dictionary<string, string>();
}
public IDictionary<string, string> ClientAttributes { get; set; }
public FormElement Element { get; set; }
}
}

View File

@@ -1,11 +1,10 @@
using System.Web.Mvc;
using Orchard.DynamicForms.Elements;
using System.Collections.Specialized;
using System.Web.Mvc;
namespace Orchard.DynamicForms.Services.Models {
public class ValidateInputContext {
public FormElement Element { get; set; }
public class ValidateInputContext : ValidationContext {
public ModelStateDictionary ModelState { get; set; }
public string FieldName { get; set; }
public string AttemptedValue { get; set; }
public NameValueCollection Values { get; set; }
}
}

View File

@@ -0,0 +1,5 @@
namespace Orchard.DynamicForms.Services.Models {
public class ValidationContext {
public string FieldName { get; set; }
}
}

View File

@@ -1,4 +1,4 @@
namespace Orchard.DynamicForms.Validators.Settings {
namespace Orchard.DynamicForms.Services.Models {
public abstract class ValidationSettingsBase {
public string CustomValidationMessage { get; set; }
public bool? ShowValidationMessage { get; set; }

View File

@@ -0,0 +1,9 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Services {
public abstract class ValidationRule : Component, IValidationRule {
public string ErrorMessage { get; set; }
public abstract void Validate(ValidateInputContext context);
public virtual void RegisterClientAttributes(RegisterClientValidationAttributesContext context) { }
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace Orchard.DynamicForms.Services {
public class ValidationRuleFactory : Component, IValidationRuleFactory {
public TRule Create<TRule>(Action<TRule> setup = null) where TRule : ValidationRule, new() {
return Create(errorMessage: null, setup: setup);
}
public TRule Create<TRule>(string errorMessage = null, Action<TRule> setup = null) where TRule : ValidationRule, new() {
var rule = new TRule {
T = T,
Logger = Logger,
ErrorMessage = errorMessage
};
if (setup != null)
setup(rule);
return rule;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using Orchard.DynamicForms.Helpers;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.Localization;
namespace Orchard.DynamicForms.ValidationRules {
public class Compare : ValidationRule {
public string TargetName { get; set; }
public override void Validate(ValidateInputContext context) {
var targetValue = context.Values[TargetName];
if (!String.Equals(context.AttemptedValue, targetValue)) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
public override void RegisterClientAttributes(RegisterClientValidationAttributesContext context) {
context.ClientAttributes["data-val-equalto"] = GetValidationMessage(context).Text;
context.ClientAttributes["data-val-equalto-other"] = "*." + TargetName;
}
private LocalizedString GetValidationMessage(ValidationContext context) {
return T(ErrorMessage.WithDefault("{0} must match the value of {1}."), context.FieldName, TargetName);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using Orchard.DynamicForms.Helpers;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.Localization;
namespace Orchard.DynamicForms.ValidationRules {
public class Mandatory : ValidationRule {
public override void Validate(ValidateInputContext context) {
if (String.IsNullOrWhiteSpace(context.AttemptedValue)) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
public override void RegisterClientAttributes(RegisterClientValidationAttributesContext context) {
context.ClientAttributes["data-val-mandatory"] = GetValidationMessage(context).Text;
}
private LocalizedString GetValidationMessage(ValidationContext context) {
return T(ErrorMessage.WithDefault("{0} is a mandatory field."), context.FieldName);
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Text.RegularExpressions;
using Orchard.DynamicForms.Helpers;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.Localization;
namespace Orchard.DynamicForms.ValidationRules {
public class RegularExpression : ValidationRule {
public RegularExpression() {
RegexOptions = RegexOptions.Singleline | RegexOptions.IgnoreCase;
}
public string Pattern { get; set; }
public RegexOptions RegexOptions { get; set; }
public override void Validate(ValidateInputContext context) {
if (!Regex.IsMatch(context.AttemptedValue, Pattern, RegexOptions)) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
public override void RegisterClientAttributes(RegisterClientValidationAttributesContext context) {
context.ClientAttributes["data-val-regex"] = GetValidationMessage(context).Text;
context.ClientAttributes["data-val-regex-pattern"] = Pattern;
}
private LocalizedString GetValidationMessage(ValidationContext context) {
return T(ErrorMessage.WithDefault("{0} must match the following pattern: {1}."), context.FieldName, Pattern);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using Orchard.DynamicForms.Helpers;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.Localization;
namespace Orchard.DynamicForms.ValidationRules {
public class Required : ValidationRule {
public override void Validate(ValidateInputContext context) {
if (String.IsNullOrWhiteSpace(context.AttemptedValue)) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
public override void RegisterClientAttributes(RegisterClientValidationAttributesContext context) {
context.ClientAttributes["data-val-required"] = GetValidationMessage(context).Text;
}
private LocalizedString GetValidationMessage(ValidationContext context) {
return T(ErrorMessage.WithDefault("{0} is a required field."), context.FieldName);
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Globalization;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.Localization;
namespace Orchard.DynamicForms.ValidationRules {
public class StringLength : ValidationRule {
public int? Minimum { get; set; }
public int? Maximum { get; set; }
public override void Validate(ValidateInputContext context) {
if (Minimum != null) {
if (context.AttemptedValue == null || context.AttemptedValue.Length < Minimum) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
if (Maximum != null) {
if (context.AttemptedValue == null || context.AttemptedValue.Length > Maximum) {
var message = GetValidationMessage(context);
context.ModelState.AddModelError(context.FieldName, message.Text);
}
}
}
public override void RegisterClientAttributes(RegisterClientValidationAttributesContext context) {
if (Minimum != null || Maximum != null) {
context.ClientAttributes["data-val-length"] = GetValidationMessage(context).Text;
if (Minimum != null) {
context.ClientAttributes["data-val-length-min"] = Minimum.Value.ToString(CultureInfo.InvariantCulture);
}
if (Maximum != null) {
context.ClientAttributes["data-val-length-max"] = Maximum.Value.ToString(CultureInfo.InvariantCulture);
}
}
}
private LocalizedString GetValidationMessage(ValidationContext context) {
if (!String.IsNullOrWhiteSpace(ErrorMessage))
return T(ErrorMessage, context.FieldName, Minimum, Maximum);
if(Minimum != null && Maximum != null)
return T("{0} must be between {1} and {2} characters long.", context.FieldName, Minimum, Maximum);
return T("{0} must be at least {1} characters long.", context.FieldName, Minimum);
}
}
}

View File

@@ -1,41 +1,20 @@
using System;
using System.Collections.Generic;
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.DynamicForms.Validators.Settings;
using Orchard.DynamicForms.ValidationRules;
namespace Orchard.DynamicForms.Validators {
public class CheckBoxValidator : ElementValidator<CheckBox> {
protected override void OnValidate(CheckBox element, ValidateInputContext context) {
var settings = element.ValidationSettings;
if (settings.IsMandatory != true)
return;
if (String.IsNullOrWhiteSpace(context.AttemptedValue)) {
var message = GetValidationMessage(settings);
context.ModelState.AddModelError(context.FieldName, T(message, context.FieldName).Text);
}
private readonly IValidationRuleFactory _validationRuleFactory;
public CheckBoxValidator(IValidationRuleFactory validationRuleFactory) {
_validationRuleFactory = validationRuleFactory;
}
protected override void OnRegisterClientValidation(CheckBox element, RegisterClientValidationAttributesEventContext context) {
protected override IEnumerable<IValidationRule> GetValidationRules(CheckBox element) {
var settings = element.ValidationSettings;
if (settings.IsMandatory != true)
return;
var message = GetValidationMessage(settings);
context.ClientAttributes["data-val"] = "true";
context.ClientAttributes["data-val-mandatory"] = T(message, context.Element.Name).Text;
}
private string GetValidationMessage(CheckBoxValidationSettings settings) {
var message = String.IsNullOrWhiteSpace(settings.CustomValidationMessage)
? "{0} is a mandatory field."
: settings.CustomValidationMessage;
return message;
if (settings.IsMandatory == true)
yield return _validationRuleFactory.Create<Mandatory>(settings.CustomValidationMessage);
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.ValidationRules;
namespace Orchard.DynamicForms.Validators {
public class PasswordFieldValidator : ElementValidator<PasswordField> {
private readonly IValidationRuleFactory _validationRuleFactory;
public PasswordFieldValidator(IValidationRuleFactory validationRuleFactory) {
_validationRuleFactory = validationRuleFactory;
}
protected override IEnumerable<IValidationRule> GetValidationRules(PasswordField element) {
var settings = element.ValidationSettings;
if (settings.IsRequired == true)
yield return _validationRuleFactory.Create<Required>(settings.CustomValidationMessage);
if (settings.MinimumLength != null || settings.MaximumLength != null) {
yield return _validationRuleFactory.Create<StringLength>(r => {
r.Minimum = settings.MinimumLength;
r.Maximum = settings.MaximumLength;
r.ErrorMessage = settings.CustomValidationMessage;
});
}
if (!String.IsNullOrWhiteSpace(settings.RegularExpression)) {
yield return _validationRuleFactory.Create<RegularExpression>(r => {
r.Pattern = settings.RegularExpression;
r.ErrorMessage = settings.CustomValidationMessage;
});
}
if (!String.IsNullOrWhiteSpace(settings.CompareWith)) {
yield return _validationRuleFactory.Create<Compare>(r => {
r.TargetName = settings.CompareWith;
r.ErrorMessage = settings.CustomValidationMessage;
});
}
}
}
}

View File

@@ -1,3 +1,5 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Validators.Settings {
public class CheckBoxValidationSettings : ValidationSettingsBase {
public bool? IsMandatory { get; set; }

View File

@@ -0,0 +1,11 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Validators.Settings {
public class PasswordFieldValidationSettings : ValidationSettingsBase {
public bool? IsRequired { get; set; }
public int? MinimumLength { get; set; }
public int? MaximumLength { get; set; }
public string RegularExpression { get; set; }
public string CompareWith { get; set; }
}
}

View File

@@ -1,3 +1,5 @@
using Orchard.DynamicForms.Services.Models;
namespace Orchard.DynamicForms.Validators.Settings {
public class TextFieldValidationSettings : ValidationSettingsBase {
public bool? IsRequired { get; set; }

View File

@@ -1,56 +1,28 @@
using System;
using System.Globalization;
using System.Collections.Generic;
using Orchard.DynamicForms.Elements;
using Orchard.DynamicForms.Services;
using Orchard.DynamicForms.Services.Models;
using Orchard.DynamicForms.Validators.Settings;
using Orchard.DynamicForms.ValidationRules;
namespace Orchard.DynamicForms.Validators {
public class TextFieldValidator : ElementValidator<TextField> {
protected override void OnValidate(TextField element, ValidateInputContext context) {
var settings = element.ValidationSettings;
if (settings.IsRequired != true)
return;
if (String.IsNullOrWhiteSpace(context.AttemptedValue)) {
var message = GetValidationMessage(settings);
context.ModelState.AddModelError(context.FieldName, T(message, context.FieldName).Text);
}
private readonly IValidationRuleFactory _validationRuleFactory;
public TextFieldValidator(IValidationRuleFactory validationRuleFactory) {
_validationRuleFactory = validationRuleFactory;
}
protected override void OnRegisterClientValidation(TextField element, RegisterClientValidationAttributesEventContext context) {
protected override IEnumerable<IValidationRule> GetValidationRules(TextField element) {
var settings = element.ValidationSettings;
if (settings.IsRequired != true && settings.MinimumLength == null && settings.MaximumLength == null)
return;
var message = GetValidationMessage(settings);
if (settings.IsRequired == true)
yield return _validationRuleFactory.Create<Required>(settings.CustomValidationMessage);
context.ClientAttributes["data-val"] = "true";
if(settings.IsRequired == true)
context.ClientAttributes["data-val-required"] = T(message, context.Element.Name).Text;
if (settings.MaximumLength != null || settings.MinimumLength != null) {
if (settings.MaximumLength != null) {
context.ClientAttributes["data-val-length-max"] = settings.MaximumLength.Value.ToString(CultureInfo.InvariantCulture);
}
if (settings.MinimumLength != null) {
context.ClientAttributes["data-val-length-min"] = settings.MinimumLength.Value.ToString(CultureInfo.InvariantCulture);
}
context.ClientAttributes["data-val-length"] = T(message, element.Name, settings.MaximumLength, settings.MinimumLength).Text;
if (settings.MinimumLength != null || settings.MaximumLength != null) {
yield return _validationRuleFactory.Create<StringLength>(r => {
r.Minimum = settings.MinimumLength;
r.Maximum = settings.MaximumLength;
r.ErrorMessage = settings.CustomValidationMessage;
});
}
}
private string GetValidationMessage(TextFieldValidationSettings validationSettings) {
var message = String.IsNullOrWhiteSpace(validationSettings.CustomValidationMessage)
? "{0} is a required field."
: validationSettings.CustomValidationMessage;
return message;
}
}
}

View File

@@ -0,0 +1,24 @@
@using Orchard.DisplayManagement.Shapes
@using Orchard.DynamicForms.Elements
@using Orchard.Layouts.Helpers
@using Orchard.Layouts.Settings
@{
var element = (PasswordField)Model.Element;
var commonSettings = element.State.GetModel<CommonElementSettings>();
var tagBuilder = (OrchardTagBuilder)TagBuilderExtensions.AddCommonElementAttributes(new OrchardTagBuilder("input"), Model);
tagBuilder.AddCssClass("text design");
tagBuilder.Attributes["type"] = "password";
tagBuilder.Attributes["value"] = element.Value;
tagBuilder.Attributes["name"] = element.Name;
}
@if (element.ShowLabel) {
<div>
<label for="@commonSettings.Id">@element.Label</label>
@Html.Raw(tagBuilder.ToString(TagRenderMode.SelfClosing))
</div>
}
else {
@Html.Raw(tagBuilder.ToString(TagRenderMode.SelfClosing))
}

View File

@@ -0,0 +1,26 @@
@using Orchard.DisplayManagement.Shapes
@using Orchard.DynamicForms.Elements
@using Orchard.Layouts.Helpers
@using Orchard.Layouts.Settings
@{
var element = (PasswordField)Model.Element;
var commonSettings = element.State.GetModel<CommonElementSettings>();
var tagBuilder = (OrchardTagBuilder)TagBuilderExtensions.AddCommonElementAttributes(new OrchardTagBuilder("input"), Model);
tagBuilder.AddCssClass("text");
tagBuilder.Attributes["type"] = "password";
tagBuilder.Attributes["name"] = element.Name;
tagBuilder.AddClientValidationAttributes((IDictionary<string, string>)Model.ClientValidationAttributes);
if (!ViewData.ModelState.IsValidField(element.Name)) {
tagBuilder.AddCssClass("input-validation-error");
}
}
@if (element.ShowLabel) {
<label for="@commonSettings.Id">@element.Label</label>
}
@Html.Raw(tagBuilder.ToString(TagRenderMode.SelfClosing))
@if (element.ValidationSettings.ShowValidationMessage == true) {
@Html.ValidationMessage(element.Name)
}