2

我知道 Orchard 有内置的 DateTime 字段,我知道我可以通过将 DataTimeFieldPart 添加到我的自定义部分来使用它。但是我的日期时间字段属于“事件部分记录”实体,我希望它们存储在一个表中。我面临的问题是自定义部分的编辑器视图 - 我的 datetime 属性呈现为文本输入,但我希望它呈现像 jquery timepicker 或至少具有 datetime 类型的输入。

是否需要添加所有日期时间属性,如单独的日期时间部分?如我所见,我可以使用日期时间选择器的唯一方法是将其手动添加到编辑器视图中。对我来说这很奇怪,因为 Orchard 在日期时间部分提供了日期时间选择器功能。

我想我错过了一些理想的逻辑问题。

        //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"))
                );

这是我的编辑观点:

    <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>
4

2 回答 2

1

没有必要甚至不可能将所有日期时间属性作为部分添加:给定类型中只有一个部分可以存在于一个类型上。但是,您可以通过字段来完成。

为了在您自己的部件中重现日期字段的 UI,您需要做的是在您自己的部件模板中重现他们使用的模板和脚本。

于 2013-06-19T20:45:47.543 回答
0

实际上可以使用 Orchard 的 DateTime 编辑器(我的 Orchard 版本是 1.10.1),但它需要大量自定义代码。开始了。

  1. EventPartRecord

    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; }
    
      ...
    }
    
  2. EventPart

    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;
        }
    }
    
  3. EventPartDriver

    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;
    }
    
  4. 编辑器视图,Views/EditorTemplates/Parts/Validity.cshtml

    @model EventPart
    
    <fieldset>
      <legend>@T("Event")</legend>
    
      <fieldset>
        <div class="editor-label">
          <label for="@Html.FieldIdFor(m => m.StartDateTimeProxy)">@T(Html.DisplayNameFor(m => m.StartDateTimeProxy).AsString())</label>
        </div>
        <div class="editor-field">
          @Html.EditorFor(m => m.StartDateTimeProxy) @* will render Orchard`s datetime editor, see Orchard.Resources/Views/EditorTemplates/DateTimeEditor *@
          @Html.ValidationMessageFor(m => m.StartDateTimeProxy)
        </div>
      </fieldset>
    </fieldset> 
    
于 2016-06-10T12:48:01.257 回答