Custom Widget designer error

Posted by Community Admin on 04-Aug-2018 17:53

Custom Widget designer error

All Replies

Posted by Community Admin on 20-Apr-2016 00:00

I am creating a custom donation module, I do not understand why my JavaScript functions are accessible in one function/area and not another. For example in the designer js file below I have the function _designaitonListToArray() which exists and is accessible in the _addButtonClicked function but not _moveDesignationItemUp.  I have an basic understanding of javascript and I am unsure of the javascript page life cycle. 

 

I am trying to create a list of items(designations in this case) to load on the public view. This list needs to have the ability to  remove an item, move an item up, and move an item down; your basic list management functions.  Currently list items are created dynamically with the necessary management buttons. The remove works but throws a function does not exists error but works anyway, my assumption is the click event binding is in correct, but not sure how to fix. 

Control properties being set:

 private Guid _campaignId;        
private string _designationList;         
public Guid DesginationId get; set;         
public string Campaign get; set;         
public Guid CampaignId get return _campaignId; set _campaignId = value;         
public bool ShowPopup get; set;                
public string DesignationList get return _designationList; set _designationList = value;

Designer js

Type.registerNamespace("SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation");SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner = function (element)      /* Initialize  fields */     this._desginationId = null;     this._campaignId = null;     this._showAmountPopup = null;     this._campaignSelector = null;     this._ddlDesignations = null;     this._addDesignationButton = null;     //this._selectDesignationDialog = null;     this._addDesignationButtonDelegate = null;     this._removeDesignationButtonDelegate = null;     this._designationOptions = null;     console.log("initialize vars");         /* Calls the base constructor */     SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner.initializeBase(this, [element]);SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner.prototype =      /* --------------------------------- set up and tear down --------------------------------- */     /* Here you can attach to events or do other initialization */     initialize: function ()          console.log("initialize func");         if (this._addDesignationButton)              this._addDesignationButtonDelegate = Function.createDelegate(this, this._addButtonClicked);             $addHandler(this._addDesignationButton, "click", this._addDesignationButtonDelegate);                      //can not bind to dynamically created content         this._removeBottonClicked;         this._moveDesignationItemUp;         /* Here you can attach to events or do other initialization */         SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner.callBaseMethod(this, 'initialize');     ,     dispose: function ()          console.log("dispose");         /* this is the place to unbind/dispose the event handlers created in the initialize method */         SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner.callBaseMethod(this, 'dispose');     ,     /* --------------------------------- public methods ---------------------------------- */     /* Called when the designer window gets opened and here is place to "bind" your designer to the control properties */     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 */         console.log("refresh");         var tempArray = new Array();         var designationListData = controlData.DesignationList;         if (designationListData != null && designationListData != "")              var dataItems = JSON.parse(designationListData);             for (var i = 0; i < dataItems.length; i++)                  tempArray.push(                     id: dataItems[i].id,                     name: dataItems[i].name                 );                          this._setDesignationList(tempArray);                  /* RefreshUI Message */         // jQuery(this.get_desginationId()).val(controlData.DesginationId);         jQuery(this.get_campaignId()).val(controlData.Campaign);         jQuery(this.get_campaignSelector()).val(controlData.CampaignId);         jQuery(this.findElement("chkShowPopupText")).prop('checked', controlData.ShowPopup);         console.log("exist refresh");     ,     /* 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 */         console.log("apply changes");         controlData.DesginationId = jQuery(this.get_desginationId()).val();         controlData.Campaign = jQuery(this.get_campaignId()).val();         controlData.CampaignId = jQuery(this.get_campaignSelector()).val();         controlData.DesignationList = JSON.stringify(this._designaitonListToArray());         //var showPopup = $("#" + this._showAmountPopup.id).prop('checked');         controlData.ShowPopup = jQuery(this.findElement("chkShowPopupText")).prop('checked');     ,     /* --------------------------------- event handlers ---------------------------------- */         _addButtonClicked: function (sender, args)          //todo: allow only unique designations         var designationArray = this._designaitonListToArray();         var designationToAdd = jQuery(this.get_ddlDesignations());         console.log("add button clicked");                 if(!this._designationListContains(designationArray,designationToAdd.val()))             designationArray.push(                 id: designationToAdd.val(),                 name: designationToAdd.find("option:selected").text()             );                      this._setDesignationList(designationArray);         else             alert("designations must be unique");                      return false;              ,     _removeBottonClicked: function (value)          console.log("remove button clicked");         var tempArray = new Array();         ////if (this._designationList == null)          if (value.toElement == undefined)  return;          var currentId = value.toElement.id.replace('_ItemRemove', '');         var listItems = $('#' + ($('#' + value.toElement.id).closest('ul').attr('id')) + ' li')         listItems.each(function (index, li)              if (currentId != li.id)                  tempArray.push(                     id: li.id,                     name: $(li).find('span').clone().children().remove().end().text()                 );                          // console.log(li.id)             //console.log($(li).find('span').clone().children().remove().end().text());         );         //ToDo: centralize designation list creation         //this._setDesignationList(tempArray);         $('.manageList').empty();         for (var i = 0; i < tempArray.length; i++)              $("<li id='" + tempArray[i].id + "'><span>" + tempArray[i].name + "<a id='" + tempArray[i].id + "_ItemUp' class='designationItemUp' onclick='_moveDesignationItemUp(this)'>Up</a><a id='" + tempArray[i].id + "_ItemDown' class='designationItemDown' onclick='_moveDesignationItemDown(this)'>Down</a><a id='" + tempArray[i].id + "_ItemRemove' class='designationItemRemove' onclick='_removeBottonClicked(this)'>Remove</a></span></li>").appendTo('.manageList');             ////bind click event             $('#' + tempArray[i].id + '_ItemUp').bind('click', this._moveDesignationItemUp);             $('#' + tempArray[i].id + '_ItemDown').bind('click', this._moveDesignationItemDown);             $('#' + tempArray[i].id + '_ItemRemove').bind('click', this._removeBottonClicked);                  //  console.log("new array "+tempArray[0].id + " " + tempArray[0].name);         console.log("exist remove button clicked");     ,     _moveDesignationItemUp: function (value)          //get array         var currentList = this._designaitonListToArray();         if (value.toElement == undefined)  return;          var currentId = value.toElement.id.replace('_ItemUp', '');         //get index of item clicked         var currentIndex= this._indexOfObject(currentList,currentId);                 var newLocationItem = currentList[currentIndex-1];         var itemToMove = currentList[currentId];         //move         currentList[currentIndex-1] = itemToMove;         currentList[currentIndex] = newLocationItem;         this._setDesignationList(currentList);                  return false;     , _moveDesignationItemDown: function (value)      ,        _setDesignationList: function (list)          console.log("set designation");         $('.manageList').empty();//clear list          for (var i = 0; i < list.length; i++)              $("<li id='" + list[i].id + "'><span>" + list[i].name + "<a id='" + list[i].id + "_ItemUp' class='designationItemUp' onclick='_moveDesignationItemUp(this)'>Up</a><a id='" + list[i].id + "_ItemDown' class='designationItemDown' onclick='_moveDesignationItemDown(this)'>Down</a><a id='" + list[i].id + "_ItemRemove' class='designationItemRemove' onclick='_removeBottonClicked(this)'>Remove</a></span></li>").appendTo('.manageList');             ////bind click event             $('#' + list[i].id + '_ItemUp').bind('click', this._moveDesignationItemUp);             $('#' + list[i].id + '_ItemDown').bind('click', this._moveDesignationItemDown);             $('#' + list[i].id + '_ItemRemove').bind('click', this._removeBottonClicked);                  console.log('designation count: ' + list.length);         console.log("exist set designation");     ,     /* --------------------------------- private methods --------------------------------- */         _designaitonListToArray:function ()         var tempArray = new Array();         var designations = $('.manageList li')         designations.each(function (index, li)              tempArray.push(                 id: li.id,                 name: $(li).find('span').clone().children().remove().end().text()             );         );         return tempArray;     ,     _designationListContains:function(array,designationId)         for(var i=0;i<array.length;i++)             if(array[i].id == designationId)                 return true;                               return false;     ,     _indexOfObject: function(array, id)         for(var i=0;i<array.length;i++)             if(array[i].id == designationId)                 return i;                               return -1;     ,     /* --------------------------------- properties -------------------------------------- */     get_desginationId: function ()  return this._desginationId; ,     set_desginationId: function (value)  this._desginationId = value; ,     get_campaignId: function ()  return this._campaignId; ,     set_campaignId: function (value)  this._campaignId = value; ,     get_showAmountPopup: function ()          if (this._showAmountPopup = null)              this._showAmountPopup = this.findElement("chkShowPopupText");                  return this._showAmountPopup;     ,     set_showAmountPopup: function (value)  this._showAmountPopup = value; ,     get_campaignSelector: function ()          if (this._campaignSelector == null)              this._campaignSelector = this.findElement('ddlCampaigns');                  return this._campaignSelector;     ,     set_campaignSelector: function (value)  this._campaignSelector = value; ,     get_addDesignationButton: function ()          if (this._addDesignationButton == null)              this._addDesignationButton = this.findElement('addDesignationButton');                  return this._addDesignationButton;     ,     set_addDesignationButton: function (value)          this._addDesignationButton = value;     ,     get_designationOptions: function ()          if (this._designationOptions == null)              this._designationOptions = this.findElement('designationOptions');                  return this._designationOptions;     ,     set_designationOptions: function (value)          this._designationOptions = value;     ,     get_ddlDesignations: function ()          if (this._ddlDesignations == null)              this._ddlDesignations = this.findElement('ddlDesignations');                  return this._ddlDesignations;     ,     set_ddlDesignations: function (value)  this._ddlDesignations = value; ,SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner.registerClass('SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation.SingleStepDonationDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);

 

Designer cs

using System; using System.Linq; using System.Web.UI; using Telerik.Sitefinity.Web.UI; using Telerik.Sitefinity.Web.UI.ControlDesign; using System.Collections.Generic; using System.Web.UI.WebControls; using Telerik.Sitefinity.DynamicModules; using Telerik.Sitefinity.Utilities.TypeConverters; using Telerik.Sitefinity.Model; using MedicalTeams.Custom.Data; using System.Web.UI.HtmlControls; using Telerik.Sitefinity.Modules.Pages; namespace SitefinityWebApp.WidgetDesigners.Donation.SingleStepDonation     /// <summary>     /// Represents a designer for the <typeparamref name="SitefinityWebApp.Mvc.Controllers.SingleStepDonationController"/> widget     /// </summary>     public class SingleStepDonationDesigner : ControlDesignerBase              #region Properties         /// <summary>         /// Obsolete. Use LayoutTemplatePath instead.         /// </summary>         protected override string LayoutTemplateName                      get                              return string.Empty;                               /// <summary>         /// Gets the layout template's relative or virtual path.         /// </summary>         public override string LayoutTemplatePath                      get                              if ( string.IsNullOrEmpty(base.LayoutTemplatePath) )                     return SingleStepDonationDesigner.layoutTemplatePath;                 return base.LayoutTemplatePath;                          set                              base.LayoutTemplatePath = value;                               protected override HtmlTextWriterTag TagKey                      get                              return HtmlTextWriterTag.Div;                               #endregion        #region Control references         protected virtual DropDownList ddlDesignations                      get                              return this.Container.GetControl<DropDownList>("ddlDesignations", true);                               protected virtual DropDownList ddlCampaigns                      get                              return this.Container.GetControl<DropDownList>("ddlCampaigns", true);                               protected virtual TextBox campaignId                      get                              return this.Container.GetControl<TextBox>("campaignId", true);                               protected virtual CheckBox showAmountPopup                      get                              return this.Container.GetControl<CheckBox>("chkShowPopupText", true);                               protected virtual HyperLink addDesignationButton                      get                              return this.Container.GetControl<HyperLink>("addDesignationButton", true);                               protected virtual HtmlGenericControl designationOptions                      get                              return this.Container.GetControl<HtmlGenericControl>("designationOptions", true);                                        #endregion        #region Methods         protected override void InitializeControls(Telerik.Sitefinity.Web.UI.GenericContainer container)                      // Place your initialization logic here             SetDesignationDropDown();             GetDigitalCampaigns();           //  SetDesignationPickList();                         private void SetDesignationDropDown()                      var designationList = new Dictionary<Guid, string>();             var providerName = String.Empty;             DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(providerName);             Type designationType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Designations.Designation");             var myCollection = dynamicModuleManager.GetDataItems(designationType).Where(x => x.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live && x.Visible == true);             foreach ( var designation in myCollection )                              designationList.Add(designation.Id, designation.GetValue<Lstring>("Designation"));                          ddlDesignations.DataSource = designationList;             ddlDesignations.DataTextField = "Value";             ddlDesignations.DataValueField = "Key";             ddlDesignations.DataBind();             ddlDesignations.Items.Insert(0, new ListItem("All Designations", Guid.Empty.ToString()));                  private void GetDigitalCampaigns()                      var campaigns = MedicalTeams.Custom.Services.CampaignService.GetOnlineCampaigns();             foreach ( var campaign in campaigns )                              ddlCampaigns.Items.Add(new ListItem()  Text = String.Format("(0)- 1", campaign.CampaignId, campaign.Name), Value = campaign.Id.ToString() );                          ddlCampaigns.DataBind();             ddlCampaigns.Items.Insert(0, new ListItem("Select Campaign", Guid.Empty.ToString()));                  #endregion        #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("desginationId", this.ddlDesignations.ClientID);             descriptor.AddElementProperty("campaignId", this.campaignId.ClientID);             descriptor.AddElementProperty("showAmountPopup", this.showAmountPopup.ClientID);             descriptor.AddElementProperty("campaignSelector", this.ddlCampaigns.ClientID);             descriptor.AddElementProperty("addDesignationButton", this.addDesignationButton.ClientID);             descriptor.AddElementProperty("designationOptions", this.designationOptions.ClientID);             descriptor.AddElementProperty("ddlDesignations", this.ddlDesignations.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(SingleStepDonationDesigner.scriptReference));             return scripts;                  /// <summary>         /// Gets the required by the control, core library scripts predefined in the <see cref="ScriptRef"/> enum.         /// </summary>         protected override ScriptRef GetRequiredCoreScripts()                      return ScriptRef.JQuery | ScriptRef.JQueryUI | ScriptRef.KendoAll;                  #endregion        #region Private members & constants         public static readonly string layoutTemplatePath = "~/WidgetDesigners/Donation/SingleStepDonation/SingleStepDonationDesigner.ascx";         public const string scriptReference = "~/WidgetDesigners/Donation/SingleStepDonation/SingleStepDonationDesigner.js";         #endregion     

 

Designer ascx

<%@ Control %><%@ 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:ResourceLinks><sf:ResourceLinks ID="scriptResources" runat="server">     <sf:ResourceFile JavaScriptLibrary="JQuery" />     <sf:ResourceFile JavaScriptLibrary="JQueryUI" />     <sf:ResourceFile JavaScriptLibrary="KendoAll" /></sf:ResourceLinks><div id="designerLayoutRoot" class="sfContentViews sfSingleContentView" style="max-height: 400px; overflow: auto;">     <div class="sfFormCtrl">         <label>Campaign ID</label><br />         <small>Campaigns in online category only '(Campaign Id)- Campaign Name'</small>         <asp:DropDownList ID="ddlCampaigns" runat="server"></asp:DropDownList>         <asp:TextBox ID="campaignId" runat="server" Style="display: none" />     </div>     <div id="designationSelection" class="sfFormCtrl">         <label for="ddlDesignations">Select Designation</label>         <br />         <asp:DropDownList ID="ddlDesignations" runat="server"></asp:DropDownList>         <asp:HyperLink ID="addDesignationButton" runat="server" NavigateUrl="javascript:void(0);" CssClass="sfLinkBtn sfChange" >             <strong class="sfLinkBtnIn">Add                 </strong>         </asp:HyperLink>         <div id="designationSelector">             <h2>Designation List</h2>             <ul id="designationOptions" runat="server" class="manageList">                              </ul>         </div>     </div>     <div style="padding-top: 10px">         <asp:CheckBox ID="chkShowPopupText" runat="server" Text=" Show Amount Popup Text" ClientIDMode="Static" />     </div></div>

Thank you for any assistance.

Scott 

Posted by Community Admin on 27-Apr-2016 00:00

Hello Scott,

For the _addButtonClicked function you use a delegate:

this._addDesignationButtonDelegate = Function.createDelegate(this, this._addButtonClicked);

Passing the "this" object to the delegate. The "this" object in the current function will be the designer itself. This means when the _addButtonClicked function is executed, in it the "this" object will again the designer and you will have access to the functions and fields of it.

In the other case, I do not see using a delegate, which means, when the function is called, the "this" object in it will be the function or window.

Regards,
Nikola Zagorchev
Telerik
 
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
 

This thread is closed