mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
URL Field for Dynamic Forms
Created this because I was binding to a content type that had a URL field. Need to do this validation when submitting the dynamic form.
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
using Orchard.DynamicForms.Elements;
|
||||||
|
using Orchard.Forms.Services;
|
||||||
|
using Orchard.Layouts.Framework.Drivers;
|
||||||
|
using Orchard.Layouts.Framework.Display;
|
||||||
|
using Orchard.Layouts.Helpers;
|
||||||
|
using Orchard.Tokens;
|
||||||
|
using DescribeContext = Orchard.Forms.Services.DescribeContext;
|
||||||
|
|
||||||
|
namespace Orchard.DynamicForms.Drivers {
|
||||||
|
public class UrlFieldElementDriver : FormsElementDriver<UrlField> {
|
||||||
|
private readonly ITokenizer _tokenizer;
|
||||||
|
|
||||||
|
public UrlFieldElementDriver(IFormManager formManager, ITokenizer tokenizer) : base(formManager) {
|
||||||
|
_tokenizer = tokenizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override EditorResult OnBuildEditor(UrlField element, ElementEditorContext context) {
|
||||||
|
var autoLabelEditor = BuildForm(context, "AutoLabel");
|
||||||
|
var webAddressFieldEditor = BuildForm(context, "UrlField");
|
||||||
|
var webAddressFieldValidation = BuildForm(context, "UrlFieldValidation", "Validation:10");
|
||||||
|
|
||||||
|
return Editor(context, autoLabelEditor, webAddressFieldEditor, webAddressFieldValidation);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DescribeForm(DescribeContext context) {
|
||||||
|
context.Form("UrlField", factory => {
|
||||||
|
var shape = (dynamic) factory;
|
||||||
|
var form = shape.Fieldset(
|
||||||
|
Id: "UrlField",
|
||||||
|
_Value: shape.Textbox(
|
||||||
|
Id: "Value",
|
||||||
|
Name: "Value",
|
||||||
|
Title: "Value",
|
||||||
|
Classes: new[] {"text", "medium", "tokenized"},
|
||||||
|
Description: T("The value of this URL field.")));
|
||||||
|
|
||||||
|
return form;
|
||||||
|
});
|
||||||
|
|
||||||
|
context.Form("UrlFieldValidation", factory => {
|
||||||
|
var shape = (dynamic) factory;
|
||||||
|
var form = shape.Fieldset(
|
||||||
|
Id: "UrlFieldValidation",
|
||||||
|
_IsRequired: shape.Checkbox(
|
||||||
|
Id: "IsRequired",
|
||||||
|
Name: "IsRequired",
|
||||||
|
Title: "Required",
|
||||||
|
Value: "true",
|
||||||
|
Description: T("Tick this checkbox to make this email field a required field.")),
|
||||||
|
_MaximumLength: shape.Textbox(
|
||||||
|
Id: "MaximumLength",
|
||||||
|
Name: "MaximumLength",
|
||||||
|
Title: "Maximum Length",
|
||||||
|
Classes: new[] {"text", "medium", "tokenized"},
|
||||||
|
Description: T("The maximum length allowed.")),
|
||||||
|
_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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDisplaying(UrlField element, ElementDisplayContext context) {
|
||||||
|
context.ElementShape.ProcessedName = _tokenizer.Replace(element.Name, context.GetTokenData());
|
||||||
|
context.ElementShape.ProcessedLabel = _tokenizer.Replace(element.Label, context.GetTokenData());
|
||||||
|
context.ElementShape.ProcessedValue = _tokenizer.Replace(element.RuntimeValue, context.GetTokenData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
using Orchard.DynamicForms.Validators.Settings;
|
||||||
|
|
||||||
|
namespace Orchard.DynamicForms.Elements {
|
||||||
|
public class UrlField : LabeledFormElement {
|
||||||
|
public UrlFieldValidationSettings ValidationSettings {
|
||||||
|
get { return Data.GetModel<UrlFieldValidationSettings>(""); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -167,7 +167,9 @@
|
|||||||
<Compile Include="Bindings\InputFieldBindings.cs" />
|
<Compile Include="Bindings\InputFieldBindings.cs" />
|
||||||
<Compile Include="Bindings\TaxonomyFieldBindings.cs" />
|
<Compile Include="Bindings\TaxonomyFieldBindings.cs" />
|
||||||
<Compile Include="Drivers\FieldsetElementDriver.cs" />
|
<Compile Include="Drivers\FieldsetElementDriver.cs" />
|
||||||
|
<Compile Include="Drivers\UrlFieldElementDriver.cs" />
|
||||||
<Compile Include="Elements\Fieldset.cs" />
|
<Compile Include="Elements\Fieldset.cs" />
|
||||||
|
<Compile Include="Elements\UrlField.cs" />
|
||||||
<Compile Include="Forms\AddModelErrorForm.cs" />
|
<Compile Include="Forms\AddModelErrorForm.cs" />
|
||||||
<Compile Include="Forms\SelectDynamicForms.cs" />
|
<Compile Include="Forms\SelectDynamicForms.cs" />
|
||||||
<Compile Include="Bindings\TextFieldBindings.cs" />
|
<Compile Include="Bindings\TextFieldBindings.cs" />
|
||||||
@@ -217,7 +219,9 @@
|
|||||||
<Compile Include="ValidationRules\EmailAddress.cs" />
|
<Compile Include="ValidationRules\EmailAddress.cs" />
|
||||||
<Compile Include="ValidationRules\RegularExpression.cs" />
|
<Compile Include="ValidationRules\RegularExpression.cs" />
|
||||||
<Compile Include="ValidationRules\StringLength.cs" />
|
<Compile Include="ValidationRules\StringLength.cs" />
|
||||||
|
<Compile Include="ValidationRules\UrlAddress.cs" />
|
||||||
<Compile Include="Validators\QueryValidator.cs" />
|
<Compile Include="Validators\QueryValidator.cs" />
|
||||||
|
<Compile Include="Validators\Settings\UrlFieldValidationSettings.cs" />
|
||||||
<Compile Include="Validators\TaxonomyValidator.cs" />
|
<Compile Include="Validators\TaxonomyValidator.cs" />
|
||||||
<Compile Include="Validators\EnumerationValidator.cs" />
|
<Compile Include="Validators\EnumerationValidator.cs" />
|
||||||
<Compile Include="Validators\CheckBoxValidator.cs" />
|
<Compile Include="Validators\CheckBoxValidator.cs" />
|
||||||
@@ -271,6 +275,7 @@
|
|||||||
<Compile Include="Validators\ReCaptchaValidator.cs" />
|
<Compile Include="Validators\ReCaptchaValidator.cs" />
|
||||||
<Compile Include="Validators\TextAreaValidator.cs" />
|
<Compile Include="Validators\TextAreaValidator.cs" />
|
||||||
<Compile Include="Validators\TextFieldValidator.cs" />
|
<Compile Include="Validators\TextFieldValidator.cs" />
|
||||||
|
<Compile Include="Validators\UrlFieldValidator.cs" />
|
||||||
<Compile Include="ViewModels\FieldValidationSettings.cs" />
|
<Compile Include="ViewModels\FieldValidationSettings.cs" />
|
||||||
<Compile Include="ViewModels\FormBindingSettings.cs" />
|
<Compile Include="ViewModels\FormBindingSettings.cs" />
|
||||||
<Compile Include="Helpers\ContentTypeDefinitionExtensions.cs" />
|
<Compile Include="Helpers\ContentTypeDefinitionExtensions.cs" />
|
||||||
@@ -506,6 +511,12 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Assets.json" />
|
<Content Include="Assets.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\Elements\UrlField.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\Elements\UrlField.Design.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
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 UrlAddress : ValidationRule
|
||||||
|
{
|
||||||
|
public UrlAddress() {
|
||||||
|
RegexOptions = RegexOptions.Singleline | RegexOptions.IgnoreCase;
|
||||||
|
Pattern = @"^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$";
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Tokenize(ErrorMessage.WithDefault(String.Format("{0} is not a valid url.", context.FieldName)), context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
using Orchard.DynamicForms.Services.Models;
|
||||||
|
|
||||||
|
namespace Orchard.DynamicForms.Validators.Settings {
|
||||||
|
public class UrlFieldValidationSettings : ValidationSettingsBase {
|
||||||
|
public bool? IsRequired { get; set; }
|
||||||
|
public int? MaximumLength { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.DynamicForms.Elements;
|
||||||
|
using Orchard.DynamicForms.Services;
|
||||||
|
using Orchard.DynamicForms.ValidationRules;
|
||||||
|
|
||||||
|
namespace Orchard.DynamicForms.Validators {
|
||||||
|
public class UrlFieldValidator : ElementValidator<UrlField> {
|
||||||
|
private readonly IValidationRuleFactory _validationRuleFactory;
|
||||||
|
|
||||||
|
public UrlFieldValidator(IValidationRuleFactory validationRuleFactory) {
|
||||||
|
_validationRuleFactory = validationRuleFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<IValidationRule> GetValidationRules(UrlField element) {
|
||||||
|
var settings = element.ValidationSettings;
|
||||||
|
|
||||||
|
if (settings.IsRequired == true)
|
||||||
|
yield return _validationRuleFactory.Create<Required>(settings.CustomValidationMessage);
|
||||||
|
|
||||||
|
if (settings.MaximumLength != null) {
|
||||||
|
yield return _validationRuleFactory.Create<StringLength>(r => {
|
||||||
|
r.Maximum = settings.MaximumLength;
|
||||||
|
r.ErrorMessage = settings.CustomValidationMessage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,21 @@
|
|||||||
|
@using Orchard.DynamicForms.Elements
|
||||||
|
@using Orchard.Layouts.Helpers
|
||||||
|
@{
|
||||||
|
var element = (UrlField)Model.Element;
|
||||||
|
var tagBuilder = TagBuilderExtensions.CreateElementTagBuilder(Model, "input");
|
||||||
|
|
||||||
|
tagBuilder.AddCssClass("text design");
|
||||||
|
tagBuilder.Attributes["type"] = "url";
|
||||||
|
tagBuilder.Attributes["value"] = element.Value;
|
||||||
|
tagBuilder.Attributes["name"] = element.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (element.ShowLabel) {
|
||||||
|
<div>
|
||||||
|
<label for="@element.HtmlId">@element.Label</label>
|
||||||
|
@tagBuilder.ToHtmlString(TagRenderMode.SelfClosing)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@tagBuilder.ToHtmlString(TagRenderMode.SelfClosing)
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
@using Orchard.DisplayManagement.Shapes
|
||||||
|
@using Orchard.DynamicForms.Elements
|
||||||
|
@using Orchard.Layouts.Helpers
|
||||||
|
@{
|
||||||
|
var element = (UrlField)Model.Element;
|
||||||
|
var tagBuilder = (OrchardTagBuilder)TagBuilderExtensions.CreateElementTagBuilder(Model, "input");
|
||||||
|
|
||||||
|
tagBuilder.AddCssClass("text");
|
||||||
|
tagBuilder.Attributes["type"] = "url";
|
||||||
|
tagBuilder.Attributes["value"] = Model.ProcessedValue;
|
||||||
|
tagBuilder.Attributes["name"] = Model.ProcessedName;
|
||||||
|
tagBuilder.AddClientValidationAttributes((IDictionary<string, string>)Model.ClientValidationAttributes);
|
||||||
|
|
||||||
|
if (!ViewData.ModelState.IsValidField(Model.ProcessedName)) {
|
||||||
|
tagBuilder.AddCssClass("input-validation-error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (element.ShowLabel) {
|
||||||
|
<label for="@element.HtmlId">@Model.ProcessedLabel</label>
|
||||||
|
}
|
||||||
|
@tagBuilder.ToHtmlString(TagRenderMode.SelfClosing)
|
||||||
|
@if (element.ValidationSettings.ShowValidationMessage == true) {
|
||||||
|
@Html.ValidationMessage((string)Model.ProcessedName)
|
||||||
|
}
|
Reference in New Issue
Block a user