Asp.net mvc 3 如何在Orchard编辑器中为datetime字段使用DateTimePicker控件(不添加datetimefieldpart)?
我知道Orchard中内置了DateTime字段,我知道可以通过将DataTimeFieldPart添加到我的自定义部分来使用它。 但我的datetime字段属于“事件部分记录”实体,我希望它们存储在一个表中。 我面临的问题是自定义部件的编辑器视图-我的datetime属性呈现为文本输入,但我希望它至少呈现为jquery timepicker或datetime类型的输入 是否有必要添加所有datetime属性,如单独的datetime部分? 如我所见,使用datetime选择器的唯一方法是手动将其添加到编辑器视图。对我来说这很奇怪,因为Orchard在datetime部分提供了datetime选择器功能 我想我错过了一些思想上的共识Asp.net mvc 3 如何在Orchard编辑器中为datetime字段使用DateTimePicker控件(不添加datetimefieldpart)?,asp.net-mvc-3,razor,editor,orchardcms,datetimepicker,Asp.net Mvc 3,Razor,Editor,Orchardcms,Datetimepicker,我知道Orchard中内置了DateTime字段,我知道可以通过将DataTimeFieldPart添加到我的自定义部分来使用它。 但我的datetime字段属于“事件部分记录”实体,我希望它们存储在一个表中。 我面临的问题是自定义部件的编辑器视图-我的datetime属性呈现为文本输入,但我希望它至少呈现为jquery timepicker或datetime类型的输入 是否有必要添加所有datetime属性,如单独的datetime部分? 如我所见,使用datetime选择器的唯一方法是手动将
//Event Type
SchemaBuilder.CreateTable("EventPartRecord",
table => table
.ContentPartRecord()
.Column<string>("Name")
.Column<DateTime>("StartDateTime")
.Column<DateTime>("PlanedEndDateTime", c=>c.Nullable())
.Column<DateTime>("EndDateTime", c => c.Nullable())
.Column<string>("EventRules")
.Column<string>("Comment")
.Column<bool>("IsFinished")
.Column<int>("CompetitionPartRecord_Id")
);
ContentDefinitionManager.AlterPartDefinition("EventPart",
builder => builder.Attachable()
.WithField("Competitors",f => f
.OfType("ContentPickerField")
.WithSetting("Multiple","true"))
);
//事件类型
SchemaBuilder.CreateTable(“EventPartRecord”,
表=>表
.ContentPartRecord()
.栏(“名称”)
.列(“StartDateTime”)
.Column(“PlanedEndDateTime”,c=>c.Nullable())
.Column(“EndDateTime”,c=>c.Nullable())
.栏(“事件规则”)
.栏(“评论”)
.列(“已完成”)
.栏(“竞争部分记录\u Id”)
);
ContentDefinitionManager.AlterPartDefinition(“EventPart”,
builder=>builder.Attachable()
.WithField(“竞争对手”,f=>f
.of类型(“ContentPickerField”)
.使用(“多重”、“真实”))
);
以下是我的看法:
<div class="editor-label">
@Html.LabelFor(model => model.PlanedEndDateTime)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.PlanedEndDateTime)
@Html.ValidationMessageFor(model => model.PlanedEndDateTime)
</div>
@LabelFor(model=>model.PlanedEndDateTime)
@EditorFor(model=>model.PlanedEndDateTime)
@Html.ValidationMessageFor(model=>model.PlanedEndDateTime)
不需要甚至不可能将所有datetime属性添加为部分:一个类型上只能存在给定类型的一个部分。不过,您可以通过字段来完成
要在您自己的部件中重现日期字段的UI,您需要做的是在您自己的部件模板中重现它们使用的模板和脚本。使用Orchard的DateTime编辑器实际上是可能的(我的Orchard版本是1.10.1),但它需要大量自定义代码。我们开始吧
public class EventPartRecord : Orchard.ContentManagement.Records.ContentPartRecord
{
// DateTime value as UTC to use Orchard convention (see CommonPart table) and to be compatible with projections
// (date/time tokens work with UTC values, see https://github.com/OrchardCMS/Orchard/issues/6963 for a related issue)
public virtual System.DateTime? StartDateTimeUtc { get; set; }
...
}
public class EventPart : Orchard.ContentManagement.ContentPart<EventPartRecord>
{
// public
public System.DateTime? StartDateTimeUtc
{
get { return Retrieve(r => r.StartDateTimeUtc); }
set { Store(r => r.StartDateTimeUtc, value); }
}
public System.DateTime StartDateTime
{
get
{
var v = ValidFromUtc;
if (v.HasValue)
return DateLocalizationServices.ConvertToSiteTimeZone(v.Value);
else
return null;
}
}
// This property is needed to render Orchard`s date time editor correctly
[System.ComponentModel.DataAnnotations.Display(Name="Start date time")]
public Orchard.Core.Common.ViewModels.DateTimeEditor StartDateTimeProxy
{
get
{
var v = StartDateTime;
var lDateLocalizationOptions = new Orchard.Localization.Models.DateLocalizationOptions {EnableCalendarConversion = false, EnableTimeZoneConversion = false};
return new Orchard.Core.Common.ViewModels.DateTimeEditor {ShowDate = true, ShowTime = true,
Date = v.HasValue ? DateLocalizationServices.ConvertToLocalizedDateString(v.Value, lDateLocalizationOptions) : "",
Time = v.HasValue ? DateLocalizationServices.ConvertToLocalizedTimeString(v.Value, lDateLocalizationOptions) : ""};
}
set
{
ValidFromUtc = CreateActualPropertyValue(value, "ValidFromProxy");
}
}
...
public Orchard.Localization.Localizer T { get; set; }
public Orchard.ContentManagement.IUpdateModel Updater { get; set; }
public Orchard.Localization.Services.IDateLocalizationServices DateLocalizationServices { get; set; }
// private
private System.DateTime? CreateActualPropertyValue(Orchard.Core.Common.ViewModels.DateTimeEditor aProxyPropertyValue, string aProxyPropertyName)
{
System.DateTime? v = null;
// the following date/time handling is based on Orchard.Fields.Drivers.DateTimeFieldDriver
bool lHasDate = !string.IsNullOrEmpty(aProxyPropertyValue.Date);
bool lHasTime = !string.IsNullOrEmpty(aProxyPropertyValue.Time);
var lPropertyName = T(this.GetPropertyAttribute<System.ComponentModel.DataAnnotations.DisplayAttribute>(aProxyPropertyName).Name);
if (lHasDate && lHasTime)
{
try
{
v = DateLocalizationServices.ConvertFromLocalizedString(aProxyPropertyValue.Date, aProxyPropertyValue.Time,
new Orchard.Localization.Models.DateLocalizationOptions {EnableTimeZoneConversion = true});
}
catch
{
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} could not be parsed as a valid date and time.", lPropertyName));
}
}
else
{
if (!lHasDate && lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a date.", lPropertyName));
else
if (lHasDate && !lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a time.", lPropertyName));
else
{
// consider both fields empty as "no date time selection",
// if property should be required add [System.ComponentModel.DataAnnotations.Required] to actual property as strangely adding it to proxy property does not work
}
}
return v;
}
}
public class EventPartDriver : Orchard.ContentManagement.Drivers.ContentPartDriver<EventPart>
{
// public
public ValidityPartDriver(Orchard.Localization.Services.IDateLocalizationServices aDateLocalizationServices)
{
T = Orchard.Localization.NullLocalizer.Instance;
mDateLocalizationServices = aDateLocalizationServices;
}
public Orchard.Localization.Localizer T { get; set; }
// protected
// GET
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart, dynamic aShapeHelper)
{
// first, set properties which are required by the code that returns part property values for the view
aPart.DateLocalizationServices = mDateLocalizationServices;
return ContentShape("Parts_Event_Edit", () => aShapeHelper.EditorTemplate(TemplateName: "Parts/Event", Model: aPart, Prefix: Prefix));
}
// POST
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart,
Orchard.ContentManagement.IUpdateModel aUpdater, dynamic aShapeHelper)
{
// first, set properties which are required by the code that handles part property updates executed by aUpdater.TryUpdateModel()
aPart.T = T;
aPart.Updater = aUpdater;
aPart.DateLocalizationServices = mDateLocalizationServices;
aUpdater.TryUpdateModel(aPart, Prefix, null, null);
return Editor(aPart, aShapeHelper);
}
// private
private Orchard.Localization.Services.IDateLocalizationServices mDateLocalizationServices;
}
public class EventPartRecord : Orchard.ContentManagement.Records.ContentPartRecord
{
// DateTime value as UTC to use Orchard convention (see CommonPart table) and to be compatible with projections
// (date/time tokens work with UTC values, see https://github.com/OrchardCMS/Orchard/issues/6963 for a related issue)
public virtual System.DateTime? StartDateTimeUtc { get; set; }
...
}
public class EventPart : Orchard.ContentManagement.ContentPart<EventPartRecord>
{
// public
public System.DateTime? StartDateTimeUtc
{
get { return Retrieve(r => r.StartDateTimeUtc); }
set { Store(r => r.StartDateTimeUtc, value); }
}
public System.DateTime StartDateTime
{
get
{
var v = ValidFromUtc;
if (v.HasValue)
return DateLocalizationServices.ConvertToSiteTimeZone(v.Value);
else
return null;
}
}
// This property is needed to render Orchard`s date time editor correctly
[System.ComponentModel.DataAnnotations.Display(Name="Start date time")]
public Orchard.Core.Common.ViewModels.DateTimeEditor StartDateTimeProxy
{
get
{
var v = StartDateTime;
var lDateLocalizationOptions = new Orchard.Localization.Models.DateLocalizationOptions {EnableCalendarConversion = false, EnableTimeZoneConversion = false};
return new Orchard.Core.Common.ViewModels.DateTimeEditor {ShowDate = true, ShowTime = true,
Date = v.HasValue ? DateLocalizationServices.ConvertToLocalizedDateString(v.Value, lDateLocalizationOptions) : "",
Time = v.HasValue ? DateLocalizationServices.ConvertToLocalizedTimeString(v.Value, lDateLocalizationOptions) : ""};
}
set
{
ValidFromUtc = CreateActualPropertyValue(value, "ValidFromProxy");
}
}
...
public Orchard.Localization.Localizer T { get; set; }
public Orchard.ContentManagement.IUpdateModel Updater { get; set; }
public Orchard.Localization.Services.IDateLocalizationServices DateLocalizationServices { get; set; }
// private
private System.DateTime? CreateActualPropertyValue(Orchard.Core.Common.ViewModels.DateTimeEditor aProxyPropertyValue, string aProxyPropertyName)
{
System.DateTime? v = null;
// the following date/time handling is based on Orchard.Fields.Drivers.DateTimeFieldDriver
bool lHasDate = !string.IsNullOrEmpty(aProxyPropertyValue.Date);
bool lHasTime = !string.IsNullOrEmpty(aProxyPropertyValue.Time);
var lPropertyName = T(this.GetPropertyAttribute<System.ComponentModel.DataAnnotations.DisplayAttribute>(aProxyPropertyName).Name);
if (lHasDate && lHasTime)
{
try
{
v = DateLocalizationServices.ConvertFromLocalizedString(aProxyPropertyValue.Date, aProxyPropertyValue.Time,
new Orchard.Localization.Models.DateLocalizationOptions {EnableTimeZoneConversion = true});
}
catch
{
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} could not be parsed as a valid date and time.", lPropertyName));
}
}
else
{
if (!lHasDate && lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a date.", lPropertyName));
else
if (lHasDate && !lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a time.", lPropertyName));
else
{
// consider both fields empty as "no date time selection",
// if property should be required add [System.ComponentModel.DataAnnotations.Required] to actual property as strangely adding it to proxy property does not work
}
}
return v;
}
}
public class EventPartDriver : Orchard.ContentManagement.Drivers.ContentPartDriver<EventPart>
{
// public
public ValidityPartDriver(Orchard.Localization.Services.IDateLocalizationServices aDateLocalizationServices)
{
T = Orchard.Localization.NullLocalizer.Instance;
mDateLocalizationServices = aDateLocalizationServices;
}
public Orchard.Localization.Localizer T { get; set; }
// protected
// GET
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart, dynamic aShapeHelper)
{
// first, set properties which are required by the code that returns part property values for the view
aPart.DateLocalizationServices = mDateLocalizationServices;
return ContentShape("Parts_Event_Edit", () => aShapeHelper.EditorTemplate(TemplateName: "Parts/Event", Model: aPart, Prefix: Prefix));
}
// POST
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart,
Orchard.ContentManagement.IUpdateModel aUpdater, dynamic aShapeHelper)
{
// first, set properties which are required by the code that handles part property updates executed by aUpdater.TryUpdateModel()
aPart.T = T;
aPart.Updater = aUpdater;
aPart.DateLocalizationServices = mDateLocalizationServices;
aUpdater.TryUpdateModel(aPart, Prefix, null, null);
return Editor(aPart, aShapeHelper);
}
// private
private Orchard.Localization.Services.IDateLocalizationServices mDateLocalizationServices;
}
公共类事件部分:Orchard.ContentManagement.ContentPart
{
//公开的
public System.DateTime?StartDateTimeUtc
{
获取{return Retrieve(r=>r.StartDateTimeUtc);}
设置{Store(r=>r.StartDateTimeUtc,value);}
}
public System.DateTime StartDateTime
{
得到
{
var v=有效的UTC;
如果(v.HasValue)
return DateLocalizationServices.ConvertToSiteTimeZone(v.Value);
其他的
返回null;
}
}
//正确呈现Orchard的日期时间编辑器需要此属性
[System.ComponentModel.DataAnnotations.Display(Name=“开始日期时间”)]
public Orchard.Core.Common.ViewModels.DateTimeEditor StartDateTimeProxy
{
得到
{
var v=起始日期时间;
var lDateLocalizationOptions=new Orchard.Localization.Models.DateLocalizationOptions{EnableCalendarConversion=false,EnableTimeZoneConversion=false};
返回新的Orchard.Core.Common.ViewModels.DateTimeEditor{ShowDate=true,ShowTime=true,
Date=v.HasValue?DateLocalizationServices.ConvertToLocalizedDataTestRing(v.Value,lDateLocalizationOptions):“”,
Time=v.HasValue?DateLocalizationServices.ConvertToLocalizedTimeString(v.Value,lDateLocalizationOptions):“”;
}
设置
{
ValidFromUtc=CreateActualPropertyValue(值,“ValidFromProxy”);
}
}
...
public Orchard.Localization.Localizer T{get;set;}
public Orchard.ContentManagement.IUpdateModel更新程序{get;set;}
public Orchard.Localization.Services.IDateLocalizationServices日期本地化服务{get;set;}
//私人的
private System.DateTime?CreateActualPropertyValue(Orchard.Core.Common.ViewModels.DateTimeEditor aProxyPropertyValue,字符串aProxyPropertyName)
{
System.DateTime?v=null;
//以下日期/时间处理基于Orchard.Fields.Drivers.DateTimeFieldDriver
bool lHasDate=!string.IsNullOrEmpty(aProxyPropertyValue.Date);
bool lHasTime=!string.IsNullOrEmpty(aProxyPropertyValue.Time);
var lPropertyName=T(this.GetPropertyAttribute(aProxyPropertyName).Name);
if(拉斯代特和拉斯代姆)
{
尝试
{
v=DateLocalizationServices.ConvertFromLocalizedString(aProxyPropertyValue.Date,aProxyPropertyValue.Time,
新的Orchard.Localization.Models.DateLocalizationOptions{EnableTimeZoneConversion=true});
}
抓住
{
Updater.AddModelError(PartDefinition.Name+“+aProxyPropertyName,T(“{0}无法解析为有效的日期和时间。”,lPropertyName));
}
}
其他的
{
如果(!lHasDate&&lHasTime)
AddModelError(PartDefinition.Name+“+aProxyPropertyName,T(“{0}需要一个日期。”,lPropertyName));
其他的
if(lHasDate&!lHasTime)
AddModelError(PartDefinition.Name+“+aProxyPropertyName,T(“{0}需要一个时间。”,lPropertyName));
其他的
{
/将两个字段视为“无日期时间选择”,
//如果属性是必需的,则将[System.ComponentModel.DataAnnotations.required]添加到实际属性,因为奇怪的是,将其添加到代理属性并不起作用
}
}
返回v;
}
}
public class EventPartRecord : Orchard.ContentManagement.Records.ContentPartRecord
{
// DateTime value as UTC to use Orchard convention (see CommonPart table) and to be compatible with projections
// (date/time tokens work with UTC values, see https://github.com/OrchardCMS/Orchard/issues/6963 for a related issue)
public virtual System.DateTime? StartDateTimeUtc { get; set; }
...
}
public class EventPart : Orchard.ContentManagement.ContentPart<EventPartRecord>
{
// public
public System.DateTime? StartDateTimeUtc
{
get { return Retrieve(r => r.StartDateTimeUtc); }
set { Store(r => r.StartDateTimeUtc, value); }
}
public System.DateTime StartDateTime
{
get
{
var v = ValidFromUtc;
if (v.HasValue)
return DateLocalizationServices.ConvertToSiteTimeZone(v.Value);
else
return null;
}
}
// This property is needed to render Orchard`s date time editor correctly
[System.ComponentModel.DataAnnotations.Display(Name="Start date time")]
public Orchard.Core.Common.ViewModels.DateTimeEditor StartDateTimeProxy
{
get
{
var v = StartDateTime;
var lDateLocalizationOptions = new Orchard.Localization.Models.DateLocalizationOptions {EnableCalendarConversion = false, EnableTimeZoneConversion = false};
return new Orchard.Core.Common.ViewModels.DateTimeEditor {ShowDate = true, ShowTime = true,
Date = v.HasValue ? DateLocalizationServices.ConvertToLocalizedDateString(v.Value, lDateLocalizationOptions) : "",
Time = v.HasValue ? DateLocalizationServices.ConvertToLocalizedTimeString(v.Value, lDateLocalizationOptions) : ""};
}
set
{
ValidFromUtc = CreateActualPropertyValue(value, "ValidFromProxy");
}
}
...
public Orchard.Localization.Localizer T { get; set; }
public Orchard.ContentManagement.IUpdateModel Updater { get; set; }
public Orchard.Localization.Services.IDateLocalizationServices DateLocalizationServices { get; set; }
// private
private System.DateTime? CreateActualPropertyValue(Orchard.Core.Common.ViewModels.DateTimeEditor aProxyPropertyValue, string aProxyPropertyName)
{
System.DateTime? v = null;
// the following date/time handling is based on Orchard.Fields.Drivers.DateTimeFieldDriver
bool lHasDate = !string.IsNullOrEmpty(aProxyPropertyValue.Date);
bool lHasTime = !string.IsNullOrEmpty(aProxyPropertyValue.Time);
var lPropertyName = T(this.GetPropertyAttribute<System.ComponentModel.DataAnnotations.DisplayAttribute>(aProxyPropertyName).Name);
if (lHasDate && lHasTime)
{
try
{
v = DateLocalizationServices.ConvertFromLocalizedString(aProxyPropertyValue.Date, aProxyPropertyValue.Time,
new Orchard.Localization.Models.DateLocalizationOptions {EnableTimeZoneConversion = true});
}
catch
{
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} could not be parsed as a valid date and time.", lPropertyName));
}
}
else
{
if (!lHasDate && lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a date.", lPropertyName));
else
if (lHasDate && !lHasTime)
Updater.AddModelError(PartDefinition.Name + "." + aProxyPropertyName, T("{0} requires a time.", lPropertyName));
else
{
// consider both fields empty as "no date time selection",
// if property should be required add [System.ComponentModel.DataAnnotations.Required] to actual property as strangely adding it to proxy property does not work
}
}
return v;
}
}
public class EventPartDriver : Orchard.ContentManagement.Drivers.ContentPartDriver<EventPart>
{
// public
public ValidityPartDriver(Orchard.Localization.Services.IDateLocalizationServices aDateLocalizationServices)
{
T = Orchard.Localization.NullLocalizer.Instance;
mDateLocalizationServices = aDateLocalizationServices;
}
public Orchard.Localization.Localizer T { get; set; }
// protected
// GET
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart, dynamic aShapeHelper)
{
// first, set properties which are required by the code that returns part property values for the view
aPart.DateLocalizationServices = mDateLocalizationServices;
return ContentShape("Parts_Event_Edit", () => aShapeHelper.EditorTemplate(TemplateName: "Parts/Event", Model: aPart, Prefix: Prefix));
}
// POST
protected override Orchard.ContentManagement.Drivers.DriverResult Editor(EventPart aPart,
Orchard.ContentManagement.IUpdateModel aUpdater, dynamic aShapeHelper)
{
// first, set properties which are required by the code that handles part property updates executed by aUpdater.TryUpdateModel()
aPart.T = T;
aPart.Updater = aUpdater;
aPart.DateLocalizationServices = mDateLocalizationServices;
aUpdater.TryUpdateModel(aPart, Prefix, null, null);
return Editor(aPart, aShapeHelper);
}
// private
private Orchard.Localization.Services.IDateLocalizationServices mDateLocalizationServices;
}
公共类EventPartDriver:Orchard.ContentManagement.Drivers.ContentPartDriver
{
//公开的
公共ValidityPartDriver(Orchard.本地化.S