2

I have a custom field with two menu items, of which one of them opens a (sheer) dialog. But I need the value from other fields of the item in my dialog. However, I cannot find any reference to the original item. There is only some reference FIELD123456, which I cannot connect to an item or field.

Anyone a clue?

Edit:

This is the code of custom Field Type

using SC = Sitecore;
using SC_Diagnostics = Sitecore.Diagnostics;
using SC_Web = Sitecore.Web;
using SC_Shell_Applications_ContentEditor = Sitecore.Shell.Applications.ContentEditor;

namespace My.Feature.ImageCropper.FieldTypes
{
    using System.Diagnostics.CodeAnalysis;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    [ExcludeFromCodeCoverage]
    public class ImageCropperField : SC_Shell_Shell_Applications_ContentEditor.Text,
        SC_Shell_Applications_ContentEditor.IContentField
    {
        protected override void Render(HtmlTextWriter output)
        {
            //cannot find any reference to item in base  :-((

            SC_Diagnostics.Assert.ArgumentNotNull(output, nameof(output));
            base.Render(output);
        }

        public string GetValue() {return Value; }
        public void SetValue(string value) { Value = value; } 

        public override void HandleMessage(SC_Web.UI.Sheer.Message message)
        {
            //cannot find any reference to item in this or message :-((

            if (message["id"] != ID || string.IsNullOrWhiteSpace(message.Name))
                return;

            switch (message.Name)
            {
                case "imagecropper:cropImage":                    
                    SC.Context.ClientPage.Start(this, "CropImage");
                    return;
                case "imagecropper:resetImage":
                    SC.Context.ClientPage.Start(this, "ResetImage");
                    return;
            }

            if (Value.Length > 0) 
                SetModified();

            Value = string.Empty;
        }

        protected void CropImage(SC_Web.UI.Sheer.ClientPipelineArgs args)
        {
            //cannot find any reference to item in this or args  :-((

            if (args.IsPostBack)
            {
                if (args.HasResult && Value.Equals(args.Result) == false)
                {
                    SetModified();
                    SetValue(args.Result);
                }
            }
            else
            {
                //show popup
                var url = SC.UIUtil.GetUri("control:ImageCropperDialog");

                var value = GetValue();
                if (!string.IsNullOrEmpty(value))
                {
                    url = $"{url}&{value}";
                }

                SC_Web.UI.Sheer.SheerResponse.ShowModalDialog(url, "800", "600", "", true, "800", "600", false);
                args.WaitForPostBack();
            }
        }

        protected void ResetImage(SC_Web.UI.Sheer.ClientPipelineArgs args)
        {
            SetValue(string.Empty);
            SetModified();
        }
    }
}

As you can see, the field inherits from Text and IContentField. All properties and methods are returning values to the control itself, the Home item (based on query string) or the Content Manager item in the core database (which is the context. I tried them all including:

this.GetContentItemFromQueryString() 
this.GetContextItem();
this.GetItem();
this.GetItemFromQueryString();
this.TemplateControl.ID;
this.UniqueID;

The this.ItemId property is not present.

So.... is there another way to get the ID of the item where this field is used in?

  • if you are inheriting your custom field from BucketList or MultilistEx you can have context item Id from this.ItemID. what is your custom field inheriting from? – Dheeraj Palagiri Dec 7 '16 at 14:48
  • I am a little confuse. Is it possible to provide screenshots or code snippets if you have? – Hishaam Namooya Dec 7 '16 at 17:50
3

"Magic" ;-)

Declare a public property; public string ItemID { get; set;}. Sitecore will populate this property by Reflection. You can then do normal .GetItem() operations.

Caveat

If multiple fields are currently being edited on the item in the Content Editor and those changes have not been saved yet - you won't see them.

Reference: https://stackoverflow.com/questions/8148279/how-to-get-a-reference-to-the-currently-edited-item-when-inside-a-custom-field-i

  • Thanks Mark! I added an answer myself also to explain how to pass the values to the dialog. – Erwin Rijss Dec 8 '16 at 14:08
2

Using the "Magic" Mark mentioned it works. However, to get the ItemId and the Source into the dialog, use the last answer as described in this article: https://stackoverflow.com/questions/8148279/how-to-get-a-reference-to-the-currently-edited-item-when-inside-a-custom-field-i.

The full class looks now like this:

using Sitecore.Diagnostics;
using Sitecore.Shell.Applications.ContentEditor;

namespace My.Feature.ImageCropper.FieldTypes
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Web.UI;

    [ExcludeFromCodeCoverage]
    public class ImageCropperField : Text, IContentField
    {
        #region Reflection
        public string ItemId
        {
            get
            {
                return base.GetViewStateString("ItemId");
            }
            set
            {
                Assert.ArgumentNotNullOrEmpty(value, "value");
                base.SetViewStateString("ItemId", value);
            }
        }
        public string Source
        {
            get
            {
                return base.GetViewStateString("Source");
            }
            set
            {
                Assert.ArgumentNotNullOrEmpty(value, "value");
                base.SetViewStateString("Source", value);
            }
        }
        #endregion

        #region IContentfield implementation
        public string GetValue() { return Value; }
        public void SetValue(string value) { Value = value; }
        #endregion

        #region Text base class overrides
        protected override void Render(HtmlTextWriter output)
        {
            Assert.ArgumentNotNull(output, nameof(output));
            base.Render(output);
        }
        #endregion

        #region Message handler
        public override void HandleMessage(Sitecore.Web.UI.Sheer.Message message)
        {
            if (message["id"] != ID || string.IsNullOrWhiteSpace(message.Name))
                return;

            switch (message.Name)
            {
                case "imagecropper:cropImage":                    
                    Sitecore.Context.ClientPage.Start(this, "CropImage");
                    return;
                case "imagecropper:resetImage":
                    Sitecore.Context.ClientPage.Start(this, "ResetImage");
                    return;
            }

            if (Value.Length > 0)
                SetModified();

            Value = string.Empty;
        }

        protected void CropImage(Sitecore.Web.UI.Sheer.ClientPipelineArgs args)
        {
            if (args.IsPostBack)
            {
                if (args.HasResult && Value.Equals(args.Result) == false)
                {
                    SetModified();
                    SetValue(args.Result);
                }
            }
            else
            {
                string url = Sitecore.UIUtil.GetUri("control:ImageCropperDialog");
                string v = GetValue();
                string i = this.ItemId;
                string s = this.Source;

                if (!string.IsNullOrEmpty(i))
                {
                    url = $"{url}&itemid={i}&{s}&{v}";

                    if (!string.IsNullOrEmpty(s))
                    {
                        url = $"{url}&{s}";
                        if (!string.IsNullOrEmpty(v))
                        {
                            url = $"{url}&{v}";
                        }

                        Sitecore.Web.UI.Sheer.SheerResponse.ShowModalDialog(url, "800", "600", "", true, "800", "600", false);
                        args.WaitForPostBack();
                    }
                    else
                    {
                        Sitecore.Web.UI.Sheer.SheerResponse.Alert("The options for cropping the image are not set properly");
                    }
                }
                else
                {
                    Sitecore.Web.UI.Sheer.SheerResponse.Alert("A reference to the item could not be set");
                }
            }
        }

        protected void ResetImage(Sitecore.Web.UI.Sheer.ClientPipelineArgs args)
        {
            SetValue(string.Empty);
            SetModified();
        }
        #endregion
    }
}
  • 1
    If you decide to mark your own answer as accepted, at least consider upvoting the other answer that was the basis of your solution. Also, your code sample may not be useful to others as a whole. I recommend that you try to reduce it to a minimal amount of code required to demonstrate the solution. – Dmytro Shevchenko Dec 9 '16 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.