Custom Widget designer error
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
Hello
For the _addButtonClicked function you use a delegate:
this
._addDesignationButtonDelegate = Function.createDelegate(
this
,
this
._addButtonClicked);