mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-09 19:24:38 +08:00
Feature/maxlengthsetting (#8719)
* added MaxLength setting for TextField # Conflicts: # src/Orchard.Web/Modules/Orchard.Taxonomies/Settings/TaxonomyFieldEditorEvents.cs * added MaxLength setting for TitlePart * added missing files * Removed where clause * changed title length to a constant and updated the recipe * added comment to remind people to update the migration when they change the constant introduced previously * fixed hint text for title * fixed maxLength initialization in TitlePartSettings.cshtml * MaxTitleLength constant is now Pascal case * Correction on constant spelling in TitlePartSettings shape. --------- Co-authored-by: Andrea Piovanelli <andrea.piovanelli@laser-group.com>
This commit is contained in:
committed by
GitHub
parent
eb09ab7f95
commit
44bfa390bc
@@ -10,6 +10,7 @@ using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Services;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Core.Common.Drivers {
|
||||
public class TextFieldDriver : ContentFieldDriver<TextField> {
|
||||
@@ -71,6 +72,16 @@ namespace Orchard.Core.Common.Drivers {
|
||||
if (settings.Required && String.IsNullOrWhiteSpace(field.Value)) {
|
||||
updater.AddModelError("Text", T("The field {0} is mandatory", T(field.DisplayName)));
|
||||
}
|
||||
|
||||
if (settings.MaxLength > 0) {
|
||||
|
||||
var value = new HtmlString(_htmlFilters.Aggregate(field.Value, (text, filter) => filter.ProcessContent(text, settings.Flavor)))
|
||||
.ToString().RemoveTags();
|
||||
|
||||
if (value.Length > settings.MaxLength) {
|
||||
updater.AddModelError("Text", T("The maximum allowed length for the field {0} is {1}", T(field.DisplayName), settings.MaxLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Editor(part, field, shapeHelper);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Orchard.Core.Common.Settings {
|
||||
|
||||
@@ -8,5 +9,8 @@ namespace Orchard.Core.Common.Settings {
|
||||
public bool Required { get; set; }
|
||||
public string Hint { get; set; }
|
||||
public string DefaultValue { get; set; }
|
||||
[Range(0, int.MaxValue)]
|
||||
[DisplayName("Maximum Length")]
|
||||
public int MaxLength { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,10 @@ namespace Orchard.Core.Common.Settings {
|
||||
builder.WithSetting("TextFieldSettings.Hint", model.Settings.Hint);
|
||||
builder.WithSetting("TextFieldSettings.Required", model.Settings.Required.ToString(CultureInfo.InvariantCulture));
|
||||
builder.WithSetting("TextFieldSettings.DefaultValue", model.Settings.DefaultValue);
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
builder.WithSetting("TextFieldSettings.MaxLength", model.Settings.MaxLength.ToString());
|
||||
}
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
@{
|
||||
var htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text large"}
|
||||
};
|
||||
var htmlAttributes = (Dictionary<string, object>)Model.HtmlAttributes;
|
||||
|
||||
if (htmlAttributes == null) {
|
||||
htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text large"}
|
||||
};
|
||||
}
|
||||
else {
|
||||
htmlAttributes["class"] = "text large";
|
||||
}
|
||||
|
||||
if (Model.Required == true) {
|
||||
htmlAttributes["required"] = "required";
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
@{
|
||||
var htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text small"}
|
||||
};
|
||||
var htmlAttributes = (Dictionary<string, object>)Model.HtmlAttributes;
|
||||
|
||||
if (htmlAttributes == null) {
|
||||
htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text small"}
|
||||
};
|
||||
}
|
||||
else {
|
||||
htmlAttributes["class"] = "text small";
|
||||
}
|
||||
|
||||
if (Model.Required == true) {
|
||||
htmlAttributes["required"] = "required";
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
@{
|
||||
var htmlAttributes = new Dictionary<string, object>();
|
||||
|
||||
var htmlAttributes = (Dictionary<string, object>)Model.HtmlAttributes;
|
||||
|
||||
if (htmlAttributes == null) {
|
||||
htmlAttributes = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
if (Model.Required == true) {
|
||||
htmlAttributes["required"] = "required";
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
@{
|
||||
var htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text medium"}
|
||||
};
|
||||
var htmlAttributes = (Dictionary<string, object>)Model.HtmlAttributes;
|
||||
|
||||
if (htmlAttributes == null) {
|
||||
htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", "text medium"}
|
||||
};
|
||||
}
|
||||
else {
|
||||
htmlAttributes["class"] = "text medium";
|
||||
}
|
||||
|
||||
if (Model.Required == true) {
|
||||
htmlAttributes["required"] = "required";
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@{
|
||||
string editorFlavor = Model.EditorFlavor;
|
||||
var htmlAttributes = (Dictionary<string, object>)Model.HtmlAttributes;
|
||||
|
||||
var htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", editorFlavor.HtmlClassify()}
|
||||
};
|
||||
if (htmlAttributes == null) {
|
||||
htmlAttributes = new Dictionary<string, object> {
|
||||
{"class", editorFlavor.HtmlClassify()}};
|
||||
|
||||
}
|
||||
else {
|
||||
htmlAttributes["class"] = editorFlavor.HtmlClassify();
|
||||
}
|
||||
|
||||
if (Model.Required == true) {
|
||||
htmlAttributes["required"] = "required";
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
@Html.ValidationMessageFor(m => m.Settings.Flavor)
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor(m => m.Settings.MaxLength)">@T("Maximum length")</label>
|
||||
@Html.EditorFor(m => m.Settings.MaxLength, new { htmlAttributes = new { min = 0 } })
|
||||
<span class="hint">@T("Maximum length allowed for this field. Setting the value to 0 means unlimited length.")</span>
|
||||
@Html.ValidationMessageFor(m => m.Settings.MaxLength)
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<div>
|
||||
@Html.CheckBoxFor(m => m.Settings.Required) <label for="@Html.FieldIdFor(m => m.Settings.Required)" class="forcheckbox">@T("Required")</label>
|
||||
@@ -21,4 +27,4 @@
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
@Display.DefinitionTemplate(TemplateName: "TextFieldDefaultValueEditor", Model: Model)
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
@model Orchard.Core.Common.ViewModels.TextFieldDriverViewModel
|
||||
@{
|
||||
var maxLength = Model.Settings.MaxLength > 0 ? Model.Settings.MaxLength.ToString() : "";
|
||||
}
|
||||
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor(m => m.Text)" @if(Model.Settings.Required) { <text>class="required"</text> }>@Model.Field.DisplayName</label>
|
||||
<label for="@Html.FieldIdFor(m => m.Text)" @if (Model.Settings.Required) { <text> class="required" </text> }>@Model.Field.DisplayName</label>
|
||||
@if (String.IsNullOrWhiteSpace(Model.Settings.Flavor)) {
|
||||
@(Model.Settings.Required ? Html.TextBoxFor(m => m.Text, new {@class = "text", required = "required"}) : Html.TextBoxFor(m => m.Text, new {@class = "text"}))
|
||||
@(Model.Settings.Required
|
||||
? Html.TextBoxFor(m => m.Text, new {@class = "text", required = "required", maxlength = maxLength})
|
||||
: Html.TextBoxFor(m => m.Text, new {@class = "text", maxlength = maxLength }))
|
||||
@Html.ValidationMessageFor(m => m.Text)
|
||||
}
|
||||
else {
|
||||
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.Settings.Flavor, Required: Model.Settings.Required, ContentItem: Model.ContentItem, Field: Model.Field)
|
||||
|
||||
var htmlAttributes = new Dictionary<string, object> {
|
||||
{"maxlength", maxLength}
|
||||
};
|
||||
|
||||
@Display.Body_Editor(Text: Model.Text, EditorFlavor: Model.Settings.Flavor, Required: Model.Settings.Required,
|
||||
ContentItem: Model.ContentItem, Field: Model.Field, HtmlAttributes: htmlAttributes)
|
||||
}
|
||||
@if (HasText(Model.Settings.Hint)) {
|
||||
<span class="hint">@Model.Settings.Hint</span>
|
||||
<span class="hint">@Model.Settings.Hint</span>
|
||||
}
|
||||
</fieldset>
|
||||
@@ -293,6 +293,8 @@
|
||||
<Compile Include="Title\Migrations.cs" />
|
||||
<Compile Include="Title\Models\TitlePart.cs" />
|
||||
<Compile Include="Title\Models\TitlePartRecord.cs" />
|
||||
<Compile Include="Title\Settings\TitlePartSettings.cs" />
|
||||
<Compile Include="Title\Settings\TitlePartSettingsEvents.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\HomeController.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\LiveWriterController.cs" />
|
||||
<Compile Include="XmlRpc\IXmlRpcDriver.cs" />
|
||||
@@ -612,6 +614,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<Content Include="Title\Views\DefinitionTemplates\TitlePartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Title.Models;
|
||||
using Orchard.Core.Title.Settings;
|
||||
using Orchard.Localization;
|
||||
|
||||
namespace Orchard.Core.Title.Drivers {
|
||||
@@ -33,7 +35,14 @@ namespace Orchard.Core.Title.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(TitlePart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
updater.TryUpdateModel(part, Prefix, null, null);
|
||||
if (updater.TryUpdateModel(part, Prefix, null, null)){
|
||||
|
||||
var settings = part.Settings.GetModel<TitlePartSettings>();
|
||||
|
||||
if (settings.MaxLength > 0 && part.Title.Length > settings.MaxLength) {
|
||||
updater.AddModelError("Title", T("The maximum allowed length for the title is {0}", settings.MaxLength));
|
||||
}
|
||||
}
|
||||
|
||||
return Editor(part, shapeHelper);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Contents.Extensions;
|
||||
using Orchard.Data.Migration;
|
||||
using Orchard.Core.Title.Settings;
|
||||
|
||||
namespace Orchard.Core.Title {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
@@ -9,7 +10,7 @@ namespace Orchard.Core.Title {
|
||||
SchemaBuilder.CreateTable("TitlePartRecord",
|
||||
table => table
|
||||
.ContentPartVersionRecord()
|
||||
.Column<string>("Title", column => column.WithLength(1024))
|
||||
.Column<string>("Title", column => column.WithLength(TitlePartSettings.MaxTitleLength))
|
||||
);
|
||||
|
||||
ContentDefinitionManager.AlterPartDefinition("TitlePart", builder => builder
|
||||
|
||||
19
src/Orchard.Web/Core/Title/Settings/TitlePartSettings.cs
Normal file
19
src/Orchard.Web/Core/Title/Settings/TitlePartSettings.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard.Core.Title.Settings {
|
||||
|
||||
|
||||
public class TitlePartSettings {
|
||||
// Whenever this constant is changed a new migration step must be created to update the length of the field on the DB
|
||||
public const int MaxTitleLength = 1024;
|
||||
[Range(0, MaxTitleLength)]
|
||||
[DisplayName("Maximum Length")]
|
||||
public int MaxLength {get; set;}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Title.Settings {
|
||||
public class TitlePartSettingsEvents : ContentDefinitionEditorEventsBase {
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition) {
|
||||
if (definition.PartDefinition.Name != "TitlePart") {
|
||||
yield break;
|
||||
}
|
||||
|
||||
var settings = definition
|
||||
.Settings
|
||||
.GetModel<TitlePartSettings>()
|
||||
?? new TitlePartSettings();
|
||||
|
||||
yield return DefinitionTemplate(settings);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
|
||||
if (builder.Name != "TitlePart") {
|
||||
yield break;
|
||||
}
|
||||
|
||||
var model = new TitlePartSettings();
|
||||
|
||||
if (updateModel.TryUpdateModel(model, "TitlePartSettings", null, null)) {
|
||||
builder.WithSetting("TitlePartSettings.MaxLength", model.MaxLength.ToString());
|
||||
|
||||
}
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
@using Orchard.Core.Title.Settings;
|
||||
@model TitlePartSettings
|
||||
@{
|
||||
var maxLength = TitlePartSettings.MaxTitleLength;
|
||||
}
|
||||
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor(m => m.MaxLength)">@T("Maximum length")</label>
|
||||
@Html.EditorFor(m => m.MaxLength, new { htmlAttributes = new { min = 0, max = maxLength } })
|
||||
<span class="hint">@T("Maximum length allowed for the title. Setting the value to 0 means the maximum allowed length is {0} characters.", maxLength)</span>
|
||||
@Html.ValidationMessageFor(m => m.MaxLength)
|
||||
</fieldset>
|
||||
@@ -1,7 +1,11 @@
|
||||
@model Orchard.Core.Title.Models.TitlePart
|
||||
@using Orchard.Core.Title.Settings
|
||||
@model Orchard.Core.Title.Models.TitlePart
|
||||
@{
|
||||
var maxLength = Model.Settings.GetModel<TitlePartSettings>().MaxLength > 0 ? Model.Settings.GetModel<TitlePartSettings>().MaxLength.ToString() : "";
|
||||
}
|
||||
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor(m => m.Title)" class="required">@T("Title")</label>
|
||||
@Html.TextBoxFor(m => m.Title, new { @class = "text large", autofocus = "autofocus" })
|
||||
<label for="@Html.FieldIdFor(m => m.Title)" class="required">@T("Title")</label>
|
||||
@Html.TextBoxFor(m => m.Title, new { @class = "text large", autofocus = "autofocus", maxlength = maxLength })
|
||||
<span class="hint">@T("You must provide a title for this content item")</span>
|
||||
</fieldset>
|
||||
|
||||
@@ -4,8 +4,8 @@ using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
using Orchard.Taxonomies.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Taxonomies.Services;
|
||||
|
||||
namespace Orchard.Taxonomies.Settings {
|
||||
public class TaxonomyFieldEditorEvents : ContentDefinitionEditorEventsBase {
|
||||
@@ -20,8 +20,7 @@ namespace Orchard.Taxonomies.Settings {
|
||||
|
||||
public override IEnumerable<TemplateViewModel> PartFieldEditor(ContentPartFieldDefinition definition) {
|
||||
if (definition.FieldDefinition.Name == "TaxonomyField") {
|
||||
var model = definition.Settings.GetModel<TaxonomyFieldSettings>();
|
||||
model.Taxonomies = _taxonomyService.GetTaxonomies();
|
||||
var model = GetCurrentSettings(definition);
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +30,8 @@ namespace Orchard.Taxonomies.Settings {
|
||||
yield break;
|
||||
}
|
||||
|
||||
var model = new TaxonomyFieldSettings();
|
||||
// Init this model preventively so if the TryUpdateModel doesn't execute correctly it doesn't cause an error
|
||||
var model = GetCurrentSettings(builder.Current);
|
||||
|
||||
if (updateModel.TryUpdateModel(model, "TaxonomyFieldSettings", null, null)) {
|
||||
builder
|
||||
@@ -43,8 +43,15 @@ namespace Orchard.Taxonomies.Settings {
|
||||
.WithSetting("TaxonomyFieldSettings.AllowCustomTerms", model.AllowCustomTerms.ToString())
|
||||
.WithSetting("TaxonomyFieldSettings.Hint", model.Hint);
|
||||
}
|
||||
|
||||
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
|
||||
private TaxonomyFieldSettings GetCurrentSettings(ContentPartFieldDefinition definition) {
|
||||
var model = definition.Settings.GetModel<TaxonomyFieldSettings>();
|
||||
model.Taxonomies = _taxonomyService.GetTaxonomies();
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user