Sitecore Custom Time Field

Sitecore features many different fields that can cater to our requirements, sometimes however, we need to customize these fields in order for them to fulfill a specific function.

In the section bellow, I will demonstrate how to create a custom time field based in the DateTime field of Sitecore 8. Please read the steps you should follow in order to add this field, which will prove very helpful if you only need to define the time without a specific date.

The first thing you have to do is create a class similar to that of the DateTime field. You can refer to the code bellow.

namespace Sitecore.Custom.Fields
{
    public class TimeField : Input, IContentField
    {
        private TimePicker _picker;

        public bool IsModified
        {
            get
            {
                return Convert.ToBoolean(base.ServerProperties["IsModified"]);
            }
            protected set
            {
                base.ServerProperties["IsModified"] = value;
            }
        }

        public string ItemID
        {
            get
            {
                return base.GetViewStateString("ItemID");
            }
            set
            {
                Assert.ArgumentNotNull(value, "value");
                base.SetViewStateString("ItemID", value);
            }
        }

        public string RealValue
        {
            get
            {
                return base.GetViewStateString("RealValue");
            }
            set
            {
                Assert.ArgumentNotNull(value, "value");
                base.SetViewStateString("RealValue", DateUtil.IsoDateToServerTimeIsoDate(value));
            }
        }

        public bool ShowTime
        {
            get
            {
                return base.GetViewStateBool("Showtime", false);
            }
            set
            {
                base.SetViewStateBool("Showtime", value);
            }
        }

        public TimeField()
        {
            this.Class = "scContentControl";
            base.Change = "#";
            base.Activation = true;
            this.ShowTime = true;
        }

        private void ClearField()
        {
            this.SetRealValue(string.Empty);
        }

        protected virtual string GetCurrentDate()
        {
            return DateUtil.IsoNow;
        }

        protected override Item GetItem()
        {
            return Client.ContentDatabase.GetItem(this.ItemID);
        }

        public string GetValue()
        {
            string realValue;
            if (this._picker != null)
            {
                var temp = (DateTime.MinValue + DateUtil.ParseTimeSpan((this._picker.Value), TimeSpan.Zero)).ToString("yyyyMMddTHHmmss");
                if (DateUtil.IsoDateToDateTime(temp + "Z") == DateTime.MinValue)
                {
                    return null;
                }
                realValue = temp;
            }
            else
            {
                realValue = this.RealValue;
            }
            return DateUtil.IsoDateToUtcIsoDate(realValue);
        }

        public override void HandleMessage(Message message)
        {
            Assert.ArgumentNotNull(message, "message");
            base.HandleMessage(message);
            if (message["id"] != this.ID)
            {
                return;
            }
            string name = message.Name;
            string str = name;
            if (name != null)
            {
                if (str == "contentdate:today")
                {
                    this.Now();
                    return;
                }
                if (str != "contentdate:clear")
                {
                    return;
                }
                this.ClearField();
            }
        }

        protected override bool LoadPostData(string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                value = DateUtil.IsoDateToServerTimeIsoDate(value);
            }
            if (!base.LoadPostData(value))
            {
                return false;
            }
            this._picker.Value = value ?? string.Empty;
            return true;
        }

        protected override void OnInit(EventArgs e)
        {
            this._picker = new TimePicker()
            {
                ID = string.Concat(this.ID, "_picker")
            };
            this.Controls.Add(this._picker);
            if (!string.IsNullOrEmpty(this.RealValue))
            {
                var temp = DateUtil.IsoDateToDateTime(RealValue);
                this._picker.Value = temp.ToString("t");
            }

            this._picker.OnChanged += new EventHandler((object param0, EventArgs param1) => this.SetModified());
            this._picker.Disabled = this.Disabled;
            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            base.ServerProperties["Value"] = base.ServerProperties["Value"];
            base.ServerProperties["RealValue"] = base.ServerProperties["RealValue"];
        }

        protected override void SetModified()
        {
            base.SetModified();
            this.IsModified = true;
            if (base.TrackModified)
            {
                Sitecore.Context.ClientPage.Modified = true;
            }
        }

        protected void SetRealValue(string realvalue)
        {
            realvalue = DateUtil.IsoDateToServerTimeIsoDate(realvalue);
            var temp = DateUtil.IsoDateToDateTime(realvalue);
            if (realvalue != this.RealValue)
            {
                this.SetModified();
            }
            this.RealValue = realvalue;
            this._picker.Value = temp.ToString("t");
        }

        public void SetValue(string value)
        {
            Assert.ArgumentNotNull(value, "value");
            value = DateUtil.IsoDateToServerTimeIsoDate(value);
            var temp = DateUtil.IsoDateToDateTime(value);
            this.RealValue = value;
            if (this._picker != null)
            {
                this._picker.Value = temp.ToString("t");
            }
        }

        private void Now()
        {
            this.SetRealValue(this.GetCurrentDate());
        }
    }


Once you have created the class you have to add it to the Sitecore fields. In order to do this you must select the Core database.

In the Content Editor navigate to Sitecore/System/Field Types and create a new folder naming it “Custom Types” (this will allow you to differentiate it from the rest). Inside that folder, create a new item with the template: /sitecore/templates/System/Templates/Template field type. You can duplicate it from the item Date, located in /Simple Types. Rename the item as Time, and you can select an icon.

Add the name of your library (your dll file), for example Sitecore.Custom, in the field Assembly. And in your field Class, insert the name of your class including the namespace, for example Sitecore.Custom.Fields.TiemField.

Expand your new item Time and make sure that you have a folder named Menu containing two items (from template “/sitecore/templates/System/Menus/Menu item”): Nowand Clear. If you duplicated from the field Date, you should be seeing an item named Today. Rename this item as Now.

Delete the folder WebEdit buttons. This is usless in Preview/Edit mode and we won’t need it for the Time field.

TimeFieldCoreDatabase
Sitecore Custom Field: how it should look like

Finally, save the item. It should now be available in the list of fields.

TimeField

If you view the field in Raw mode, you will notice that it stores in the exact same format in which it saves the datetime. The only difference is that the date will have the value of DateTime.MinValue.

Feel free to take the code and utilize it in your project!

Happy Sitecoring!

2 thoughts on “Sitecore Custom Time Field

Leave a comment