Problem creating designer for custom widget - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Problem creating designer for custom widget

  • Problem creating designer for custom widget
  • I am having a problem creating my designer with multiple properties. I followed the Hello World tutorial and was able to get that working properly but now I am trying to add page selector and title properties. I keep getting a javascript error "b is undefined" and the edit screen is completely blank. Can't seem to figure out why this is happening. Below is my code for my designer.

    I have 3 properties in my widget. Message, ButtonTitle, PageID

    SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner = function (element)
        this._Message = null;
        this._ButtonTitle = null;
        this._PageSelector = null;
        SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner.initializeBase(this, [element]);
    SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner.prototype =
        /* --------------------------------- set up and tear down --------------------------------- */
        initialize: function ()
            /* Here you can attach to events or do other initialization */
            SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner.callBaseMethod(this, 'initialize');
        dispose: function ()
            /* this is the place to unbind/dispose the event handlers created in the initialize method */
            SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner.callBaseMethod(this, 'dispose');
        /* --------------------------------- public methods ---------------------------------- */
        /* 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(); /* JavaScript clone of your control - all the control properties will be properties of the controlData too */
            /* RefreshUI Message */
            var p = this.get_PageSelector();
            var pageid = controlData.SelectedPageID;
            if (pageid) p.set_value(pageid);
        /* 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();
            controlData.Message = jQuery(this.get_Message()).val();
            controlData.PageID = this.get_PageSelector().get_value();
            controlData.ButtonTitle = jQuery(this.get_Button()).val();
        /* --------------------------------- event handlers ---------------------------------- */
        /* --------------------------------- private methods --------------------------------- */
        findElement: function (id)
            var result = jQuery(this.get_element()).find("#" + id).get(0);
            return result;
        /* --------------------------------- properties -------------------------------------- */
        /* Message properties */
        get_Message: function () return this._Message; ,
        get_Button: function () return this._ButtonTitle; ,
        get_PageSelector: function () return this._PageSelector; ,
        set_Message: function (value) this._Message = value; ,
        set_Button: function (value) this._ButtonTitle = value; ,
        set_PageSelector: function (value) this._PageSelector = value;
    SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner.registerClass('SitefinityWebApp.Widgets.EmptyLeg.Designer.EmptyLegListDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);

    #region Properties
            /// <summary>
            /// Gets the layout template path
            /// </summary>
            public override string LayoutTemplatePath
                    return EmptyLegListDesigner.layoutTemplatePath;
            /// <summary>
            /// Gets the layout template name
            /// </summary>
            protected override string LayoutTemplateName
                    return String.Empty;
            protected override HtmlTextWriterTag TagKey
                    return HtmlTextWriterTag.Div;
            #region Control references
            /// <summary>
            /// Gets the control that is bound to the Message property
            /// </summary>
            protected virtual TextBox Message
                get return this.Container.GetControl<TextBox>("Message", true);
            protected virtual TextBox ButtonTitle
                get return this.Container.GetControl<TextBox>("ButtonTitle", true);
            protected PageField PageSelector
                get return Container.GetControl<PageField>("PageSelector", true);
            /// <summary>
            /// Gets or sets the ID of the selected page.
            /// </summary>
            /// <value>
            /// The selected page ID.
            /// </value>
            public Guid SelectedPageID get; set;
            #region Methods
            protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container)
                // Place your initialization logic here
                this.PageSelector.RootNodeID = Telerik.Sitefinity.Abstractions.SiteInitializer.FrontendRootNodeId;
            #region IScriptControl implementation
            /// <summary>
            /// Gets a collection of script descriptors that represent ECMAScript (JavaScript) client components.
            /// </summary>
            public override System.Collections.Generic.IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
                var scriptDescriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());
                var descriptor = (ScriptControlDescriptor)scriptDescriptors.Last();
                descriptor.AddElementProperty("Message", this.Message.ClientID);
                descriptor.AddElementProperty("ButtonTitle", this.ButtonTitle.ClientID);
                descriptor.AddElementProperty("PageSelector", this.PageSelector.ClientID);
                return scriptDescriptors;
            /// <summary>
            /// Gets a collection of ScriptReference objects that define script resources that the control requires.
            /// </summary>
            public override System.Collections.Generic.IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
                var scripts = new List<ScriptReference>(base.GetScriptReferences());
                scripts.Add(new ScriptReference(EmptyLegListDesigner.scriptReference));
                return scripts;
            #region Private members & constants
            public static readonly string layoutTemplatePath = "~/Widgets/EmptyLeg/Designer/EmptyLegListDesigner.ascx";
            public const string scriptReference = "~/Widgets/EmptyLeg/Designer/EmptyLegListDesigner.js";

    <%@ Register Assembly="Telerik.Sitefinity" TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" %>
    <%@ Register Assembly="Telerik.Sitefinity" TagPrefix="sitefinity" Namespace="Telerik.Sitefinity.Web.UI" %>
    <%@ Register Assembly="Telerik.Sitefinity" TagPrefix="sfFields" Namespace="Telerik.Sitefinity.Web.UI.Fields" %>
    <sitefinity:ResourceLinks ID="resourcesLinks" runat="server">
        <sitefinity:ResourceFile Name="Styles/Ajax.css" />
    <sitefinity:FormManager ID="formManager" runat="server" />
    <div class="sfContentViews sfSingleContentView" style="max-height: 600px; overflow: auto; ">
            <li class="sfFormCtrl">
                <asp:Label runat="server" AssociatedControlID="Message" CssClass="sfTxtLbl">Message</asp:Label>
                <asp:TextBox ID="Message" runat="server" CssClass="sfTxt" ClientIDMode="Static" />
                <div class="sfExample">The label's message</div>
            <li class="sfFormCtrl">
                <asp:Label ID="lblTitle" runat="server" AssociatedControlID="ButtonTitle" CssClass="sfTxtLbl">Button Title</asp:Label>
                <asp:TextBox ID="ButtonTitle" runat="server" CssClass="sfTxt" ClientIDMode="Static" />
                <div class="sfExample">The title shown on the button</div>
            <li class="sfFormCtrl">
                <asp:Label ID="Label1" runat="server" AssociatedControlID="PageSelector" CssClass="sfTxtLbl">Page</asp:Label>
                <sfFields:PageField ID="PageSelector" runat="server" WebServiceUrl="~/Sitefinity/Services/Pages/PagesService.svc/" DisplayMode="Write" ClientIDMode="Static" />
                <div class="sfExample">The page user is redirected to</div>

    Any help would be great because Im at a loss right now and can't move further.


  • this usually happens if the designer script isn't loaded properly or if the namespaces in it don't match the control. can you verify that your designer js file is loaded with a tool like firebug?

    Also, I highly recommend you now use Sitefinity Thunder for this, as it has an item template to build a designer for an existing widget that will let you assign a Page Selector to a Guid property automatically.
    hope this is helpful!
  • I feel your pain here.  The javascript error messages that the template designers give are very hard to understand because the variable names are not meaningful.  I took the code you provided and slapped it on one of my user controls on my project to see if I could help you.  Lo and behold, I was able to reproduce the error with your code.

    To solve your error you will need to change the following in your Designer.cs
    descriptor.AddElementProperty("Message", this.Message.ClientID);
    descriptor.AddElementProperty("ButtonTitle", this.ButtonTitle.ClientID);
    descriptor.AddElementProperty("PageSelector", this.PageSelector.ClientID);
    descriptor.AddComponentProperty("Message", this.Message.ClientID);
    descriptor.AddComponentProperty("Title", this.Title.ClientID);
    descriptor.AddComponentProperty("PageSelector", this.PageSelector.ClientID);

    I am honestly not sure why AddComponentProperty works and AddElementProperty doesn't but I remembered having your error before and that is how I fixed.  After changing that I received some more JavaScript errors but with different messages.  If you do get passed your initial error and receive more try changing the following item in your code.

    1) Change your textboxes to Sitefinity TextFields.  I had trouble getting textboxes to work with correctly and changing them to text fields fixed the next errors I received.  You will need to make changes in your Designer.ascx and Designer.cs for this.

    The best way to debug errors like this is to comment out all of your controls being added in the GetScriptDescriptors() method and turn them on one by one to see which one is throwing the error.  It then can get easier to narrow down what is different with that control compared to the other ones.

    After this, I keep running into problems with your ButtonTitle property.  If I do not add its descriptor, everything works fine.  I've tried copying and pasting Message and changing it into ButtonTile, renaming ButtonTitle, and even moving it first in the code but system always throws an error with ButtonTitle. 

    If you can make the above changes, hopefully you odn't run into what I did with ButtonTitle but they should get you moving in the right direction.
  • Sorry, I figured it out. thanks, I got it working.
  • I've never experienced the bug you are getting now and I do not know where to begin.  I don't ever use Thunder so I am not sure I can help you anymore.  Maybe SelAromDotNet can give you some additional help. Good luck!
  • Not sure if you will see this, but is there any chance you can elaborate on your fix?

    I am experiencing the exact same issue and cannot seem to find what I am missing. As soon as I try to add another descriptor of any sort to the GetScriptDescriptors() method it causes my designer widget to be a blank window.

    Any help would be greatly appreciated!!

  • Hi Christopher,

    Looking through Daniel's code the problem is that all Button references should be with the ID of the control by convention. See the following:

    get_Button: function () return this._ButtonTitle; ,

    this will throw the "b is not defined" because the actual ID from the template is:
    <asp:TextBox ID="ButtonTitle" runat="server" CssClass="sfTxt" ClientIDMode="Static" />

    so it needs to be referenced like so:
    get_ButtonTitle: function () return this._ButtonTitle; ,

    When all of those have been replaced the designer ran properly on my side.

    Additionally please inspect you Namespaces like Josh suggested.

    All the best,
    Pavel Benov
    the Telerik team
  • That did the trick.

    Thanks all for the help!

  • In response to Brett Whittington's first post, I would like to say first of all thank you. You gave an answer, and although it didn't help me directly, it showed me how to debug. I have a problem though. I was doing the same thing that D.Tharp was doing, which was adding fields to a widget, and I ran into some crazy error when I clicked edit. It looked like I added all of the changes that would make the new fields work, but since it didn't, I decided to do what Brett suggested, which was comment out all of the changes, then add them one by one.

    The problem is, I commented everything out, and it still doesn't work! I still get some crazy 500 internal server error. Why doesn't sitefinity go back to the way it was? How is it saving things that when I build, and then revert, they are still there (You know what I mean). I keep cleaning and rebuilding, and I still get this error. Do I have to restart my computer? 

  • Hello Jeremy,

    It is really strange. Most probably there is some custom logic that you have not commented out and this causing the issue. It is really hard to say what is the exact issue since the error message you are getting (Internal server error 500) does not provide sufficient information to say what exactly is causing the issue.

    Can you please also inspect the browser's console to check if there are any errors logged there which may provide more details about the issue?

    What I can also suggest is to take a look at the following resources for more details about creating widget designers:

    Create a simple widget designer
    Thunder: Create widget designers
    Creating a Custom Widget Designer using Sitefinity and Sitefinity Thunder Part 1
    Creating a Custom Widget Designer Using Sitefinity and Sitefinity Thunder Part 2

    Sabrie Nedzhip
    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 Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items