Custom Control Designer

Posted by Community Admin on 03-Aug-2018 17:06

Custom Control Designer

All Replies

Posted by Community Admin on 10-Jan-2011 00:00

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();

Posted by Community Admin on 10-Jan-2011 00:00

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

Posted by Community Admin on 16-Jun-2011 00:00

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

Posted by Community Admin on 16-Jun-2011 00:00

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

Posted by Community Admin on 16-Jun-2011 00:00

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

Posted by Community Admin on 20-Jun-2011 00:00

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

Posted by Community Admin on 11-Jul-2011 00:00

Hi Ivan,

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

www.sitefinity.com/.../custom-control-designer.aspx

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

Posted by Community Admin on 11-Jul-2011 00:00

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 :)

Posted by Community Admin on 11-Jul-2011 00:00

Hello Cii,

There is a difference.Please take a look at

forums.asp.net/.../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

This thread is closed