using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.UI; using System.ComponentModel; using System.Drawing.Design; using System.Web.UI.WebControls; using System.Web; using System.Security.Permissions; using System.Reflection; using System.Globalization; using Mullivan.Web.UI.Design.WebControls; namespace Mullivan.Web.UI.WebControls { [ToolboxData("<{0}:JQueryAccordion Width=\"200\" Height=\"150\" runat=\"server\"></{0}:JQueryAccordion>"), Designer(typeof(JQueryAccordionDesigner)), PersistChildren(false), ParseChildren(true), Bindable(false), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class JQueryAccordion : WebControl { // Fields private int _cacheSectionIndex = -1; private bool _initialized; private JQueryAccordionSectionCollection _sectionCollection = null; private static readonly object EventActiveSectionChanged = new object(); private Type _tControl = null; private Type _tOccasionalFields = null; private MethodInfo _miRenderChildrenInternal; private MethodInfo _miEnsureOccasionalFields; private FieldInfo _fiOccasionalFields; private object _objOccasionalFields; private FieldInfo _fiOccasionalFieldsControls; // Event [Category("Behavior")] public event EventHandler ActiveSectionChanged { add { base.Events.AddHandler(EventActiveSectionChanged, value); } remove { base.Events.RemoveHandler(EventActiveSectionChanged, value); } } // Methods public JQueryAccordion() : base(HtmlTextWriterTag.Div) { _tControl = typeof(Control); _miEnsureOccasionalFields = _tControl.GetMethod("EnsureOccasionalFields", BindingFlags.Instance | BindingFlags.NonPublic); _miRenderChildrenInternal = _tControl.GetMethod("RenderChildrenInternal", BindingFlags.NonPublic | BindingFlags.Instance); _miEnsureOccasionalFields.Invoke(this, null); _fiOccasionalFields = _tControl.GetField("_occasionalFields", BindingFlags.NonPublic | BindingFlags.Instance); _objOccasionalFields = _fiOccasionalFields.GetValue(this); _tOccasionalFields = _objOccasionalFields.GetType(); _fiOccasionalFieldsControls = _tOccasionalFields.GetField("Controls", BindingFlags.Instance | BindingFlags.Public); this._cacheSectionIndex = -1; } [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public JQueryAccordionSection ActiveSection { get { int activeTabIndex = this.ActiveSectionIndex; if ((activeTabIndex < 0) || (activeTabIndex >= this.Sections.Count)) { return null; } return this.Sections[activeTabIndex]; } set { int index = this.Sections.IndexOf(value); if (index < 0) { throw new ArgumentOutOfRangeException("value"); } this.ActiveSectionIndex = index; } } [DefaultValue(-1), Category("Behavior"), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public int ActiveSectionIndex { get { if (this._initialized) { if (this.Sections.Count == 0) { this._cacheSectionIndex = -1; } else if (_cacheSectionIndex >= this.Sections.Count) { this._cacheSectionIndex = this.Sections.Count - 1; } return this._cacheSectionIndex; } return _cacheSectionIndex; } set { if (!_initialized) { this._cacheSectionIndex = value; } else { if (value < -1) { throw new ArgumentOutOfRangeException("value"); } if (value >= this.Sections.Count) { throw new ArgumentOutOfRangeException("value"); } if (this._cacheSectionIndex != value) { this._cacheSectionIndex = value; OnActiveTabChanged(new EventArgs()); } } } } [Category("Behavior"), Browsable(true)] public bool Collapsible { get { return (this.ViewState["Collapsible"] != null ? (bool)this.ViewState["Collapsible"] : false); } set { this.ViewState["Collapsible"] = value; } } [Category("Behavior"), DisplayName("Selection Mode"), Browsable(true)] public JQueryAccordionSelectionMode SelectionMode { get { return (this.ViewState["SelectionMode"] != null ? (JQueryAccordionSelectionMode)this.ViewState["SelectionMode"] : JQueryAccordionSelectionMode.Click); } set { this.ViewState["SelectionMode"] = value; } } [DefaultValue(typeof(Unit), ""), Category("Appearance")] public override Unit Height { get { return base.Height; } set { if (!value.IsEmpty && (value.Type != UnitType.Pixel)) { throw new ArgumentOutOfRangeException("value", "Height must be set in pixels only, or Empty."); } base.Height = value; } } [DefaultValue(typeof(Unit), ""), Category("Appearance")] public override Unit Width { get { return base.Width; } set { base.Width = value; } } [Category("Behavior"), DefaultValue("")] public string OnClientActiveSectionChanged { get { return (this.ViewState["OnClientActiveSectionChanged"] != null ? this.ViewState["OnClientActiveSectionChanged"].ToString() : string.Empty); } set { this.ViewState["OnClientActiveSectionChanged"] = value; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(true), Themeable(false), Editor(typeof(JQueryAccordionSectionCollectionEditor), typeof(UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty)] public JQueryAccordionSectionCollection Sections { get { if (this._sectionCollection == null) { this._sectionCollection = new JQueryAccordionSectionCollection(this); } return this._sectionCollection; } } internal JQueryAccordionSectionControlCollection SectionControls { get { JQueryAccordionSectionControlCollection collection = (JQueryAccordionSectionControlCollection) _fiOccasionalFieldsControls.GetValue(_objOccasionalFields); if (collection == null) { collection = (JQueryAccordionSectionControlCollection)this.CreateControlCollection(); _fiOccasionalFieldsControls.SetValue(_objOccasionalFields, collection); } return collection; } } public string UniqueID { get { return base.UniqueID; } set { } } [Browsable(false)] public string ClientJQueryControlId { get { this.EnsureID(); return "jq" + this.ClientID; } } [Browsable(false)] public string ClientActiveSectionControlId { get { this.EnsureID(); return "jq" + this.ClientID + "_ActiveSection"; } } protected override void AddedControl(Control control, int index) { ((JQueryAccordionSection)control).SetOwner(this); base.AddedControl(control, index); } protected override void AddParsedSubObject(object obj) { JQueryTab child = obj as JQueryTab; if (child != null) { this.Controls.Add(child); } else if (!(obj is LiteralControl)) { throw new HttpException(string.Format(CultureInfo.CurrentCulture, "TabContainer cannot have children of type '{0}'.", new object[] { obj.GetType() })); } } protected virtual void OnActiveTabChanged(EventArgs e) { EventHandler handler = base.Events[EventActiveSectionChanged] as EventHandler; if (handler != null) { handler(this, e); } } protected override void OnInit(EventArgs e) { base.OnInit(e); ClientScriptProxy p = ClientScriptProxy.Current; this.Page.RegisterRequiresControlState(this); JQueryUtil.RegisterRequiredResources(p, this); #if DEBUG p.RegisterClientScriptInclude(this, WebResources.JQUERY_JAVASCRIPT_UI_ACCORDION, false); #endif p.RegisterClientScriptInclude(this, WebResources.JQUERY_JAVASCRIPT_UI_EXT_ACCORDION, false); if (!this.Page.IsPostBack) { if (this.Sections.Count > 0) { if (_cacheSectionIndex > -1 && _cacheSectionIndex < this.Sections.Count) { this.ActiveSectionIndex = _cacheSectionIndex; } else this.ActiveSectionIndex = 0; } } else { this.ActiveSectionIndex = int.Parse(this.Page.Request.Form[ClientActiveSectionControlId]); } this._initialized = true; } protected override void RemovedControl(Control control) { JQueryAccordionSection panel = control as JQueryAccordionSection; this.Sections.Remove(panel); } protected override void OnPreRender(EventArgs e) { ClientScriptProxy p = ClientScriptProxy.Current; string strSelectedSectionChanged = ClientJQueryControlId + "_SelectedSectionChanged"; p.RegisterHiddenField(this, ClientActiveSectionControlId, this.ActiveSectionIndex.ToString()); StringBuilder sbStartup = new StringBuilder(); sbStartup.Append("var "); sbStartup.Append(ClientJQueryControlId); sbStartup.Append(" = jQuery('#"); sbStartup.Append(this.ClientID); sbStartup.AppendLine("');"); //Invoke client side rendering sbStartup.Append("var "); sbStartup.Append(ClientActiveSectionControlId); sbStartup.Append(" = document.getElementById('"); sbStartup.Append(ClientActiveSectionControlId); sbStartup.AppendLine("');"); sbStartup.Append("$(window).bind('load', "); sbStartup.Append("Init_"); sbStartup.Append(ClientJQueryControlId); sbStartup.AppendLine(");"); sbStartup.Append("function Init_"); sbStartup.Append(ClientJQueryControlId); sbStartup.AppendLine("(){"); sbStartup.Append(ClientJQueryControlId); sbStartup.AppendLine(".accordion();"); //Set Selection Mode sbStartup.Append(ClientJQueryControlId); sbStartup.Append(".accordion('option', 'event', '"); sbStartup.Append(this.SelectionMode.ToString().ToLower()); sbStartup.AppendLine("');"); //Set collapsible sbStartup.Append(ClientJQueryControlId); sbStartup.Append(".accordion('option', 'collapsible', "); sbStartup.Append(this.Collapsible.ToString().ToLower()); sbStartup.AppendLine(");"); //Set selected tab sbStartup.Append("if(parseInt("); sbStartup.Append(ClientActiveSectionControlId); sbStartup.Append(".value) > 0)"); sbStartup.AppendLine("{"); sbStartup.Append(ClientJQueryControlId); sbStartup.Append(".accordion('activate', parseInt("); sbStartup.Append(ClientActiveSectionControlId); sbStartup.AppendLine(".value));"); sbStartup.AppendLine("}"); //set handler for SelectedTabChanged sbStartup.Append(ClientJQueryControlId); sbStartup.Append(".bind('accordionchange', function (event, ui){"); sbStartup.Append(strSelectedSectionChanged); sbStartup.AppendLine("(event, ui);});"); sbStartup.AppendLine("}"); #region "Tab Selection" sbStartup.Append("function "); sbStartup.Append(strSelectedSectionChanged); sbStartup.AppendLine("(event, ui){"); sbStartup.Append(ClientJQueryControlId); sbStartup.AppendLine(".accordion('getIndexOfHeader', ui.newHeader, function(result){ "); sbStartup.Append(ClientActiveSectionControlId); sbStartup.AppendLine(".value = result;"); if (!string.IsNullOrEmpty(this.OnClientActiveSectionChanged)) { sbStartup.Append("try{"); sbStartup.Append(this.OnClientActiveSectionChanged); sbStartup.AppendLine("(event,ui);}catch(e){alert(e.message);}"); } Dictionary<string, string> sectionEvents = new Dictionary<string, string>(); foreach (JQueryAccordionSection sec in this.Sections) { if (!string.IsNullOrEmpty(sec.OnClientSectionSelected)) sectionEvents.Add(sec.Position.ToString(), sec.OnClientSectionSelected); } if (sectionEvents.Count > 0) { sbStartup.AppendLine("switch(result){"); foreach (string key in sectionEvents.Keys) { sbStartup.Append("case "); sbStartup.Append(key); sbStartup.AppendLine(":"); sbStartup.Append("try{"); sbStartup.Append(sectionEvents[key]); sbStartup.Append("(event,ui);"); sbStartup.AppendLine("}catch(e){alert(e.message);}"); sbStartup.AppendLine("break;"); } sbStartup.AppendLine("default:"); sbStartup.AppendLine("break;"); sbStartup.AppendLine("}"); } sbStartup.AppendLine("});"); sbStartup.AppendLine("}"); #endregion "Tab Selection" p.RegisterStartupScript(this.Page, typeof(WebResources), "_jsStartup__" + this.ClientID, sbStartup.ToString(), true); base.OnPreRender(e); } public override ControlCollection Controls { get { //Fakes out the Collection Editor for the Tabs return new ControlCollection(this); } } protected override ControlCollection CreateControlCollection() { return new JQueryAccordionSectionControlCollection(this); } protected override object SaveControlState() { Pair pair = new Pair(); pair.First = base.SaveControlState(); pair.Second = this.ActiveSectionIndex; if ((pair.First == null) && (pair.Second == null)) { return null; } return pair; } public enum JQueryAccordionSelectionMode { Click, DblClick, MouseOver, MouseDown, MouseUp } } }
By viewing downloads associated with this article you agree to the Terms of use and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
Skills that self-taught computer programmers lack