+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Image Selector on Custom Controls

Image Selector on Custom Controls

26 posts, 1 answered
  1. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    21 Jan 2011
    Link to this post
    Hey Telerik Team,

    In following along with various posts in how to implement page selectors in custom control templates, I was wondering how you might go about implementing an image selector in a custom control template - choosing an image from the libraries as you see in the regular Sitefinity Image widget.

    Can you point me to some documentation or code example that would illustrate that?  I apologize if this has been answered previously.  I just can't seem to find that in a forum search.

    Thanks

    - Wiliam
  2. Pepi
    Pepi avatar
    981 posts
    Registered:
    28 Oct 2016
    26 Jan 2011
    Link to this post
    Hello WilliamCooper,

    You could use MediaContentSelectorView control to achieve the required functionality. Here is an example how to declare it:

    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Modules.Libraries.Web.UI.Designers" TagPrefix="sf" %>
    <sf:MediaContentSelectorView
        id="selectorView"
        runat="server"
        ContentType="Telerik.Sitefinity.Libraries.Model.Image"
        ParentType="Telerik.Sitefinity.Libraries.Model.Album"
        LibraryBinderServiceUrl="~/Sitefinity/Services/Content/AlbumService.svc/"
        MediaContentBinderServiceUrl="~/Sitefinity/Services/Content/ImageService.svc/"
        MediaContentItemsListDescriptionTemplate="Telerik.Sitefinity.Resources.Templates.Designers.Libraries.Images.ImageItemDescriptionTemplate.htm"
        DisplayResizingOptionsControl="false"
        ShowOpenOriginalSizeCheckBox="false">
    </sf:MediaContentSelectorView>

    Let us know if this helps.

    Kind regards,
    Pepi
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    27 Jan 2011
    Link to this post
    Hi Pepi,

    Thanks for that nice code snippet, those help.  I'll try to implement it tomorrow.

    I'm assuming that registering that designer in the .cs file is similar to how you'd register the page selector?  If not, can you give me an idea of what the .cs file and the .js file would look like in terms of the custom control designer?

    Thanks much.  I'll post again when I've had a chance to test it out.

    Great work on the final release.

    - William
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    27 Jan 2011
    Link to this post
    Hello William,

    Please take a look at How to create a custom widget.  If there are any questions, please update the post with them.

    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  5. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    28 Jan 2011
    Link to this post
    Hi Ivan,

    I guess my question (and I've done a number of custom widgets now in my testing) is how to get and set the value of the Media Selector.  With the Page Selector, there was a great deal of component registering and javascript code that supported passing values back and forth.

    So the big question is, what goes in the refreshUI and applyChanges blocks of the prototype to support getting a usuable value from the Media Selector to pass?  And if necessary, what would go in the supporting .cs file in terms of ScriptDescriptors to register the Media Selector component?

    Thanks!

    - William

  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    28 Jan 2011
    Link to this post
    Hello William,

    refreshUI()
    This method is called, when you need to refresh or update the user interface of your designer with the new data. Sitefinity automatically calls this method every time it needs to (for example, user switches to advanced mode and changes some properties in the property grid, then switches back to the simple mode or designer – this method will be called so that you can update the user interface of your designer with the changes that have been made in the advanced mode. Generally you can think of this method as “from data to user interface”.

    - applyChanges()
    This method is called, when Sitefinity needs to get the properties from your designer. For example, let’s say that user clicks the “Done” button in the designer. In that case Sitefinity needs to get all the properties from your designer and persist them so that it can render the widget properly. Generally, you can think of this method as “from user interface to data”.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  7. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    28 Jan 2011
    Link to this post
    Hey Ivan,

    I actually understand how the prototype methods works, as I've done several custom controls by now.  My question was about specifics.  I can't quite figure out what the actual code would be to get the value from the Media Selector mentioned by Pepi and pass it a value in.  Can you provide any specifics for this case?

    For instance, looking at the value in "selectorView" returns undefined on submit.  Obviously that's not the correct place to look for the value of the image selected.  So where would that be?

    A quick code snippet would be fantastic if possible.

    Thanks

    - William
  8. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    31 Jan 2011
    Link to this post
    Hello William,

    Inside Initialize of your javascript you can create a delegate and subscribe for onItemSelectCommand

    this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect); this.add_onItemSelectCommand(this._itemSelectDelegate);

    and get the selected item


        _itemSelect: function (sender, args) {
            var dataItem = args.get_dataItem();
        },

        add_onItemSelectCommand: function (delegate) {
            this.get_events().addHandler('onItemSelectCommand', delegate);
        },

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  9. jocelyn payneau
    jocelyn payneau avatar
    51 posts
    Registered:
    07 Dec 2009
    31 Jan 2011
    Link to this post
    Hello,

    I need this image selector too but in a custom module I develop.

    Is there a way to add it to the insert form definitions using a definition element?

    Can you provide me a short sample to do this?

    Thanks

    Jocelyn
  10. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    31 Jan 2011
    Link to this post
    Hey Ivan,

    I think I'm still missing either some pieces to this, or some understanding.  I'm going to share the code I have so far and maybe you can tell me what is missing in terms of capturing information about the image selected when somebody hits "save".  Basically, I need to capture information about the image selected so that I can pass it back to the control that calls it, and obviously pass information back from the control to the selector to pre-select images.

    Since in advanced cases, one might like to have multiple image selectors, I'd need that information pass back from that specific selector so that I could potentially add a second to the control.  In other words, the data needs to come from "selectorView" specifically.

    ImageControlDesignerTemplate.ascx
    <%@ Control Language="C#"%>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sfFields" %>
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sitefinity" %>
    <%@ Register Assembly="Telerik.Sitefinity" TagPrefix="designers" Namespace="Telerik.Sitefinity.Web.UI.ControlDesign" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Modules.Libraries.Web.UI.Designers" TagPrefix="sf" %>
    <sf:MediaContentSelectorView
        id="selectorView"
        runat="server"
        ContentType="Telerik.Sitefinity.Libraries.Model.Image"
        ParentType="Telerik.Sitefinity.Libraries.Model.Album"
        LibraryBinderServiceUrl="~/Sitefinity/Services/Content/AlbumService.svc/"
        MediaContentBinderServiceUrl="~/Sitefinity/Services/Content/ImageService.svc/"
        MediaContentItemsListDescriptionTemplate="Telerik.Sitefinity.Resources.Templates.Designers.Libraries.Images.ImageItemDescriptionTemplate.htm"
        DisplayResizingOptionsControl="false"
        ShowOpenOriginalSizeCheckBox="false">
    </sf:MediaContentSelectorView>

    ImageControlDesigner.js
    Type.registerNamespace("TestAppCustomControls");
     
    TestAppCustomControls.ImageControlDesigner = function (element) {
        TestAppCustomControls.ImageControlDesigner.initializeBase(this, [element]);
    }
    TestAppCustomControls.ImageControlDesigner.prototype = {
        initialize: function () {
            TestAppCustomControls.ImageControlDesigner.callBaseMethod(this, 'initialize');
     
            // Specific to image selector
            this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect);
            this.add_onItemSelectCommand(this._itemSelectDelegate);
        },
        dispose: function () {
            TestAppCustomControls.ImageControlDesigner.callBaseMethod(this, 'dispose');
        },
        refreshUI: function () {
            var data = this._propertyEditor.get_control();
            // Something goes here to set the image selector 'selectorView' to the selected image
        },
        applyChanges: function () {
            var controlData = this._propertyEditor.get_control();
            // Something goes here to save the image selected from 'selectorView' and pass it to the control.
        },
        _itemSelect: function (sender, args) {
            var dataItem = args.get_dataItem();
        },
        add_onItemSelectCommand: function (delegate) {
            this.get_events().addHandler('onItemSelectCommand', delegate);
        }
    }
    TestAppCustomControls.ImageControlDesigner.registerClass('TestAppCustomControls.ImageControlDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);
    if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

    ImageControlDesigner.cs
    using System.Collections.Generic;
    using System.Web.UI;
    using System.Linq;
    using Telerik.Sitefinity.Web.UI.ControlDesign;
    using Telerik.Web.UI;
    using Telerik.Sitefinity.Web.UI.Fields;
    using System.Web.UI.WebControls;
    using Telerik.Sitefinity.Modules.Libraries.Web.UI.Designers;
     
    namespace TestAppCustomControls
    {
     
        public class ImageControlDesigner : ControlDesignerBase
        {
            protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container)
            {
                //throw new System.NotImplementedException();
                base.DesignerMode = ControlDesignerModes.Simple;
            }
     
            protected override string LayoutTemplateName
            {
                get
                {
                    return "TestAppCustomControls.Resources.ImageControlDesignerTemplate.ascx";
                }
            }
     
            public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
            {
                var scriptDescriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
                var desc = (ScriptControlDescriptor)scriptDescriptors.Last();
                return scriptDescriptors.ToArray();
            }
     
            public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
            {
                var res = new List<ScriptReference>(base.GetScriptReferences());
                var assemblyName = this.GetType().Assembly.GetName().ToString();
                res.Add(new ScriptReference("TestAppCustomControls.Resources.ImageControlDesigner.js", assemblyName));
                return res.ToArray();
            }
     
            /// <summary>
            /// Gets a reference to the media selector
            /// </summary>
            protected MediaContentSelectorView MediaSelector
            {
                get
                {
                    return Container.GetControl<MediaContentSelectorView>("selectorView", true);
                }
            }
        }
    }

    Thanks!

    - William
  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    02 Feb 2011
    Link to this post
    Hello William,

    Inside the control designer you have to add reference to MediaContentSelectorView and then send  its client ID to the client side component.

    public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
       {
           var scriptDescriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
           var desc = (ScriptControlDescriptor)scriptDescriptors.Last();
           desc.AddComponentProperty("selectorView", SelectorView.ClientID);
           return scriptDescriptors.ToArray();
       }
     
       /// <summary>
       /// Gets a collection of <see cref="T:System.Web.UI.ScriptReference"/> objects that define script resources that the control requires.
       /// </summary>
       /// <returns>
       /// An <see cref="T:System.Collections.IEnumerable"/> collection of <see cref="T:System.Web.UI.ScriptReference"/> objects.
       /// </returns>
       public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
       {
           var res = new List<ScriptReference>(base.GetScriptReferences());
           var assemblyName = this.GetType().Assembly.GetName().ToString();
           res.Add(new ScriptReference(designerScriptName, assemblyName));
           return res.ToArray();
       }
     
     
       protected virtual MediaContentSelectorView SelectorView
       {
           get
           {
               return this.Container.GetControl<MediaContentSelectorView>("selectorView", true);
           }
       }

    Then you can access the MediaContentSelectorView object and listen to the click event

    Telerik.Sitefinity.Samples.SimpleViewCustomDesigner = function (element) {
     
        // element
        this._selectorView = null;
        this._itemSelectDelegate = null;
        Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.initializeBase(this, [element]);
     
    }
     
    Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.prototype = {
     
        initialize: function () {
            Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.callBaseMethod(this, 'initialize');
            this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect);
            this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
     
        },
     
        dispose: function () {
            Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.callBaseMethod(this, 'dispose');
     
            if (this._selectorView) {
                this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
            }
     
        },
     
     
        get_selectorView: function () {
            return this._selectorView;
        },
        set_selectorView: function (value) {
            this._selectorView = value;
        },
     
            _itemSelect: function (sender, args) {
            var dataItem = args.get_dataItem();
        },


    Regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
    Answered
  12. William
    William avatar
    42 posts
    Registered:
    17 May 2007
    03 Feb 2011
    Link to this post
    Ivan,

    Yes, I was indeed missing a piece of this.  Mainly, I'd forgotten to add the SelectorView into the GetScriptDescriptors.

    This works like a charm now, thanks.

    One extra question, which I don't necessarily need for this, but which would make the solution complete.  Can you show me how you'd pre-select an image based on a GUID passed in?  In other words, I'd love it if the image you'd previously selected was pre-selected when you went to edit later.

    I'm assuming that's another handler, but I'm not sure which handlers are involved with the Media Selector.

    Any ideas?

    Thanks

    - William

  13. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    03 Feb 2011
    Link to this post
    Hi William,

    You can use css , but you should pass the value back to itemSelected. You can keep the key in gloabal variable. The code should something like this.


       _itemSelected: function (sender, args) {
            var dataItem = args.get_dataItem();
            // or you can try getting the image key from the args
            this._selectedImageKey = args.get_key();
            var selectedElement = args.get_itemElement();
            this._highlightSelectedImage(selectedElement);

        },

       
        _highlightSelectedImage: function (selectedElement) {
            if (this.selectedImageElement) {
                if (this.selectedImageElement != selectedElement) {
                    $(this.selectedImageElement).find(".imgSelect").removeClass("sfSelImgBorder");
                    $(this.selectedImageElement).removeClass("sfSel");
                } else {
                    $(this.selectedImageElement).addClass("sfSel");
                }
            }

            if (selectedElement) {
                this.selectedImageElement = selectedElement;
                $(selectedElement).find(".imgSelect").addClass("sfSelImgBorder");
            }

        },

    Regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  14. Mark
    Mark avatar
    12 posts
    Registered:
    10 Feb 2011
    04 Aug 2011
    Link to this post
    Hi Ivan,

    I've had a go at getting an image selector working as in the code examples above.  I have some textboxes that I'm using to set string values in my control from the designer (which all work fine),  I can see and select images, however I also want to set the url of the selected image from the custom designer into a string value on the control and I can't work out how to do this.  Could you provide an example of how I can achieve this?

    In the designer.js I have the following

        get_widthTxtControl: function () {
            return this._widthTxtControl;
        },
        set_widthTxtControl: function (value) {
            this._widthTxtControl = value;
        },

        refreshUI: function () {
            var data = this.get_controlData();

            $("#" + this._widthTxtControl.id).val(data.Width);
        },
        
        applyChanges: function () {
            var data = this.get_controlData();

            data.Width = $("#" + this._widthTxtControl.id).val();
        }
        
    I've tried adding something like but no luck

        var imageUrl = args.get_dataItem().MediaUrl;
        this.set_imageSelectorView(imageUrl);
        
    Once I get that working I'd also like to add another MediaContentSelectorView for selecting documents, so I'm hoping this will be a similar process.

    Thanks in advance
    Mark   
  15. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    04 Aug 2011
    Link to this post
    Hi Mark,

    The dataitem should have MediaUrl property. Do you get it when you call

    var imageUrl = args.get_dataItem().MediaUrl;



    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  16. Mark
    Mark avatar
    12 posts
    Registered:
    10 Feb 2011
    05 Aug 2011
    Link to this post
    Hi Ivan,

    Thanks for the reply, yep I've got that working now.  Just one extra thing to polish this off.  I'd like to highlight the image and document selected when the user goes back to edit.  I've tried playing around with the code in the thread but can't really work this out, I'm kind off coding blind here as I'm not really that sure what I should be doing.  I've put the code for my designer.js below, any help is much appreciated.

    Cheers
    Mark

    // <reference name="Telerik.Sitefinity.Resources.Scripts.jquery-1.4.2-vsdoc.js" assembly="Telerik.Sitefinity.Resources"/>
    Type.registerNamespace("Custom.UserControls");
     
    Custom.UserControls.CustomDesigner = function (element) {
     
        // element
        this._heightTxtControl = null;
        this._widthTxtControl = null;
        this._imageSelectorView = null;
        this._imageSelectDelegate = null;
        this._docSelectorView = null;
        this._docSelectDelegate = null;
        Custom.UserControls.CustomDesigner.initializeBase(this, [element]);
    }
     
    Custom.UserControls.CustomDesigner.prototype = {
     
        initialize: function () {
            Custom.UserControls.CustomDesigner.callBaseMethod(this, 'initialize');
            this._imageSelectDelegate = Function.createDelegate(this, this._imageSelected);
            this._imageSelectorView.add_onItemSelectCommand(this._imageSelectDelegate);
     
            this._docSelectDelegate = Function.createDelegate(this, this._docSelected);
            this._docSelectorView.add_onItemSelectCommand(this._docSelectDelegate);
        },
     
        dispose: function () {
            Custom.UserControls.CustomDesigner.callBaseMethod(this, 'dispose');
     
            if (this._imageSelectorView) {
                this._imageSelectorView.add_onItemSelectCommand(this._imageSelectDelegate);
            }
     
            if (this._docSelectorView) {
                this._docSelectorView.add_onItemSelectCommand(this._docSelectDelegate);
            }
        },
     
        get_heightTxtControl: function () {
            return this._heightTxtControl;
        },
        set_heightTxtControl: function (value) {
            this._heightTxtControl = value;
        },
     
        get_widthTxtControl: function () {
            return this._widthTxtControl;
        },
        set_widthTxtControl: function (value) {
            this._widthTxtControl = value;
        },
     
        get_imageSelectorView: function () {
            return this._imageSelectorView;
        },
        set_imageSelectorView: function (value) {
            this._imageSelectorView = value;
        },
     
        get_docSelectorView: function () {
            return this._docSelectorView;
        },
        set_docSelectorView: function (value) {
            this._docSelectorView = value;
        },
     
        _imageSelected: function (sender, args) {
            var imageUrl = args.get_dataItem().MediaUrl;
            this.set_imageSelectorView(imageUrl);
        },
     
        _docSelected: function (sender, args) {
            var docUrl = args.get_dataItem().MediaUrl;
            this.set_docSelectorView(docUrl);
        },
     
        add_onItemSelectCommand: function (delegate) {
            this.get_events().addHandler('onItemSelectCommand', delegate);
        },
     
        _itemSelected: function (sender, args) {
            var dataItem = args.get_dataItem();
            this._selectedImageKey = args.get_key();
            var selectedElement = args.get_itemElement();
            this._highlightSelectedImage(selectedElement);
        },
     
        _highlightSelectedImage: function (selectedElement) {
            if (this.selectedImageElement) {
                if (this.selectedImageElement != selectedElement) {
                    $(this.selectedImageElement).find(".imgSelect").removeClass("sfSelImgBorder");
                    $(this.selectedImageElement).removeClass("sfSel");
                } else {
                    $(this.selectedImageElement).addClass("sfSel");
                }
            }
     
            if (selectedElement) {
                this.selectedImageElement = selectedElement;
                $(selectedElement).find(".imgSelect").addClass("sfSelImgBorder");
            }
        },
     
        /* --------------------------------- event handlers --------------------------------- */
     
        /* ----------------------------- public methods ----------------------------- */
     
        refreshUI: function () {
            var data = this.get_controlData();
     
            $("#" + this._heightTxtControl.id).val(data.Height);
            $("#" + this._widthTxtControl.id).val(data.Width);
        },
     
        // forces the designer to apply the changes on UI to the control Data
        applyChanges: function () {
            var data = this.get_controlData();
     
            data.Height = $("#" + this._heightTxtControl.id).val();
            data.Width = $("#" + this._widthTxtControl.id).val();
            data.Image = this.get_imageSelectorView();
            data.Doc = this.get_docSelectorView();
        }
    }
     
    Custom.UserControls.CustomDesigner.registerClass('Custom.UserControls.CustomDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);
    if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
  17. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    09 Aug 2011
    Link to this post
    Hi Mark,

    You can get the selected item Id and save it as a public property of the control. Then when you click on the edit buton you should subscribe for the client ItemDataBound event of the selector view get the item you need by Id and set the css. In RefreshUI you can subscribe for add_onItemDataBound

    Here is how to save the item ID as a public property

    initialize: function () {
            Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.callBaseMethod(this, 'initialize');

            this._itemSelectedDelegate = Function.createDelegate(this, this._propertyGridItemSelectCommand);
            this._selectorView.add_onItemSelectCommand(this._itemSelectedDelegate);



            this._mediaContentBinderItemDataBoundDelegate = Function.createDelegate(this, this._mediaContentBinderItemDataBound);

        },

    _propertyGridItemSelectCommand: function (sender, args) {
            var dataItem = args.get_dataItem();
            var d = this.get_controlData();
            d.SelectedItemValue = dataItem.Id;
        },

        _mediaContentBinderItemDataBound: function (sender, args) {
            var dataItem = args.get_dataItem();
            var id = dataItem.Id;

        },

        refreshUI: function () {
            var data = this.get_controlData();
            var selector = this.get_selectorView();
    this._selectorView.get_mediaContentBinder().add_onItemDataBound(this._mediaContentBinderItemDataBoundDelegate);
         },


    where SelectedItemValue is a public property of your control.

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  18. Kalisha
    Kalisha avatar
    5 posts
    Registered:
    27 Jun 2011
    14 Sep 2011
    Link to this post
    Hi William/Ivan,

    Can either of you share the files in a zip. I'm trying to get this to work but I'm getting an invalid resource error when I click select. All I need is to be able to select an image, nothing too fancy. Thanks!
  19. Lurch
    Lurch avatar
    64 posts
    Registered:
    18 Jan 2011
    02 Jul 2013 in reply to Kalisha
    Link to this post
    YES! Can comeone please post a complete, working example on how to use the MediaContentSelectorView.

    I am trying to develop an update form, that maintains a RadGrid of personnel details, and one of the fields is a photo. I have spent the last three days delving through countless forum posts, but have not found a complete example of how to do this.

    I just need one source code example that I can use to learn from, to adapt to what I need.
  20. Brett Whittington
    Brett Whittington avatar
    89 posts
    Registered:
    10 Aug 2012
    05 Jul 2013 in reply to Lurch
    Link to this post
    I could send you two.  One that I have working, to use through the Module Builder.  And one using the MediaContentSelectorView in a custom built "intra-site" module.  I'm am only version 5.0 of Sitefinity so I do not know if it will work with later versions.  This code is from a message rotator thingy I wrote and is using the MediaContentSelectorView

    AddEditView.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FeaturedMessagesAddEditView.ascx.cs"
        Inherits="InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields"
        TagPrefix="sf" %>
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI"
        TagPrefix="sitefinity" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields"
        TagPrefix="sfFields" %>
    <%@ Register Assembly="Telerik.Sitefinity" TagPrefix="designers" Namespace="Telerik.Sitefinity.Web.UI.ControlDesign" %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Modules.Libraries.Web.UI.Designers"
        TagPrefix="sf1" %>
    <%--<sfFields:FormManager  runat="server" ID="FormsManager1" />--%>
    <telerik:RadScriptManager ID="manager" runat="server"></telerik:RadScriptManager>
    <sitefinity:UserPreferences ID="userPreferences" runat="server" />
    <h1 class="sfBreadCrumb">Featured Messages</h1>
    <div class="sfMain sfClearfix">
        <div class="sfContent">
            <div class="rgTopOffset sfWorkArea">
                <fieldset class="sfNewContentForm">
                    <div class="sfFormIn">
                        <asp:ValidationSummary ID="vsum" runat="server" ForeColor="Red" DisplayMode="BulletList" />
                        <ul>
                            <li>
                                <asp:Label ID="lblBlurb" runat="server" Text="Blurb" CssClass="sfTxtLbl" />
                                <telerik:RadEditor ID="radblurb" runat="server">
                                </telerik:RadEditor>
                            </li>
                            <li>
                                <sf1:MediaContentSelectorView ID="selectorView" runat="server" ContentType="Telerik.Sitefinity.Libraries.Model.Image"
                                    ParentType="Telerik.Sitefinity.Libraries.Model.Album" LibraryBinderServiceUrl="~/Sitefinity/Services/Content/AlbumService.svc/"
                                    MediaContentBinderServiceUrl="~/Sitefinity/Services/Content/ImageService.svc/"
                                    MediaContentItemsListDescriptionTemplate="Telerik.Sitefinity.Resources.Templates.Designers.Libraries.Images.ImageItemDescriptionTemplate.htm"
                                    DisplayResizingOptionsControl="false" ShowOpenOriginalSizeCheckBox="false">
                                </sf1:MediaContentSelectorView>
                            </li>
                            <li>
                                <asp:Label ID="lblRelatedLink" runat="server" Text="RelatedLink" CssClass="sfTxtLbl" />
                                <sitefinity:GenericPageSelector
                                    id="GenericPageSelector1"
                                    runat="server"
                                    RootNodeID="F669D9A7-009D-4d83-DDAA-000000000002"
                                    WebServiceUrl="~/Sitefinity/Services/Pages/PagesService.svc/"
                                    ShowOnlySelectedAsGridOnLoad="true"
                                    MarkItemsWithoutTranslation="false"
                                    AllowMultipleSelection="false" />
                            </li>
                            <li>
                                <asp:Label ID="lblEffectiveDate" runat="server" Text="Effective Date" CssClass="sfTxtLbl" />
                                <telerik:RadDatePicker ID="rdpEffectiveDate" runat="server">
                                </telerik:RadDatePicker>
                            </li>
                            <li>
                                <asp:Label ID="lblExpirationDate" runat="server" Text="Expiration Date" CssClass="sfTxtLbl" />
                                <telerik:RadDatePicker ID="rdpExpirationDate" runat="server">
                                </telerik:RadDatePicker>
                            </li>
                            <asp:HiddenField ID="imageId" runat="server" ClientIDMode="Static" />
                            <asp:HiddenField ID="pageId" runat="server" ClientIDMode="Static" />
                        </ul>
                        <p>
                            <asp:Button ID="btnSave" runat="server" Text="Save Featured Messages" OnClick="btnSave_Click" />
                            or <a href="<%= ResolveUrl("~/Sitefinity/Content/Featured Messages") %>">Cancel and
                                go back to Featured Messages</a>
                        </p>
                    </div>
                </fieldset>
            </div>
        </div>
    </div>
    <asp:CustomValidator ID="cusBlurb" runat="server" ForeColor="Red" ErrorMessage="Blurb is required"
        ControlToValidate="radblurb" ValidateEmptyText="true"></asp:CustomValidator>
    <asp:CustomValidator ID="cusEffectiveDate" runat="server" ForeColor="Red" ErrorMessage="Effective Date is required"
        ControlToValidate="rdpEffectiveDate" ValidateEmptyText="true"></asp:CustomValidator>
    <asp:CustomValidator ID="cusExpirationDate" runat="server" ForeColor="Red" ErrorMessage="Expiration Date is required"
        ControlToValidate="rdpExpirationDate" ValidateEmptyText="true"></asp:CustomValidator>

    AddEditView..ascx.cs
    using InstalledWebComponents.Modules.FeaturedMessages.Data;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Telerik.Sitefinity;
    using Telerik.Sitefinity.Data;
    using Telerik.Sitefinity.Model;
    using Telerik.Sitefinity.Modules;
    using Telerik.Sitefinity.Libraries;
    using Telerik.Sitefinity.Libraries.Model;
    using Telerik.Sitefinity.Modules.Libraries;
    using Telerik.Sitefinity.Modules.Libraries.Images;
    using Telerik.Sitefinity.Modules.Pages;
    using Telerik.Sitefinity.Modules.Pages.Web.UI;
    using Telerik.Sitefinity.Taxonomies;
    using Telerik.Sitefinity.Taxonomies.Model;
    using Telerik.Sitefinity.Web;
    using Telerik.Sitefinity.Web.UI.ControlDesign;
    using Telerik.Sitefinity.Web.UI.Fields;
    using Telerik.Sitefinity.Resources;
    using Telerik.Web.UI;
     
    namespace InstalledWebComponents.Modules.FeaturedMessages.Admin
    {
     
        public partial class FeaturedMessagesAddEditView : System.Web.UI.UserControl, IScriptControl
        {
            private const string UrlNameCharsToReplace = @"[^\w\-\!\$\'\(\)\=\@\d_]+";
            private const string UrlNameReplaceString = "-";
     
            FeaturedMessagesContext context = FeaturedMessagesContext.Get();
     
            private ScriptManager sm;
         
            #region Check Mode
     
            public enum AdminControlMode
            {
                Create,
                Edit
            }
     
            /// <summary>
            /// Gets or sets the mode in which to render the control.
            /// </summary>
            /// <value>
            /// The mode.
            /// </value>
            public AdminControlMode Mode { get { return _mode; } set { _mode = value; } }
            private AdminControlMode _mode;
     
            private Guid featuredMessageID = Guid.Empty;
     
            /// <summary>
            /// Gets the featuredMessage ID to load in Edit Mode.
            /// </summary>
            protected Guid FeaturedMessageID
            {
                get
                {
                    if (featuredMessageID == Guid.Empty)
                    {
                        // ensure parameter is valid
                        var param = Request.RequestContext.RouteData.Values["Params"] as string[];
                        if (param == null) return Guid.Empty;
     
                        // grab id from url
                        Guid id;
                        if (!Guid.TryParse(param[0], out id)) return Guid.Empty;
     
                        // retrieve featuredMessage
                        var featuredMessage = context.FeaturedMessages.FirstOrDefault(t => t.Id == id);
                        featuredMessageID = (featuredMessage == null) ? Guid.Empty : featuredMessage.Id;
                    }
                    return featuredMessageID;
                }
            }
     
            #endregion
     
            /// <summary>
            /// Handles the Load event of the Page control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack && Mode == AdminControlMode.Edit)
                {
     
     
                    // retrieve featuredMessage from DB
                    var featuredMessage = context.FeaturedMessages.Where(t => t.Id == FeaturedMessageID).FirstOrDefault();
                    if (featuredMessage == null) return;
     
     
                    Telerik.Sitefinity.Libraries.Model.Image image = App.WorkWith().Images().Where(i => i.Id == featuredMessage.ImageId).Get().SingleOrDefault();
     
                    radblurb.Content = featuredMessage.Blurb;
                    rdpEffectiveDate.SelectedDate = featuredMessage.EffectiveDate;
                    rdpExpirationDate.SelectedDate = featuredMessage.ExpirationDate;
                    pageId.Value = featuredMessage.RelatedLink.ToString();
                    imageId.Value = featuredMessage.ImageId.ToString();
                }
     
                cusBlurb.ServerValidate += new ServerValidateEventHandler(cusBlurb_ServerValidate);
                cusEffectiveDate.ServerValidate += new ServerValidateEventHandler(cusEffectiveDate_ServerValidate);
                cusExpirationDate.ServerValidate += new ServerValidateEventHandler(cusExpirationDate_ServerValidate);
     
            }
     
            void cusExpirationDate_ServerValidate(object source, ServerValidateEventArgs args)
            {
                args.IsValid = false;
                if (rdpExpirationDate.SelectedDate != null)
                {
                    args.IsValid = true;
                }
            }
     
            void cusEffectiveDate_ServerValidate(object source, ServerValidateEventArgs args)
            {
                args.IsValid = false;
                if (rdpEffectiveDate.SelectedDate != null)
                {
                    args.IsValid = true;
                }
            }
     
            void cusBlurb_ServerValidate(object source, ServerValidateEventArgs args)
            {
                args.IsValid = false;
                if (!string.IsNullOrEmpty(radblurb.Content))
                {
                    args.IsValid = true;
                }
            }
     
            protected override void OnPreRender(EventArgs e)
            {
                if (!this.DesignMode)
                {
                    // Test for ScriptManager and register if it exists
                    sm = RadScriptManager.GetCurrent(this.Page);
     
                    if (sm == null)
                        throw new HttpException("A ScriptManager control must exist on the current page.");
     
                    sm.RegisterScriptControl(this);
                }
     
                base.OnPreRender(e);
            }
     
            protected override void Render(HtmlTextWriter writer)
            {
                if (!this.DesignMode)
                    sm.RegisterScriptDescriptors(this);
     
                base.Render(writer);
            }
     
            protected virtual IEnumerable<ScriptReference> GetScriptReferences()
            {
                ScriptReference imageReference = new ScriptReference();
                imageReference.Path = "~/Modules/FeaturedMessages/Admin/JavaScript/FeaturedMessagesAddEditView.js";
     
                return new ScriptReference[] { imageReference };
            }
     
            protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
            {
                ScriptControlDescriptor imageDescriptor = new ScriptControlDescriptor("InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView", this.ClientID);
                //Send the MediaContentSelectorView clientside object to the page.
                imageDescriptor.AddComponentProperty("selectorView", selectorView.ClientID);
                //Send the GenericPageSelector clientside object to the page.
                imageDescriptor.AddComponentProperty("pageSelectorView", GenericPageSelector1.ClientID);
                //Send the Save Button clientside object to the page.
                imageDescriptor.AddElementProperty("saveLink", btnSave.ClientID);
                return new ScriptDescriptor[] { imageDescriptor };
            }
                 
     
            IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
            {
                return GetScriptReferences();
            }
     
            IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
            {
                return GetScriptDescriptors();
            }
     
     
            /// <summary>
            /// Handles the Click event of the btnSave control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void btnSave_Click(object sender, EventArgs e)
            {
                this.Page.Validate();
                if (this.Page.IsValid)
                {
                    Telerik.Sitefinity.Project.Configuration.ProjectConfig config = new Telerik.Sitefinity.Project.Configuration.ProjectConfig();
                    Telerik.Sitefinity.Project.Web.Services.ProjectInfo projectInfo = new Telerik.Sitefinity.Project.Web.Services.ProjectInfo(config);
                    switch (Mode)
                    {
                        case AdminControlMode.Edit:
     
                            // update existing featuredMessage
                            var featuredMessage = context.FeaturedMessages.Where(t => t.Id == FeaturedMessageID).FirstOrDefault();
                            if (featuredMessage == null) return; // default 404 response
     
                            // mark route handled/found
                            RouteHelper.SetUrlParametersResolved();
                            featuredMessage.Application = projectInfo.Name;
                            featuredMessage.Blurb = radblurb.Content;
                            featuredMessage.EffectiveDate = rdpEffectiveDate.SelectedDate.Value;
                            featuredMessage.ExpirationDate = rdpExpirationDate.SelectedDate.Value;
                            featuredMessage.ImageId = new Guid(imageId.Value);
                            featuredMessage.PublishDate = DateTime.Now;
                            featuredMessage.RelatedLink = new Guid(pageId.Value);
                            break;
     
                        case AdminControlMode.Create:
                            // create and save new featuredMessage
                            var newFeaturedMessage = new FeaturedMessage();
                            newFeaturedMessage.Application = projectInfo.Name;
                            newFeaturedMessage.Blurb = radblurb.Content;
                            newFeaturedMessage.EffectiveDate = rdpEffectiveDate.SelectedDate.Value;
                            newFeaturedMessage.ExpirationDate = rdpExpirationDate.SelectedDate.Value;
                            newFeaturedMessage.ImageId = new Guid(imageId.Value);
                            newFeaturedMessage.PublishDate = DateTime.Now;
                            if (!string.IsNullOrEmpty(pageId.Value))
                            {
                                newFeaturedMessage.RelatedLink = new Guid(pageId.Value);
                            }
                            else
                            {
                                newFeaturedMessage.RelatedLink = Guid.Empty;
                            }
                            newFeaturedMessage.ListOrder = context.FeaturedMessages.ToList().Count + 1;
                            context.Add(newFeaturedMessage);
                            break;
                    }
     
                    // save and return to main view
                    context.SaveChanges();
                    Response.Redirect(ResolveUrl(SiteMapBase.GetActualCurrentNode().ParentNode.Url));
                }
            }
     
            protected override void OnUnload(EventArgs e)
            {
                base.OnUnload(e);
                if (context != null)
                    context.Dispose();
            }
        }
    }

    AddEditView.js
    Type.registerNamespace("InstalledWebComponents.Modules.FeaturedMessages.Admin");
     
    InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView = function (element) {
        InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.initializeBase(this, [element]);
     
        this._imageId = $("#imageId").val();
        this._pageId = $("#pageId").val();
    }
     
    InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.prototype = {
        initialize: function () {
            InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.callBaseMethod(this, 'initialize');
            this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect);
            this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
     
            this._saveLinkClickDelegate = Function.createDelegate(this, this._saveLinkClicked);
            if (this._saveLink) {
                $addHandler(this._saveLink, "click", this._saveLinkClickDelegate);
            }
     
            this._mediaContentBinderItemDataBoundDelegate = Function.createDelegate(this, this._mediaContentBinderItemDataBound);
     
            this._onLoadDelegate = Function.createDelegate(this, this._onLoad);
            Sys.Application.add_load(this._onLoadDelegate);
     
     
        },
     
        _onLoad: function (sender, args) {
            this._selectorView.get_mediaContentBinder().add_onItemDataBound(this._mediaContentBinderItemDataBoundDelegate);
            this._pageSelectorView.set_selectedItemId(this._pageId);
        },
     
        dispose: function () {
            InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.callBaseMethod(this, 'dispose');
            if (this._selectorView) {
                this._selectorView.add_onItemSelectCommand(this._itemSelectDelegate);
            }
     
            if (this._selectLinkClickDelegate) {
                delete this._saveLinkClickDelegate;
            }
     
        },
     
        _mediaContentBinderItemDataBound: function (sender, args) {
            var dataItem = args.get_dataItem();
            var id = dataItem.Id;
            if (id == this._imageId) {
                sender._selectedItems.push(dataItem);
                this._highlightSelectedImage(args.get_itemElement());
            }
        },
     
        get_selectorView: function () {
            return this._selectorView;
        },
     
        set_selectorView: function (value) {
            this._selectorView = value;
        },
     
        get_pageSelectorView: function () {
            return this._pageSelectorView;
        },
        set_pageSelectorView: function (value) {
            this._pageSelectorView = value;
        },
     
        get_saveLink: function () {
            return this._saveLink;
        },
     
        set_saveLink: function (value) {
            this._saveLink = value;
        },
     
        _itemSelect: function (sender, args) {
            this._imageId = args.get_dataItem().Id;
            $("#imageId").val(this._imageId);
            var selectedElement = args.get_itemElement();
            this._highlightSelectedImage(selectedElement);
        },
     
        _itemSet: function (sender, args) {
            var d = this.get_controlData();
            d.SelectedItemValue = this._imageId;
        },
     
        _highlightSelectedImage: function (selectedElement) {
            if (this.selectedImageElement) {
                if (this.selectedImageElement != selectedElement) {
                    $(this.selectedImageElement).find(".imgSelect").removeClass("sfSelImgBorder");
                    $(this.selectedImageElement).removeClass("sfSel");
                } else {
                    $(this.selectedImageElement).addClass("sfSel");
                }
            }
     
            if (selectedElement) {
                this.selectedImageElement = selectedElement;
                $(selectedElement).addClass("sfSel");
                $(selectedElement).find(".imgSelect").addClass("sfSelImgBorder");
            }
        },
     
     
        _saveLinkClicked: function (sender, args) {
            var selectedValue = this.get_pageSelectorView().get_selectedItem();
     
            if (!selectedValue || selectedValue === "") {
                alert("No page selected.");
            } else {
                $("#pageId").val(selectedValue.Id);
            }
        },
     
        add_onItemSelectCommand: function (delegate) {
            this.get_events().addHandler('onItemSelectCommand', delegate);
        }
    }
     
    InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView.registerClass('InstalledWebComponents.Modules.FeaturedMessages.Admin.FeaturedMessagesAddEditView', Sys.Component);
     
    if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
  21. Lurch
    Lurch avatar
    64 posts
    Registered:
    18 Jan 2011
    05 Jul 2013
    Link to this post
    Thanks for the example. Still trying to get my head around all these new objects and code blocks.

    I have noticed that everybody is embedding the control inside their widget, to show the "Select an Image" form contents, along with their own. Is there a way to just have a link, to pop-up the standard Sitefinity image control on top of the screen?
  22. Brett Whittington
    Brett Whittington avatar
    89 posts
    Registered:
    10 Aug 2012
    05 Jul 2013 in reply to Lurch
    Link to this post
    You're right they do but that is because everyone is basing it off of the Blog Posts and forum articles that Sitefinity's team posts.

    The only example I have that you might be able get to work is a separate widget and you might be able to reference it on your page.  I currently use in the module builder.  I'll link it but is very much like one of the blog posts from a Sitefinity Team Member.  Sorry for the block code but I cannot give you an example any other way.

    ImageField.ascx
    <%@ Control %>
    <%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
    <sf:ResourceLinks ID="resourcesLinks" runat="server" UseEmbeddedThemes="True" Theme="Default">
        <sf:ResourceFile JavaScriptLibrary="JQuery" />
        <sf:ResourceFile Name="Telerik.Sitefinity.Resources.Themes.Default.Styles.jQuery.jquery.ui.core.css"  Static="True"/>
        <sf:ResourceFile Name="Telerik.Sitefinity.Resources.Themes.Default.Styles.jQuery.jquery.ui.dialog.css" Static="True"/>
        <sf:ResourceFile Name="Telerik.Sitefinity.Resources.Themes.Default.Styles.jQuery.jquery.ui.theme.sitefinity.css"  Static="True"/>   
    </sf:ResourceLinks>
      
    <sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server">
        <Templates>
            <sf:ConditionalTemplate Left="DisplayMode" Operator="Equal" Right="Read" runat="server">  
                <sf:SitefinityLabel id="titleLabel_read" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtLbl"></sf:SitefinityLabel>
                <sf:SitefinityLabel id="textLabel_read" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfTxtContent"></sf:SitefinityLabel>
                <asp:Image ID="image_read" runat="server" />
                <sf:SitefinityLabel id="descriptionLabel_read" runat="server" WrapperTagName="p" HideIfNoText="true" CssClass="sfDescription"></sf:SitefinityLabel>
                <sf:SitefinityLabel ID="exampleLabel_read" runat="server" WrapperTagName="P" HideIfNoText="true" CssClass="sfExample" />
            </sf:ConditionalTemplate>
            <sf:ConditionalTemplate Left="DisplayMode" Operator="Equal" Right="Write" runat="server">
                <sf:SitefinityLabel ID="titleLabel_write" runat="server" CssClass="sfTxtLbl" />
                <div class="sfPreviewImgFrame">
                    <asp:Image ID="image_write" runat="server" Width="160" Height="160" />
                </div>
      
                <sf:EditorContentManagerDialog runat="server" ID="asyncImageSelector" DialogMode="Image" Width="540" HostedInRadWindow="false" BodyCssClass="" />
                <asp:LinkButton ID="selectImageButton_write" OnClientClick="return false;" runat="server" CssClass="sfLinkBtn sfChange">
                    <span class="sfLinkBtnIn"><asp:Literal runat="server" ID="AddImageLiteral" Text="Select..." /></span>
                </asp:LinkButton>
                <sf:SitefinityLabel id="descriptionLabel_write" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfDescription" />
                <sf:SitefinityLabel id="exampleLabel_write" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfExample" />
            </sf:ConditionalTemplate>
        </Templates>
    </sf:ConditionalTemplateContainer>

    ImageField.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Sitefinity;
    using Telerik.Sitefinity.Web.UI;
    using Telerik.Sitefinity.Web.UI.Fields;
    using Telerik.Sitefinity.Web.UI.Fields.Enums;
     
    namespace InstalledWebComponents.CustomControls.ImageField
    {
     
        [FieldDefinitionElement(typeof(ImageFieldDefinitionElement))]
     
        public class ImageField : FieldControl
        {
     
            protected override string LayoutTemplateName
            {
                get { return layoutTemplateName; }
            }
     
            #region Constructors
            public ImageField()
            {
     
            }
     
            #endregion
     
            #region Properties
     
            protected override WebControl TitleControl
            {
                get
                {
                    return TitleLabel;
                }
     
            }
     
            protected override WebControl DescriptionControl
            {
                get
                {
                    return DescriptionLabel;
                }
            }
     
            protected override WebControl ExampleControl
            {
                get
                {
                    return ExampleLabel;
                }
            }
     
            protected internal virtual Label TitleLabel
            {
                get
                {
                    return DisplayMode == FieldDisplayMode.Write ?
                        Container.GetControl<Label>("titleLabel_write", true) :
                        Container.GetControl<Label>("titleLabel_read", true);
                }
            }
     
            protected internal virtual Label DescriptionLabel
            {
                get
                {
                    return DisplayMode == FieldDisplayMode.Write ?
                        Container.GetControl<Label>("descriptionLabel_write", true) :
                        Container.GetControl<Label>("descriptionLabel_read", true);
                }
            }
     
            protected internal virtual Label ExampleLabel
            {
                get
                {
                    return DisplayMode == FieldDisplayMode.Write ?
                        Container.GetControl<Label>("exampleLabel_write", true) :
                        Container.GetControl<Label>("exampleLabel_read", true);
                }
            }
     
            public override object Value
            {
                get
                {
                    return imageUrl;
                }
                set
                {
                    if (value != null)
                    {
                        var val = new Guid(value.ToString());
                        _imageId = val;
     
                        if (val != Guid.Empty)
                        {
                            ReadImage.ImageUrl = App.WorkWith().Image(val).Get().MediaUrl;
                            imageUrl = App.WorkWith().Image(val).Get().MediaUrl;
                        }
                    }
                }
            }
     
            protected Image ReadImage
            {
                get { return Container.GetControl<Image>("image_read", false); }
            }
     
            protected Image WriteImage
            {
                get { return Container.GetControl<Image>("image_write", false); }
            }
     
            protected EditorContentManagerDialog AsyncImageSelector
            {
                get { return Container.GetControl<EditorContentManagerDialog>("asyncImageSelector", false); }
            }
     
            protected LinkButton SelectImageButton
            {
                get
                {
                    return Container.GetControl<LinkButton>("selectImageButton_write", false);
                }
            }
     
            #endregion
     
            #region Methods
     
            protected override void InitializeControls(GenericContainer container)
            {
     
                TitleLabel.Text = Title;
                ExampleLabel.Text = Example;
                DescriptionLabel.Text = Description;
     
                if (_imageId != Guid.Empty)
                {
                    ReadImage.ImageUrl = App.WorkWith().Image(_imageId).Get().MediaUrl;
     
                }
            }
     
            public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
            {
                var descriptors = new List<ScriptDescriptor>();
                var descriptor = base.GetScriptDescriptors().Last() as ScriptControlDescriptor;
     
                if (DisplayMode == FieldDisplayMode.Read)
                {
                    descriptor.AddElementProperty("readImage", ReadImage.ClientID);
                }
     
                if (DisplayMode == FieldDisplayMode.Write)
                {
                    descriptor.AddComponentProperty("asyncImageSelector", AsyncImageSelector.ClientID);
                    descriptor.AddElementProperty("selectImageButton", SelectImageButton.ClientID);
                    descriptor.AddElementProperty("writeImage", WriteImage.ClientID);
                    descriptor.AddProperty("imageServiceUrl", VirtualPathUtility.ToAbsolute("~/Sitefinity/Services/Content/ImageService.svc/"));
                }
     
                descriptors.Add(descriptor);
                return descriptors.ToArray();
            }
     
            public override IEnumerable<ScriptReference> GetScriptReferences()
            {
                var assemblyName = this.GetType().Assembly.GetName().ToString();
                var scripts = new List<ScriptReference>(base.GetScriptReferences());
                scripts.Add(new ScriptReference("Telerik.Sitefinity.Resources.Scripts.jquery-ui-1.8.8.custom.min.js", "Telerik.Sitefinity.Resources"));
                scripts.Add(new ScriptReference("Telerik.Sitefinity.Resources.Scripts.ajaxupload.js", "Telerik.Sitefinity.Resources"));
                scripts.Add(new ScriptReference(ScriptReference, assemblyName));
                return scripts;
            }
     
            private Guid _imageId;
            private string imageUrl;
            public static readonly string layoutTemplateName = "InstalledWebComponents.CustomControls.ImageField.ImageField.ascx";
            public static readonly string ScriptReference = typeof(ImageField).Namespace + ".ImageField.js";
            #endregion
     
        }
     
    }

     

     

    ImageField.js

    Type.registerNamespace("InstalledWebComponents.CustomControls.ImageField");
     
    InstalledWebComponents.CustomControls.ImageField.ImageField = function (element) {
        InstalledWebComponents.CustomControls.ImageField.ImageField.initializeBase(this, [element]);
     
        this._asyncImageSelector = null;
        this._selectImageButton = null;
        this._writeImage = null;
        this._readImage = null;
        this._imageServiceUrl = null;
        this._selectImageButtonClickDelegate = null;
        this._uploadDialog = null;
    };
     
    InstalledWebComponents.CustomControls.ImageField.ImageField.prototype =
    {
        initialize: function () {
            InstalledWebComponents.CustomControls.ImageField.ImageField.callBaseMethod(this, "initialize");
            this._selectImageButtonClickDelegate = Function.createDelegate(this, this._selectImageButtonClicked);
            if (this._selectImageButton) {
                $addHandler(this._selectImageButton, "click", this._selectImageButtonClickDelegate);
            }
     
            if (this._asyncImageSelector) {
                this._uploadDialog = jQuery(this._asyncImageSelector.get_element()).dialog({
                    autoOpen: false,
                    modal: true,
                    width: 540,
                    height: "auto",
                    closeOnEscape: true,
                    resizable: false,
                    draggable: false,
                    zIndex: 5000,
                    dialogClass: "sfSelectorDialog"
                });
                this._asyncImageSelectorInsertDelegate = Function.createDelegate(this, this._asyncImageSelectorInsertHandler);
                this._asyncImageSelector.set_customInsertDelegate(this._asyncImageSelectorInsertDelegate);
            }
        },
     
        dispose: function () {
            InstalledWebComponents.CustomControls.ImageField.ImageField.callBaseMethod(this, "dispose");
            if (this._selectImageButton) {
                $removeHandler(this._selectImageButton, "click", this._selectImageButtonClickDelegate);
            }
     
            if (this._selectImageButtonClickDelegate) {
                delete this._selectImageButtonClickDelegate;
            }
        },
     
        _selectImageButtonClicked: function (sender, args) {
            this._uploadDialog.dialog("open");
            var scrollTopHtml = jQuery("html").eq(0).scrollTop();
            var scrollTopBody = jQuery("body").eq(0).scrollTop();
            var scrollTop = ((scrollTopHtml > scrollTopBody) ? scrollTopHtml : scrollTopBody) + 50;
            jQuery(this._uploadDialog).parent().css({ "top": scrollTop });
     
            try {
                this._asyncImageSelector.get_uploaderView().get_altTextField().set_value("");
            }
            catch (ex) { }
            jQuery(this._asyncImageSelector.get_uploaderView().get_settingsPanel()).hide();
            return false;
        },
     
        _asyncImageSelectorInsertHandler: function (selectedItem) {
            if (selectedItem) {
                this.set_value(selectedItem.Id);
                this._uploadDialog.dialog("close");
            }
        },
     
        set_value: function (value) {
            if (this._displayMode == 0) {
                return;
            }
     
            var imageControl = this._writeImage;
            if (value && value.toString() != "00000000-0000-0000-0000-000000000000") {
                var id = value;
                var url = this._imageServiceUrl + "live/" + id + "/";
                var data = null;
     
                $.ajax({
                    url: url,
                    success: function (data) {
                        var imageUrl = data["Item"]["MediaUrl"];
                        if (imageControl) {
                            jQuery(imageControl).attr("src", imageUrl);
                        }
                    }
                });
            } else {
                if (imageControl) {
                    jQuery(imageControl).attr("src", "data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==");
                }
            }
            InstalledWebComponents.CustomControls.ImageField.ImageField.callBaseMethod(this, "set_value", [value]);
        },
     
        get_asyncImageSelector: function () {
            return this._asyncImageSelector;
        },
     
        set_asyncImageSelector: function (value) {
            this._asyncImageSelector = value;
        },
     
        get_selectImageButton: function () {
            return this._selectImageButton;
        },
     
        set_selectImageButton: function (value) {
            this._selectImageButton = value;
        },
     
        get_writeImage: function () {
            return this._writeImage;
        },
     
        set_writeImage: function (value) {
            this._writeImage = value;
        },
     
        get_readImage: function () {
            return this._readImage;
        },
     
        set_readImage: function (value) {
            this._readImage = value;
        },
     
        get_imageServiceUrl: function () {
            return this._imageServiceUrl;
        },
     
        set_imageServiceUrl: function (value) {
            this._imageServiceUrl = value;
        }
    };
     
    InstalledWebComponents.CustomControls.ImageField.ImageField.registerClass("InstalledWebComponents.CustomControls.ImageField.ImageField", Telerik.Sitefinity.Web.UI.Fields.FieldControl);

    ImageFieldDefinition.cs

    using Telerik.Sitefinity.Configuration;
    using Telerik.Sitefinity.Web.UI.Fields.Definitions;
     
    namespace InstalledWebComponents.CustomControls.ImageField
    {
        public class ImageFieldDefinition : FieldControlDefinition
        {
            public ImageFieldDefinition()
            {
     
            }
     
            public ImageFieldDefinition(ConfigElement configDefinition)
                : base(configDefinition)
            {
     
            }
        }
     
    }

    ImageFieldDefinitionElement.cs

    using System;
    using Telerik.Sitefinity.Configuration;
    using Telerik.Sitefinity.Web.UI;
    using Telerik.Sitefinity.Web.UI.Fields.Config;
     
    namespace InstalledWebComponents.CustomControls.ImageField
    {
        public class ImageFieldDefinitionElement : FieldControlDefinitionElement
        {
     
            #region Constructors
     
            public ImageFieldDefinitionElement(ConfigElement parent)
                : base(parent)
            {
     
            }
     
            #endregion
     
            #region FieldControlDefinitionElement members
            public override DefinitionBase GetDefinition()
            {
                return new ImageFieldDefinition(this);
            }
     
            #endregion
     
            #region IFieldDefinition members
            public override Type DefaultFieldType
            {
                get
                {
                    return typeof(ImageField);
                }
            }
     
            #endregion
        }
    }

  23. Lurch
    Lurch avatar
    64 posts
    Registered:
    18 Jan 2011
    08 Jul 2013 in reply to Brett Whittington
    Link to this post
    Not sure if this will work, because I already have a widget, which I want to embed a link to the "Select an Image" within. So in effect, I want to place the Sitefinity image widget, within my own widget.

    If anybody has the source code for Sitefinity's 5.4 image widget, or a way to extend that widget into a new one, I'd very much like to review your ideas. Thanks.
  24. Lurch
    Lurch avatar
    64 posts
    Registered:
    18 Jan 2011
    08 Jul 2013
    Link to this post
    Another thing that may help, is that this is NOT the widgets controller, but in the widget itself. It is designed to display along with the widget's contents, not as part of it's property display in the control designer.

    So I guess this is why a lot of the examples are not working for me, as I'm trying to use them in the widget itself, and the code assumes I am using the designer associated the widget?
  25. Luyen Minh
    Luyen Minh avatar
    9 posts
    Registered:
    27 Oct 2014
    03 Dec 2014
    Link to this post

    Hi William/Ivan,

    I'm using this code as below:

    Type.registerNamespace("SitefinityWebApp.WidgetDesigners.ExperienceContentWidget");



    SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner = function (element) {
        /* Initialize Message fields */
        this._title = null;
        this._hTMLContent = null;
        this._overlayPosition = null;
        this._overlayWidth = null;
        this._overlayColor = null;
        this._backgroundImage = null;
        
        //this._selectorView = null;
        //this._itemSelectDelegate = null;
        this._newEmployeeImage = null;
        this._insertBackGround = null;
        
        this._backGroundSelectorView = null;
        this._itemSelectDelegate = null;
        this.selectedImageUrl = null;
        
        /* Calls the base constructor */
        SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner.initializeBase(this, [element]);
    }

    SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner.prototype = {
        /* --------------------------------- set up and tear down --------------------------------- */
        initialize: function () {
            /* Here you can attach to events or do other initialization */
            SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner.callBaseMethod(this, 'initialize');
            
            this._itemSelectDelegate = Function.createDelegate(this, this._itemSelect);
            this._backGroundSelectorView.add_onItemSelectCommand(this._itemSelectDelegate);
            //this.add_onItemSelectCommand(this._itemSelectDelegate);
            //this._mediaContentBinderItemDataBoundDelegate = Function.createDelegate(this, this._mediaContentBinderItemDataBound);
        },
        dispose: function () {
            /* this is the place to unbind/dispose the event handlers created in the initialize method */
            SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner.callBaseMethod(this, 'dispose');
            
            if (this._backGroundSelectorView) {
                this._backGroundSelectorView.add_onItemSelectCommand(this._itemSelectDelegate);
            }
        },
        _propertyGridItemSelectCommand: function (sender, args) {
            var dataItem = args.get_dataItem();
            var d = this.get_controlData();
            d.SelectedItemValue = dataItem.Id;
        },

        _mediaContentBinderItemDataBound: function (sender, args) {
            var dataItem = args.get_dataItem();
            var id = dataItem.Id;

        },
        
       

        /* --------------------------------- public methods ---------------------------------- */

        findElement: function (id) {
            var result = jQuery(this.get_element()).find("#" + id).get(0);
            return result;
        },

        /* Called when the designer window gets opened and here is place to "bind" your designer to the control properties */
        refreshUI: function () {
            var controlData = this._propertyEditor.get_control().Settings; /* JavaScript clone of your control - all the control properties will be properties of the controlData too */
            /* RefreshUI Message */
            jQuery(this.get_title()).val(controlData.Title);
            jQuery(this.get_overlayPosition()).val(controlData.OverlayPosition);
            jQuery(this.get_overlayWidth()).val(controlData.OverlayWidth);
            jQuery(this.get_overlayColor()).val(controlData.OverlayColor);
            jQuery(this.get_backgroundImage()).val(controlData.BackgroundImage);
            var editor = $find('HTMLContent');
            if (controlData.HTMLContent != undefined) {
                editor.set_html(controlData.HTMLContent);
            }
           

        },

        /* Called when the "Save" button is clicked. Here you can transfer the settings from the designer to the control */
        applyChanges: function () {
            var controlData = this._propertyEditor.get_control().Settings;

            /* ApplyChanges Message */
            controlData.Title = jQuery(this.get_title()).val();
            controlData.OverlayPosition = jQuery(this.get_overlayPosition()).val();
            controlData.OverlayWidth = jQuery(this.get_overlayWidth()).val();
            controlData.OverlayColor = jQuery(this.get_overlayColor()).val();
            controlData.BackgroundImage = jQuery(this.get_backgroundImage()).val();
            controlData.BackGroundSelectorView = this.get_backGroundSelectorView();
            var backgroundImage = this.get_backGroundSelectorView();
            console.log(backgroundImage);
            var url = this.get_selectedImageUrl();
            console.log(url);
            //console.log(selectedImageUrl);
            console.log(jQuery("#HTMLContent").val());
            var editor = $find('HTMLContent');
            controlData.HTMLContent = editor.get_html();
           

        },

        /* --------------------------------- event handlers ---------------------------------- */

        /* --------------------------------- private methods --------------------------------- */

        /* --------------------------------- properties -------------------------------------- */

        /* Message properties */
        get_title: function () { return this._title; },
        set_title: function (value) { this._title = value; },
        get_hTMLContent: function () { return this._hTMLContent; },
        set_hTMLContent: function (value) { this._hTMLContent = value; },
        get_overlayPosition: function () { return this._overlayPosition; },
        set_overlayPosition: function (value) { this._overlayPosition = value; },
        get_overlayWidth: function () { return this._overlayWidth; },
        set_overlayWidth: function (value) { this._overlayWidth = value; },
        get_overlayColor: function () { return this._overlayColor; },
        set_overlayColor: function (value) { this._overlayColor = value; },
        get_backgroundImage: function () { return this._backgroundImage; },
        set_backgroundImage: function (value) { this._backgroundImage = value; },
        get_newEmployeeImage: function () {
            return this._newEmployeeImage;
        },
        set_newEmployeeImage: function (value) {
            this._newEmployeeImage = value;
        },
        get_insertBackGround: function () {
            return this._insertBackGround;
        },
        set_insertBackGround: function (value) {
            this._insertBackGround = value;
        },
        get_backGroundSelectorView: function () {
            return this._backGroundSelectorView;
    },
        set_backGroundSelectorView: function (value) {
            this._backGroundSelectorView = value;
        },
        get_selectedImageUrl: function () {
            return this.selectedImageUrl;
    },
        set_selectedImageUrl: function (value) {
            this.selectedImageUrl = value;
        },
        _itemSelect: function (sender, args) {
            var dataItem = args.get_dataItem();
            set_selectedImageUrl(dataItem.MediaUrl);
        },

        add_onItemSelectCommand: function (delegate) {
            this.get_events().addHandler('onItemSelectCommand', delegate);
        },
     
       
    }

    SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner.registerClass('SitefinityWebApp.WidgetDesigners.ExperienceContentWidget.ExperienceContentWidgetDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);


    But it has a error with message: Uncaught TypeError: undefined is not a function

    please tell me why.

    Thanks.

  26. Brett Whittington
    Brett Whittington avatar
    33 posts
    Registered:
    12 Jan 2012
    11 Dec 2014 in reply to Luyen Minh
    Link to this post
    I didn't see anything inherently wrong in your code but usually it is a naming issue.  Your properties and methods having different names, forgotten ones, casing issues.  When I run into these errors, I generally comment out a property at a time from my widget designers ascx, js, and cs until it works.  Then I figure out what is wrong with that property/control
26 posts, 1 answered