EMail Widget not updating when Form is Selected
Ok...here is today's challenge. :-)
After going through a list of discussions about customizing the email forms and applying them to my own control (listed below)...
001.using System;002.using System.Collections.Generic;003.using System.ComponentModel;004.using System.Web.UI;005.using Telerik.Sitefinity.Modules.Forms;006.using Telerik.Sitefinity.Modules.Forms.Web.UI;007.using Telerik.Sitefinity.Modules.Forms.Web.UI.Fields;008.using Telerik.Sitefinity.Web.UI;009.using Telerik.Sitefinity.Web.UI.ControlDesign;010. 011.namespace BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget012.013. [ControlDesigner(typeof(ExactTargetWidgetDesigner))]014. public class ExactTargetWidget : FormsControl015. 016. public Guid ThankYouPageId get; set; 017. public Guid ErrorPageId get; set; 018. public Guid UnsubscribePageId get; set; 019. 020. public string FormHtml get; set; 021. 022. private Guid _formId;023. public Guid FormId024. 025. get return _formId; 026. set 027. _formId = value;028. var mgr = new FormsManager();029. var form = mgr.GetForm(_formId);030. if (form != null)031. 032. // What to add?033. 034. 035. 036. 037. #region Public Properties for the control.038. 039. /// <summary>040. /// Gets or sets the member id.041. /// </summary>042. /// <value>043. /// The member id.044. /// </value>045. public int MemberId046. 047. get048. 049. var propertyValue = 0;050. var obj = ViewState["MemberId"];051. if (obj != null)052. 053. Int32.TryParse(obj.ToString(), out propertyValue);054. 055. 056. return propertyValue;057. 058. set059. 060. ViewState["MemberId"] = value;061. 062. 063. 064. /// <summary>065. /// Gets or sets the list id.066. /// </summary>067. /// <value>068. /// The list id.069. /// </value>070. public int ListId071. 072. get073. 074. var propertyValue = 0;075. var obj = ViewState["ListId"];076. if (obj != null)077. 078. Int32.TryParse(obj.ToString(), out propertyValue);079. 080. 081. return propertyValue;082. 083. set084. 085. ViewState["ListId"] = value;086. 087. 088. 089. /// <summary>090. /// Gets or sets the postback URL.091. /// </summary>092. /// <value>093. /// The postback URL.094. /// </value>095. public string PostbackUrl096. 097. get098. 099. var propertyValue = String.Empty;100. var obj = ViewState["PostbackUrl"];101. if (obj != null)102. 103. propertyValue = obj.ToString();104. 105. 106. return propertyValue;107. 108. set109. 110. ViewState["PostbackUrl"] = value;111. 112. 113. 114. #endregion115. 116. /// <summary>117. /// Gets or Sets the layout template name for the control.118. /// </summary>119. private const string layoutTemplateName = "BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetTemplate.ascx";120. protected override string LayoutTemplateName121. 122. get return layoutTemplateName; 123. 124. 125. #region Widget Events126. 127. protected override void InitializeControls(GenericContainer container)128. 129. base.InitializeControls(container);130. 131. // BeforeFormAction += ExactTargetWidget_BeforeFormAction;132. 133. 134. private void ExactTargetWidget_BeforeFormAction(object sender, CancelEventArgs e)135. 136. 137. 138. 139. protected override void ConfigureSubmitButton(Control control, string validationGroup)140. 141. var submit = control as FormSubmitButton;142. submit.Click += new EventHandler(submit_Click);143. base.ConfigureSubmitButton(control, validationGroup);144. 145. 146. /// <summary>147. /// Handles the Click event of the submit control.148. /// </summary>149. /// <param name="sender">The source of the event.</param>150. /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>151. private void submit_Click(object sender, EventArgs e)152. 153. Guid formId = this.FormId;154. var formMgr = new FormsManager();155. var formDescr = formMgr.GetForm(formId);156. var msgBody = string.Empty;157. foreach (var fld in this.FieldControls)158. 159. //fld.GetType().160. if (fld is FormTextBox)161. 162. msgBody += String.Format("<p><strong>0:</strong> 1</p>", ((FormTextBox) fld).Title,163. ((FormTextBox) fld).Value);164. 165. else if (fld is FormParagraphTextBox)166. 167. msgBody += String.Format("<p><strong>0:</strong> 1</p>", ((FormParagraphTextBox) fld).Title,168. ((FormParagraphTextBox) fld).Value);169. 170. else if (fld is FormCheckboxes)171. 172. string choices = string.Empty;173. foreach (string item in ((List<String>) ((FormCheckboxes) fld).Value))174. 175. choices += String.Format("0,", item);176. 177. msgBody += String.Format("<p><strong>0:</strong> 1</p>", ((FormCheckboxes) fld).Title, choices);178. 179. 180. else if (fld is FormChoiceField)181. 182. msgBody += String.Format("<p><strong>0:</strong> 1</p>", ((FormChoiceField) fld).Title, ((FormChoiceField) fld).Value);183. 184. 185. 186. try187. 188. 189. string subject = String.Format("0 1 - Form Submission", formDescr.ApplicationName.TrimEnd('/'), formDescr.Title);190. // SendEmailMsg(this.FromAddress, this.ToAddresses, this.CCAddresses, subject, msgBody);191. 192. 193. catch (Exception)194. 195. throw;196. 197. 198. 199. #endregion200. 201.001.using System.Collections.Generic;002.using System.Linq;003.using System.Web.UI;004.using Telerik.Sitefinity.Web.UI;005.using Telerik.Sitefinity.Web.UI.ControlDesign;006.using Telerik.Sitefinity.Web.UI.Fields;007. 008.namespace BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget009.010. public class ExactTargetWidgetDesigner : ControlDesignerBase011. 012. /// <summary>013. /// Initializes the controls.014. /// </summary>015. /// <param name="container"></param>016. protected override void InitializeControls(GenericContainer container)017. 018. // load in advanced mode019. base.DesignerMode = ControlDesignerModes.Simple;020. 021. // set root node for page selector022. ThankYouPageSelector.RootNodeID = Telerik.Sitefinity.Abstractions.SiteInitializer.FrontendRootNodeId;023. ErrorPageSelector.RootNodeID = Telerik.Sitefinity.Abstractions.SiteInitializer.FrontendRootNodeId;024. UnsubscribePageSelector.RootNodeID = Telerik.Sitefinity.Abstractions.SiteInitializer.FrontendRootNodeId;025. 026. GridSelector.ItemType = "Telerik.Sitefinity.Forms.Model.FormDescription";027. GridSelector.BindOnLoad = true;028. 029. 030. /// <summary>031. /// Gets a reference to the form selector032. /// </summary>033. public FlatSelector GridSelector034. 035. // Quoted parameter is the name of the Server Control on the ascx page.036. get return this.Container.GetControl<FlatSelector>("itemSelector", true); 037. 038. 039. 040. 041. protected PageField ThankYouPageSelector042. 043. // The id of the control will be in the quotes.044. get return Container.GetControl<PageField>("ThanksPageSelector", true); 045. 046. 047. protected PageField ErrorPageSelector048. 049. // The id of the control will be in the quotes.050. get return Container.GetControl<PageField>("ErrPageSelector", true); 051. 052. 053. protected PageField UnsubscribePageSelector054. 055. // The id of the control will be in the quotes.056. get return Container.GetControl<PageField>("UnsubPageSelector", true); 057. 058. 059. protected override HtmlTextWriterTag TagKey get return HtmlTextWriterTag.Div; 060. 061. private string _layoutTemplatePath = "~/ButlerModules/ExactTarget/ExactTargetWidgetDesignerTemplate.ascx";062. public override string LayoutTemplatePath063. 064. get return _layoutTemplatePath; 065. set _layoutTemplatePath = value; 066. 067. 068. private string _scriptPath = "~/ButlerModules/ExactTarget/ExactTargetWidgetDesigner.js";069. public string DesignerScriptPath070. 071. get return _scriptPath; 072. set _scriptPath = value; 073. 074. 075. private string _layoutTemplateName =076. "BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesignerTemplate.ascx";077. protected override string LayoutTemplateName078. 079. get return null; 080. 081. 082. /// <summary>083. /// Gets a collection of <see cref="T:System.Web.UI.ScriptReference"/> objects that define script resources that the control requires.084. /// </summary>085. /// <returns>086. /// An <see cref="T:System.Collections.IEnumerable"/> collection of <see cref="T:System.Web.UI.ScriptReference"/> objects.087. /// </returns>088. public override IEnumerable<ScriptReference> GetScriptReferences()089. 090. var scripts = base.GetScriptReferences() as List<ScriptReference>;091. if (scripts == null) return base.GetScriptReferences();092. 093. scripts.Add(new ScriptReference(DesignerScriptPath));094. return scripts.ToArray();095. 096. 097. /// <summary>098. /// Gets a collection of script descriptors that represent ECMAScript (JavaScript) client components.099. /// </summary>100. /// <returns>101. /// An <see cref="T:System.Collections.IEnumerable"/> collection of <see cref="T:System.Web.UI.ScriptDescriptor"/> objects.102. /// </returns>103. public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()104. 105. var descriptors = new List<ScriptDescriptor>(base.GetScriptDescriptors());106. var descriptor = (ScriptControlDescriptor)descriptors.Last();107. 108. // Mapping occurs here between the designer controls (aspx) and the get_ and set_ in the JavaScript109. // For example, gridSelector should be in quotes, but in the Designer.js file there 110. // better be a set_gridSelector() and a get_gridSelector().111. descriptor.AddComponentProperty("gridSelector", this.GridSelector.ClientID);112. 113. descriptor.AddComponentProperty("ThankYouPageSelector", this.ThankYouPageSelector.ClientID);114. descriptor.AddComponentProperty("ErrorPageSelector", this.ErrorPageSelector.ClientID);115. descriptor.AddComponentProperty("UnsubscribePageSelector", this.UnsubscribePageSelector.ClientID);116. 117. return descriptors;118. 119. 120.001.Type.registerNamespace("BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidget");002. 003.BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner = function (element) 004. 005. BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.initializeBase(this, [element]);006. 007. // Element008. this._contentFormElement = null;009. 010. this._ThankYouPageSelector = null;011. this._ErrorPageSelector = null;012. this._UnsubscribePageSelector = null;013.014. 015.BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.prototype = 016. initialize: function () 017. BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.callBaseMethod(this, 'initialize');018. 019. var self = this;020. 021. self._toogleExactTargetSettingsDelegate = Function.createDelegate(self, function () 022. dialogBase.resizeToContent();023. );024. 025. // Have it already open.026. jQuery("#expanderSettings")027. .click(self._toogleDesignSettingsDelegate);028. 029. jQuery("#exactTargetSettingsExp a")030. // .click(self._toogleExactTargetSettingsDelegate)031. .click(function () 032. var parent = $(this).closest(".sfExpandableSection");033. if (parent != null) 034. $(parent).toggleClass("sfExpandedSection");035. 036. $(this)037. .closest(".sfExpandableSection:first")038. .toggleClass("sfExpandedSection");039. dialogBase.resizeToContent();040. );041. 042. ,043. dispose: function () 044. BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.callBaseMethod(this, 'dispose');045. ,046. reset: function () 047. this.set_value(null);048. BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.callBaseMethod(this, "reset");049. ,050. refreshUI: function () 051. this._refreshMode = true;052. var data = this.get_controlData();053. 054. // Hide the Advanced button on the modal.055. var p = this.get_propertyEditor();056. jQuery(p.get_advancedModeButton()).hide();057. 058. jQuery("#MemberIdField").val(data.MemberId);059. jQuery("#ListIdField").val(data.ListId);060. jQuery("#PostbackUrlField").val(data.PostbackUrl);061. 062. if (data && data.FormId) 063. var dataItemId = data.FormId;064. if (dataItemId) 065. this.get_gridSelector().set_selectedKeys([dataItemId]);066. 067. 068. 069. // load thank you page.070. var t = this.get_ThankYouPageSelector();071. var pageid = data.ThankYouPageId;072. if (pageid) t.set_value(pageid);073. 074. // load Error page.075. var e = this.get_ErrorPageSelector();076. pageid = data.ErrorPageId;077. if (pageid) e.set_value(pageid);078. 079. // load Unsubscribe page.080. var u = this.get_UnsubscribePageSelector();081. pageid = data.UnsubscribePageId;082. if (pageid) u.set_value(pageid);083. ,084. 085. applyChanges: function () 086. 087. var controlData = this.get_controlData();088. 089. controlData.MemberId = jQuery("#MemberIdField").val();090. controlData.ListId = jQuery("#ListIdField").val();091. controlData.PostbackUrl = jQuery("#PostbackUrlField").val();092. 093. var selectedItems = this.get_gridSelector().getSelectedItems();094. if (selectedItems.length > 0) 095. controlData.FormId = selectedItems[0].Id;096. // this.get_propertyEditor().097. 098. 099. // save selected Thank You page100. controlData.ThankYouPageId = this.get_ThankYouPageSelector().get_value();101. controlData.ErrorPageId = this.get_ErrorPageSelector().get_value();102. controlData.UnsubscribePageId = this.get_UnsubscribePageSelector().get_value();103. ,104. 105. /* Get/Sets */106. get_controlData: function () 107. return this.get_propertyEditor().get_control();108. ,109. 110. // ThankYou Page Selector111. get_ThankYouPageSelector: function () 112. return this._ThankYouPageSelector;113. ,114. set_ThankYouPageSelector: function (value) 115. this._ThankYouPageSelector = value;116. ,117. 118. // Error Page Selector119. get_ErrorPageSelector: function () 120. return this._ErrorPageSelector;121. ,122. set_ErrorPageSelector: function (value) 123. this._ErrorPageSelector = value;124. ,125. 126. // Unsubscribe Page Selector127. get_UnsubscribePageSelector: function () 128. return this._UnsubscribePageSelector;129. ,130. set_UnsubscribePageSelector: function (value) 131. this._UnsubscribePageSelector = value;132. ,133. 134. // Used to set the Form135. get_contentFormElement: function () 136. return this._contentFormElement;137. ,138. set_contentFormElement: function (value) 139. this._contentFormElement = value;140. ,141. 142. // gets the reference to the propertyEditor control143. get_propertyEditor: function () 144. return this._propertyEditor;145. ,146. // sets the reference fo the propertyEditor control147. set_propertyEditor: function (value) 148. this._propertyEditor = value;149. ,150. 151. get_gridSelector: function () 152. return this._gridSelector;153. ,154. set_gridSelector: function (value) 155. this._gridSelector = value;156. ,157. 158. // function to initialize resizer methods and handlers159. _resizeControlDesigner: function () 160. setTimeout("dialogBase.resizeToContent()", 100);161. 162.163. 164.BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner.registerClass('BSAH.eCommerce.SitefinityWebApp.ButlerModules.ExactTarget.ExactTargetWidgetDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);165.if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();01.<%@ Control Language="C#" %>02.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.Fields" Assembly="Telerik.Sitefinity, Version=5.1.3270.0, Culture=neutral, PublicKeyToken=b28c218413bdf563" %>03.<%@ Register TagPrefix="sitefinity" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity, Version=5.1.3270.0, Culture=neutral, PublicKeyToken=b28c218413bdf563" %>04.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ControlDesign" Assembly="Telerik.Sitefinity, Version=5.1.3270.0, Culture=neutral, PublicKeyToken=b28c218413bdf563" %>05.<sitefinity:ResourceLinks ID="resourcesLinks" runat="server">06. <sitefinity:ResourceFile JavaScriptLibrary="JQuery" />07. <sitefinity:ResourceFile Name="Styles/Grid.css" />08. <sitefinity:ResourceFile Name="Styles/ToolBar.css" />09. <sitefinity:ResourceFile Name="Styles/Ajax.css" />10.</sitefinity:ResourceLinks>11.<style>12. #selectorTag .sfSelectorGridWrapper13. 14. height: 150px;15. 16. /*17. .exactTargetFormSelector h1, .exactTargetFormSelector .sfButtonArea, .exactTargetFormSelector .sfSelectorBtns18. 19. display: none;20. 21. */22.</style>23.<sitefinity:FormManager ID="formManager" runat="server" />24.<sitefinity:SitefinityLabel runat="server" ID="lblTitle" WrapperTagName="h1" HideIfNoText="false" />25.<div class="sfContentViews">26. <div id="selectorTag" class="sfFlatDialogSelector">27. <sitefinity:FlatSelector ID="itemSelector" runat="server" DataKeyNames="Id" AllowSearching="false"28. ItemsFilter = "Visible == true AND Status == Live" ShowProvidersList="false" InclueAllProvidersOption="true"29. ServiceUrl="~/Sitefinity/Services/Forms/FormsService.svc">30. <DataMembers>31. <sitefinity:DataMemberInfo ID="DataMemberInfo1" runat="server" Name="Title" IsSearchField="false"32. HeaderText="Title">33. <span>Title</span>34. </sitefinity:DataMemberInfo>35. </DataMembers>36. </sitefinity:FlatSelector>37. <div id="exactTargetPageSelect">38. <div id="exactTargetSettingsExp" class="sfExpandableSection">39. <h3>40. <a id="expanderSettings" href="javascript:void(0);" class="sfMoreDetails">Exact Target41. Options</a></h3>42. <ul class="sfTargetList">43. <li class="sfFormCtrl">44. <label class="sfTxtLbl">45. Member Id:</label>46. <input id="MemberIdField" type="text" />47. </li>48. <li class="sfFormCtrl">49. <label class="sfTxtLbl">50. List Id:</label>51. <input id="ListIdField" type="text" />52. </li>53. <li class="sfFormCtrl">54. <asp:Label ID="Label1" runat="server" AssociatedControlID="ThanksPageSelector" CssClass="sfTxtLbl">Thank You Page:</asp:Label>55. <sf:PageField ID="ThanksPageSelector" runat="server" WebServiceUrl="~/Sitefinity/Services/Pages/PagesService.svc/"56. DisplayMode="Write" />57. </li>58. <li class="sfFormCtrl">59. <asp:Label ID="Label2" runat="server" AssociatedControlID="ErrPageSelector" CssClass="sfTxtLbl">Error Page:</asp:Label>60. <sf:PageField ID="ErrPageSelector" runat="server" WebServiceUrl="~/Sitefinity/Services/Pages/PagesService.svc/"61. DisplayMode="Write" />62. </li>63. <li class="sfFormCtrl">64. <asp:Label ID="Label3" runat="server" AssociatedControlID="UnsubPageSelector" CssClass="sfTxtLbl">UnSubscribe Page:</asp:Label>65. <sf:PageField ID="UnsubPageSelector" runat="server" WebServiceUrl="~/Sitefinity/Services/Pages/PagesService.svc/"66. DisplayMode="Write" />67. </li>68. <li>69. <label class="sfTxtLbl">70. Postback Url:</label>71. <input type="text" id="PostbackUrlField" />72. </li>73. </ul>74. </div>75. </div>76. </div>77.</div>01.<%@ Control Language="C#" %>02.<%@ Register TagPrefix="sfFields" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" %>03.<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>04. 05.<sfFields:FormManager id="formManager" runat="server" />06. 07. 08.<asp:Panel ID="errorsPanel" runat="server" CssClass="sfErrorSummary" />09.<sf:SitefinityLabel id="successMessage" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfSuccess" />10.<asp:Panel ID="formControls" runat="server">11. 12.</asp:Panel>Just wondering...was this the right place to post this?
Hello JD,
Can you please let us know if you intend on introducing another specific functionality for this use case scenario, apart form the custom Form notifications?
First, I'd like to point out that the blog post you're referring to has been released prior to including this functionality out of the box in Sitefinity 5.1, so you should be able to use it if you have a Sitefinity version equal to, or higher.
If you prefer following the blog post, please ntoe that the desired functionality already comes out of the box, as you're inheriting from the default FormsControl, which does this task for you - in other words there's no need to create a new designer and implement this functionality, as just by inheriting from FormsControl you're going to have it.
Greetings,
Boyan Barnev
the Telerik team
Boyan,
Thanks for the reply, but I think I figured out my issue...and it was four issues on my side. Consider these notes and a coding example for someone looking for a way to further extend the FormsControl.
Hello Jonathan,
Thnak you for sharing your approach with the community, we really appreciate it.
Regarding the FormControl class members, you can get more information about these by installing our API Reference in VS 2010. For more information on how to achieve this, I believe you might find this blog post useful
Greetings,
Boyan Barnev
the Telerik team