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

Forums / Developing with Sitefinity / Custom Widget designer error

Custom Widget designer error

2 posts, 0 answered
  1. Scott
    Scott avatar
    5 posts
    Registered:
    11 Aug 2014
    20 Apr
    Link to this post

    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 

  2. Nikola Zagorchev
    Nikola Zagorchev avatar
    424 posts
    Registered:
    27 Sep 2016
    27 Apr
    Link to this post
    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
     
2 posts, 0 answered