using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;
using System.Web;
using System.Security.Permissions;
using System.Globalization;
using System.Web.Script.Serialization;
using System.Collections.Specialized;
using Mullivan.Web.UI.Design.WebControls;
using System.Diagnostics;
using System.Drawing.Design;
using System.Reflection;
namespace Mullivan.Web.UI.WebControls
{
[ToolboxData("<{0}:JQueryTabView Width=\"200\" Height=\"150\" runat=\"server\"></{0}:JQueryTabView>"),
Designer(typeof(JQueryTabViewDesigner)),
PersistChildren(false),
ParseChildren(true),
Bindable(false),
AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public class JQueryTabView : WebControl
{
// Fields
private int _cacheTabIndex = -1;
private bool _initialized;
private JQueryTabCollection _tabCollection = null;
private static readonly object EventActiveTabChanged = 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;
[Browsable(false)]
public string ClientJQueryControlId
{
get
{
this.EnsureID();
return "jq" + this.ClientID;
}
}
[Browsable(false)]
public string ClientActiveTabControlId
{
get
{
this.EnsureID();
return "jq" + this.ClientID + "_ActiveTab";
}
}
// Event
[Category("Behavior")]
public event EventHandler ActiveTabChanged
{
add
{
base.Events.AddHandler(EventActiveTabChanged, value);
}
remove
{
base.Events.RemoveHandler(EventActiveTabChanged, value);
}
}
// Methods
public JQueryTabView()
: 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._cacheTabIndex = -1;
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public JQueryTab ActiveTab
{
get
{
int activeTabIndex = this.ActiveTabIndex;
if ((activeTabIndex < 0) || (activeTabIndex >= this.Tabs.Count))
{
return null;
}
return this.Tabs[activeTabIndex];
}
set
{
int index = this.Tabs.IndexOf(value);
if (index < 0)
{
throw new ArgumentOutOfRangeException("value");
}
this.ActiveTabIndex = index;
}
}
[DefaultValue(-1),
Category("Behavior"),
Browsable(true),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int ActiveTabIndex
{
get
{
if (this._initialized)
{
if (this.Tabs.Count == 0)
{
this._cacheTabIndex = -1;
}
else if (_cacheTabIndex >= this.Tabs.Count)
{
this._cacheTabIndex = this.Tabs.Count - 1;
}
return this._cacheTabIndex;
}
return _cacheTabIndex;
}
set
{
if (!_initialized)
{
this._cacheTabIndex = value;
}
else
{
if (value < -1)
{
throw new ArgumentOutOfRangeException("value");
}
if (value >= this.Tabs.Count)
{
throw new ArgumentOutOfRangeException("value");
}
if (this._cacheTabIndex != value)
{
this._cacheTabIndex = 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 JQueryTabSelectionMode SelectionMode
{
get
{
return (this.ViewState["SelectionMode"] != null ? (JQueryTabSelectionMode)this.ViewState["SelectionMode"] : JQueryTabSelectionMode.Click);
}
set
{
this.ViewState["SelectionMode"] = value;
}
}
[Category("Behavior"),
Browsable(true)]
public bool Sortable
{
get
{
return (this.ViewState["Sortable"] != null ? (bool)this.ViewState["Sortable"] : false);
}
set
{
this.ViewState["Sortable"] = 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 OnClientActiveTabChanged
{
get
{
return (this.ViewState["OnClientActiveTabChanged"] != null ? this.ViewState["OnClientActiveTabChanged"].ToString() : string.Empty);
}
set
{
this.ViewState["OnClientActiveTabChanged"] = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
Browsable(true),
Themeable(false),
Editor(typeof(JQueryTabCollectionEditor), typeof(UITypeEditor)),
PersistenceMode(PersistenceMode.InnerProperty)]
public JQueryTabCollection Tabs
{
get
{
if (this._tabCollection == null)
{
this._tabCollection = new JQueryTabCollection(this);
}
return this._tabCollection;
}
}
internal JQueryTabControlCollection TabControls
{
get
{
JQueryTabControlCollection collection = (JQueryTabControlCollection)
_fiOccasionalFieldsControls.GetValue(_objOccasionalFields);
if (collection == null)
{
collection = (JQueryTabControlCollection)this.CreateControlCollection();
_fiOccasionalFieldsControls.SetValue(_objOccasionalFields, collection);
}
return collection;
}
}
public string UniqueID
{
get
{
return base.UniqueID;
}
set
{
}
}
protected override void AddedControl(Control control, int index)
{
((JQueryTab)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[EventActiveTabChanged] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.EnsureID();
ClientScriptProxy p = ClientScriptProxy.Current;
this.Page.RegisterRequiresControlState(this);
JQueryUtil.RegisterRequiredResources(p, this);
#if DEBUG
p.RegisterClientScriptInclude(this, WebResources.JQUERY_JAVASCRIPT_UI_TABS, false);
#endif
if (!this.Page.IsPostBack)
{
if (this.Tabs.Count > 0)
{
if (_cacheTabIndex > -1 && _cacheTabIndex < this.Tabs.Count)
{
this.ActiveTabIndex = _cacheTabIndex;
}
else
this.ActiveTabIndex = 0;
}
}
else
{
this.ActiveTabIndex = int.Parse(this.Page.Request.Form[ClientActiveTabControlId]);
}
this._initialized = true;
}
protected override void RemovedControl(Control control)
{
JQueryTab panel = control as JQueryTab;
this.Tabs.Remove(panel);
}
protected override void RenderContents(HtmlTextWriter writer)
{
this.Page.VerifyRenderingInServerForm(this);
this.RenderHeader(writer);
this.RenderChildren(writer);
}
protected virtual void RenderHeader(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Height, "25px");
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
foreach (JQueryTab panel in this.Tabs)
{
if (panel.Visible)
{
panel.RenderHeader(writer);
}
}
writer.RenderEndTag();
}
protected override void OnPreRender(EventArgs e)
{
ClientScriptProxy p = ClientScriptProxy.Current;
string strSelectedTabChanged = ClientJQueryControlId + "_SelectedTabChanged";
p.RegisterHiddenField(this, ClientActiveTabControlId, this.ActiveTabIndex.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(ClientActiveTabControlId);
sbStartup.Append(" = document.getElementById('");
sbStartup.Append(ClientActiveTabControlId);
sbStartup.AppendLine("');");
sbStartup.Append(ClientJQueryControlId);
sbStartup.Append(".tabs()");
//Set sortable
if (this.Sortable)
sbStartup.AppendLine(".find('.ui-tabs-nav').sortable({axis:'x'});");
else
sbStartup.AppendLine(";");
//Set Selection Mode
sbStartup.Append(ClientJQueryControlId);
sbStartup.Append(".tabs('option', 'event', '");
sbStartup.Append(this.SelectionMode.ToString().ToLower());
sbStartup.AppendLine("');");
//Set collapsible
sbStartup.Append(ClientJQueryControlId);
sbStartup.Append(".tabs('option', 'collapsible', ");
sbStartup.Append(this.Collapsible.ToString().ToLower());
sbStartup.AppendLine(");");
//Set selected tab
sbStartup.Append("if(parseInt(");
sbStartup.Append(ClientActiveTabControlId);
sbStartup.Append(".value) > 0)");
sbStartup.AppendLine("{");
sbStartup.Append(ClientJQueryControlId);
sbStartup.Append(".accordion('activate', parseInt(");
sbStartup.Append(ClientActiveTabControlId);
sbStartup.AppendLine(".value));");
sbStartup.AppendLine("}");
//set handler for SelectedTabChanged
sbStartup.Append(ClientJQueryControlId);
sbStartup.Append(".bind('tabsselect', function (event, ui){");
sbStartup.Append(strSelectedTabChanged);
sbStartup.AppendLine("(event, ui);});");
#region "Tab Selection"
sbStartup.Append("function ");
sbStartup.Append(strSelectedTabChanged);
sbStartup.AppendLine("(event, ui){");
sbStartup.Append(ClientActiveTabControlId);
sbStartup.AppendLine(".value = ui.index;");
if (!string.IsNullOrEmpty(this.OnClientActiveTabChanged))
{
sbStartup.Append("try{");
sbStartup.Append(this.OnClientActiveTabChanged);
sbStartup.AppendLine("(event,ui);}catch(e){alert(e.message);}");
}
Dictionary<string, string> tabEvents = new Dictionary<string, string>();
foreach (JQueryTab tab in this.Tabs)
{
if (!string.IsNullOrEmpty(tab.OnClientTabSelected))
tabEvents.Add(tab.ClientID, tab.OnClientTabSelected);
}
if (tabEvents.Count > 0)
{
sbStartup.AppendLine("switch(ui.panel.id){");
foreach (string key in tabEvents.Keys)
{
sbStartup.Append("case '");
sbStartup.Append(key);
sbStartup.AppendLine("':");
sbStartup.Append("try{");
sbStartup.Append(tabEvents[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("}");
#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 JQueryTabControlCollection(this);
}
protected override object SaveControlState()
{
Pair pair = new Pair();
pair.First = base.SaveControlState();
pair.Second = this.ActiveTabIndex;
if ((pair.First == null) && (pair.Second == null))
{
return null;
}
return pair;
}
public enum JQueryTabSelectionMode
{
Click,
DblClick,
MouseOver,
MouseDown,
MouseUp
}
}
}