#18866: Applying current culture when editing and displaying NumericField

The editor has been substituted to type="text" as chrome forces the user
to use '.' as a decimal separator, and other cultures as french could use ','
for instance.

Work Item: 18866

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2012-09-21 16:46:18 -07:00
parent aff19cb1dd
commit 138f9a204e
5 changed files with 55 additions and 13 deletions

View File

@@ -6,15 +6,19 @@ using Orchard.ContentManagement.Handlers;
using Orchard.Fields.Fields;
using Orchard.Fields.Settings;
using Orchard.Localization;
using Orchard.Fields.ViewModels;
namespace Orchard.Fields.Drivers {
public class NumericFieldDriver : ContentFieldDriver<NumericField> {
public IOrchardServices Services { get; set; }
private const string TemplateName = "Fields/Numeric.Edit";
private readonly Lazy<CultureInfo> _cultureInfo;
public NumericFieldDriver(IOrchardServices services) {
Services = services;
T = NullLocalizer.Instance;
_cultureInfo = new Lazy<CultureInfo>(() => CultureInfo.GetCultureInfo(Services.WorkContext.CurrentCulture));
}
public Localizer T { get; set; }
@@ -29,24 +33,49 @@ namespace Orchard.Fields.Drivers {
protected override DriverResult Display(ContentPart part, NumericField field, string displayType, dynamic shapeHelper) {
return ContentShape("Fields_Numeric", GetDifferentiator(field, part), () => {
var settings = field.PartFieldDefinition.Settings.GetModel<NumericFieldSettings>();
return shapeHelper.Fields_Numeric().Settings(settings);
return shapeHelper.Fields_Numeric()
.Settings(field.PartFieldDefinition.Settings.GetModel<NumericFieldSettings>())
.Value(Convert.ToString(field.Value, _cultureInfo.Value));
});
}
protected override DriverResult Editor(ContentPart part, NumericField field, dynamic shapeHelper) {
return ContentShape("Fields_Numeric_Edit", GetDifferentiator(field, part),
() => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part)));
() => {
var model = new NumericFieldViewModel {
Field = field,
Settings = field.PartFieldDefinition.Settings.GetModel<NumericFieldSettings>(),
Value = Convert.ToString(field.Value, _cultureInfo.Value)
};
return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: model, Prefix: GetPrefix(field, part));
});
}
protected override DriverResult Editor(ContentPart part, NumericField field, IUpdateModel updater, dynamic shapeHelper) {
if (updater.TryUpdateModel(field, GetPrefix(field, part), null, null)) {
var viewModel = new NumericFieldViewModel();
if (updater.TryUpdateModel(viewModel, GetPrefix(field, part), null, null)) {
Decimal value;
var settings = field.PartFieldDefinition.Settings.GetModel<NumericFieldSettings>();
if (settings.Required && !field.Value.HasValue) {
if (settings.Required && String.IsNullOrWhiteSpace(viewModel.Value)) {
updater.AddModelError(GetPrefix(field, part), T("The field {0} is mandatory.", T(field.DisplayName)));
}
if (!settings.Required && String.IsNullOrWhiteSpace(viewModel.Value)) {
field.Value = null;
}
else if (Decimal.TryParse(viewModel.Value, NumberStyles.Any, _cultureInfo.Value, out value)) {
field.Value = value;
}
else {
updater.AddModelError(GetPrefix(field, part), T("{0} is an invalid number", field.DisplayName));
field.Value = null;
}
if (settings.Minimum.HasValue && field.Value.HasValue && field.Value.Value < settings.Minimum.Value) {
updater.AddModelError(GetPrefix(field, part), T("The value must be greater than {0}", settings.Minimum.Value));
}

View File

@@ -21,6 +21,10 @@
</UpgradeBackupLocation>
<TargetFrameworkProfile />
<UseIISExpress>false</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -138,6 +142,7 @@
<Compile Include="Settings\EnumerationFieldEditorEvents.cs" />
<Compile Include="Settings\EnumerationFieldSettings.cs" />
<Compile Include="Tokens\FieldTokens.cs" />
<Compile Include="ViewModels\NumericFieldViewModel.cs" />
<Compile Include="ViewModels\DateTimeFieldViewModel.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,10 @@
using Orchard.Fields.Fields;
using Orchard.Fields.Settings;
namespace Orchard.Fields.ViewModels {
public class NumericFieldViewModel {
public NumericField Field { get; set; }
public NumericFieldSettings Settings { get; set; }
public string Value { get; set; }
}
}

View File

@@ -1,12 +1,10 @@
@model Orchard.Fields.Fields.NumericField
@model Orchard.Fields.ViewModels.NumericFieldViewModel
@using System.Globalization
@using Orchard.Fields.Settings;
@{
var settings = Model.PartFieldDefinition.Settings.GetModel<NumericFieldSettings>();
}
<fieldset>
<label for="@Html.FieldIdFor(m => m.Value)" @if(settings.Required) { <text>class="required"</text> }>@Model.DisplayName</label>
@Html.TextBoxFor(m => m.Value, new { @class = "text-small", type = "number", min = (settings.Minimum.HasValue) ? settings.Minimum.Value : 0, max = (settings.Maximum.HasValue) ? settings.Maximum.Value : 1000000, step = Math.Pow(10, 0 - settings.Scale).ToString(CultureInfo.InvariantCulture) })
<label for="@Html.FieldIdFor(m => m.Value)" @if(Model.Settings.Required) { <text>class="required"</text> }>@Model.Field.DisplayName</label>
@Html.TextBoxFor(m => m.Value, new { @class = "text-small", type = "text", min = (Model.Settings.Minimum.HasValue) ? Model.Settings.Minimum.Value : 0, max = (Model.Settings.Maximum.HasValue) ? Model.Settings.Maximum.Value : 1000000, step = Math.Pow(10, 0 - Model.Settings.Scale).ToString(CultureInfo.InvariantCulture) })
@Html.ValidationMessageFor(m => m.Value)
<span class="hint">@settings.Hint</span>
<span class="hint">@Model.Settings.Hint</span>
</fieldset>

View File

@@ -7,6 +7,6 @@
@if (number.HasValue) {
<p class="numeric-field numeric-field-@name.HtmlClassify()">
<span class="name">@name:</span>
<span class="value">@(number.Value)</span>
<span class="value">@(Model.Value)</span>
</p>
}