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

Forums / General Discussions / Custom Control Designer

Custom Control Designer

9 posts, 0 answered
  1. Jerami Tainter
    Jerami Tainter avatar
    27 posts
    Registered:
    29 Oct 2009
    10 Jan 2011
    Link to this post
    Is there an example of a custom designer out there I can reference?  I followed the tutorial here:

    http://www.sitefinity.com/4.0/documentation/how-to-create-a-widget/advanced/writing-the-javascript-for-the-dialog.aspx

    But I still cannot load/save data...dont know what im doing wrong...my javascript looks like this:

    Type.registerNamespace("RogueContent");


    RogueContent.RogueContentDesigner = function (element) {
        // element
        this._radEditorControl = null;
        RogueContent.RogueContentDesigner.initializeBase(this, [element]);
    }


    RogueContent.RogueContentDesigner.prototype = {
        initialize: function () {
            RogueContent.RogueContentDesigner.callBaseMethod(this, 'initialize');
        },
        dispose: function () {
            RogueContent.RogueContentDesigner.callBaseMethod(this, 'dispose');
        },
        get_radEditorControl: function () {
            return this._radEditorControl;
        },
        set_radEditorControl: function (value) {
            this._radEditorControl = value;
        },


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


        //refreshes the UI overrides the base interface


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


            jQuery("#Title").val(data.Title);


            //this.get_radEditorControl().set_html(data.Content);
        },


        // forces the designer to apply the changes on UI to the cotnrol Data
        applyChanges: function () {
            var data = this.get_controlData();


            //data.Content = this.get_radEditorControl().get_html();
            data.Title = jQuery("#Title").val();
        }


    }


    RogueContent.RogueContentDesigner.registerClass('RogueContent.RogueContentDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);


    if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    10 Jan 2011
    Link to this post
    Hi Jerami,

    Here is a sample control

    1. You need a class with a template.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Sitefinity.Web.UI;
      
    using System.Web.UI;
    using Telerik.Sitefinity.Modules.Pages.Web.UI;
    using Telerik.Sitefinity.Web.UI.ControlDesign;
    using Telerik.Web.UI;
    using Telerik.Sitefinity.Modules.Pages;
      
      
    namespace Telerik.Sitefinity.Samples
    {
        [RequireScriptManager]
        [Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesigner(typeof(SimpleViewCustomDesigner))]
        public class SimpleViewCustom : SimpleView
        {
      
            public string SelectedValue { get; set; }
      
            
      
            protected override string LayoutTemplateName
            {
                get { return SimpleViewCustom.layoutTemplateName; }
            }
      
            
      
            private const string layoutTemplateName = "Telerik.Sitefinity.Samples.Resources.SimpleViewTemplate.ascx";
        }
    }

    Inside the control you should have properties that will interact with the control designer. In this property we will save and retrieve some values.

    2. The control designer. Here i will use RadComboBox. The combo is bound on the server - InitializeControls. If you want you can bind it on the client, but this is more complex, because you have to use client side api of the control that you will populate with data.
    As you can see there are two constants - template and script that will be used for getting and setting values to the contorl designer. The RadComboBox client ID is sent to the client, so you can use the object there without issues.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Sitefinity.Modules.Pages.Web.UI;
    using Telerik.Sitefinity.Web.UI.ControlDesign;
    using System.Web.UI;
    using Telerik.Sitefinity.Modules.Pages;
    using Telerik.Sitefinity.Pages.Model;
    using Telerik.Web.UI;
    using System.Web.UI.WebControls;
      
    namespace Telerik.Sitefinity.Samples
    {
          
       public class SimpleViewCustomDesigner : ControlDesignerBase
        {
             
            protected override string LayoutTemplateName
            {
                get { return SimpleViewCustomDesigner.layoutTemplateName; }
            }
      
            #region Methods
      
            protected override void InitializeControls(Web.UI.GenericContainer container)
            {
      
      
                base.DesignerMode = ControlDesignerModes.Simple;
                base.AdvancedModeIsDefault = false;
     
      
                if (Combo1 != null)
                {
                    Combo1.Items.Add(new RadComboBoxItem("test", "test"));
                    Combo1.Items.Add(new RadComboBoxItem("test1", "test1"));
                    Combo1.Items.Add(new RadComboBoxItem("test2", "test2"));
                    Combo1.Items.Add(new RadComboBoxItem("test3", "test3"));
                }
      
              
                  
            }
      
            #endregion
      
            #region IScriptControl Members
      
            public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
            {
                var scriptDescriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
                var desc = (ScriptControlDescriptor)scriptDescriptors.Last();
                var combo = this.Combo1;
                desc.AddComponentProperty("comboBoxControl", combo.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 RadComboBox Combo1
            {
                get
                {
                    return this.Container.GetControl<RadComboBox>("RadComboBox1", true);
                }
            }
      
            
      
            #endregion
      
            #region Private fields and constants
      
            private const string layoutTemplateName = "Telerik.Sitefinity.Samples.Resources.SimpleViewCustomDesigner.ascx";
            private const string designerScriptName = "Telerik.Sitefinity.Samples.Resources.SimpleViewDesignerCustom.js";
      
            #endregion
        }
    }

    3. Javascript. Here are the important parts

    - you have to register your namespace.
    - you have to initialize the designer element
    - you should have to properties -get and set for the RadComboBox - get_comboBoxControl and set_comboBoxControl

    - refreshUI and applyChanges functions

    You use data to get or set a property from the Control - SimpleViewCustomDesigner

    Type.registerNamespace("Telerik.Sitefinity.Samples");
      
    Telerik.Sitefinity.Samples.SimpleViewCustomDesigner = function (element) {
      
        // element
        this._comboBoxControl = null;
        Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.initializeBase(this, [element]);
      
    }
      
    Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.prototype = {
      
        initialize: function () {
            Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.callBaseMethod(this, 'initialize');
      
        },
      
        dispose: function () {
            Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.callBaseMethod(this, 'dispose');
      
        },
      
        get_comboBoxControl: function () {
            return this._comboBoxControl;
        },
        set_comboBoxControl: function (value) {
            this._comboBoxControl = value;
        },
      
        /* ----------------------------- public methods ----------------------------- */
      
        //refreshes the UI overrides the base interface
      
        refreshUI: function () {
            this._refreshMode = true;
            var data = this.get_controlData();
            this.get_comboBoxControl().set_value(data.SelectedValue);
        },
      
        // forces the designer to apply the changes on UI to the cotnrol Data
        applyChanges: function () {
            var data = this.get_controlData();
            data.SelectedValue = this.get_comboBoxControl().get_selectedItem().get_value();
      
        }
      
    }
      
    Telerik.Sitefinity.Samples.SimpleViewCustomDesigner.registerClass('Telerik.Sitefinity.Samples.SimpleViewCustomDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);
      
    if (typeof (Sys) !== 'undefined') Sys.Applic


    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
  3. Duneel
    Duneel avatar
    166 posts
    Registered:
    08 Dec 2010
    16 Jun 2011
    Link to this post
    Hi Ivan,

    Is there a way to handle the Save button click event on the client script code? I simply want to validate user entered data.

    Thanks,
    Duneel
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    16 Jun 2011
    Link to this post
    Hi Duneel,


    You can subscribe for the click event of the save button when you initialize the client component

    jQuery(this.get_propertyEditor().get_saveButton())

    Kind regards,
    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
  5. Duneel
    Duneel avatar
    166 posts
    Registered:
    08 Dec 2010
    16 Jun 2011
    Link to this post
    Thanks Ivan. It worked.

    1 more question... How should I stop the dialog being closed after clicking the Save button? I need to leave the control designer opened if the user has entered invalid info. i tried returning "return false;" from the event handler but that didn't work.

    Thanks,
    Duneel
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    20 Jun 2011
    Link to this post
    Hi Duneel,

    Property controls are saved by the component called PropertyEditor. In your designer, you should have such property, as it is defined on the JS interface. PropertyEditor exposes an event called "beforeSaveChanges". So, in your designer you could implement something like this:

    // ... code excluded for simplicity
      
    this._beforeSaveChangesDelegate = Function.createDelegate(this, this._beforeSaveChangesHandler);
    this.get_propertyEditor().add_beforeSaveChanges(this._beforeSaveChangesDelegate);
      
    // ... code excluded for simplicity
      
    _beforeSaveChangesHandler: function (sender, eventArgs) {
            if (this._valuesInvalid == true) {
                // cancel the saving of values
                eventArgs.set_cancel(true);
                // ... implement JS code for showing the warning messages
            }
    }


    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
  7. Cii
    Cii avatar
    10 posts
    Registered:
    13 Jan 2011
    11 Jul 2011
    Link to this post
    Hi Ivan,

    I was having a problem with custom control designer for my custom widget and came across this forum and your post:

    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/general-discussions/custom-control-designer.aspx#1482138

    I am trying to put some listbox on to designer control but I cannot access it in js file. I am trying to write their value using alert with below statement, but it is printing null on the screen...

            ......
            ......
            jQuery("#txtScrollDuration").val(controlData.ScrollDuration);
            jQuery("#txtFrameDuration").val(controlData.FrameDuration);

            alert(this.get_listBoxRotatorDirection()); // this is printing null

    Now, In the js file, you have declared get/set functions for a combobox control.. You initialized the holder "_comboBox" variable with null BUT you never assigned any value to it... I feel like this is the problem I am having. ps: I did not forget to put below line on my GetScriptDescriptors function:

                desc.AddComponentProperty("listBoxRotatorDirection", this.ListBoxRotatorDirection.ClientID);

    But again, you wrote this code on your side by saying
    desc.AddComponentProperty("comboBoxControl", combo.ClientID);
    NOT by saying
    desc.AddComponentProperty("_comboBoxControl", combo.ClientID);

    Am I missing something?? I would attached my designer and control code file bu system allows only image files...

    Thanks,
    Cihan
  8. Cii
    Cii avatar
    10 posts
    Registered:
    13 Jan 2011
    11 Jul 2011
    Link to this post
    Lol, I have found the solution:

    when using listbox, you need to use

        desc.AddElementProperty("listBoxRotatorType", this.ListBoxRotatorType.ClientID);
    instead of
        desc.AddComponentProperty("listBoxRotatorType", this.ListBoxRotatorType.ClientID);

    I do not know why such a difference exists, but it works :)
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    11 Jul 2011
    Link to this post
    Hello Cii,

    There is a difference.Please take a look at

    http://forums.asp.net/p/1103167/1681438.aspx

    Greetings,
    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
9 posts, 0 answered