Yeah I realized that about 10 seconds after I posted that. Here you go.
Note that my real code is different only in the codebehind for database connections. But you'll see that the tooltip doesn't display when you click the save button on the example below. At least, it doesn't for me. I am running through Cassini btw, not sure if that makes a difference.
markup:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ExtSample1._Default" ValidateRequest="false" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<ext:ResourceManager runat="server" ID="ResourceManager1" />
<form id="form1" runat="server">
<ext:Viewport runat="server" ID="ViewportMain" StyleSpec="background-color: #DFE8F6;" Layout="Fit">
<Items>
<ext:Panel runat="server" ID="PanelFrame" Layout="Border" Title="Asset Library">
<Items>
<ext:Panel runat="server" ID="PanelNavigation" Title="Navigation" Region="West" Width="200px" Margins="4 0 4 4" Split="true" Collapsible="true">
<Items>
<ext:TreePanel runat="server" ID="TreeNavigation" Border="false" />
</Items>
</ext:Panel>
<ext:Panel runat="server" ID="PanelContent" Region="Center" Margins="4 4 4 0" Split="true" Layout="Border" Border="false">
<Items>
<ext:Panel runat="server" ID="PanelList" Title="Assets" Region="North" Split="true" Layout="Fit" Height="240">
<Items>
<ext:GridPanel runat="server" ID="GridAssets" StripeRows="true" TrackMouseOver="true" AutoExpandColumn="Description" Border="false">
<Store>
<ext:Store runat="server" ID="AssetStore">
<Reader>
<ext:JsonReader>
<Fields>
<ext:RecordField Name="AssetID" />
<ext:RecordField Name="Name" />
<ext:RecordField Name="Description" />
<ext:RecordField Name="ExpirationDate" Type="Date" DateFormat="c" />
</Fields>
</ext:JsonReader>
</Reader>
</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ColumnID="AssetID" Header="Asset ID" DataIndex="AssetID" Hidden="true" />
<ext:Column ColumnID="Name" Header="Name" DataIndex="Name" Width="500" />
<ext:Column ColumnID="Description" Header="Description" DataIndex="Description" />
<ext:Column ColumnID="Expiration" Header="Expiration" DataIndex="ExpirationDate">
<Renderer Fn="Ext.util.Format.dateRenderer('m/d/Y')" />
</ext:Column>
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel runat="server" SingleSelect="true" />
</SelectionModel>
<Listeners>
<RowClick Handler="Ext.net.DirectMethods.RowClick(item.getSelectionModel().getSelected().data.AssetID);" />
</Listeners>
</ext:GridPanel>
</Items>
</ext:Panel>
<ext:Panel runat="server" ID="PanelEditor" Region="Center" Split="true" Layout="Fit">
<Items>
<ext:FormPanel runat="server" ID="FormEditor" Padding="8" ButtonAlign="Right" Border="false" MonitorValid="true" Hidden="true">
<Items>
<ext:TextField runat="server" ID="txtName" FieldLabel="Name" Anchor="95%" MaxLength="100" />
<ext:TextField runat="server" ID="txtDesc" FieldLabel="Description" Anchor="95%" MaxLength="500" />
</Items>
<Buttons>
<ext:Button runat="server" ID="btnSave" Text="Save">
<Listeners>
<Click Handler="Ext.net.DirectMethods.SubmitForm();" />
</Listeners>
<ToolTips>
<ext:ToolTip
ID="ToolTip1"
runat="server"
Html="I should only display once after a click!"
HideDelay="2000"
Target="btnSave">
<Listeners>
<BeforeShow Handler="return !this.locked;" />
<Show Handler="if (typeof this.locked === 'undefined') { this.hide(); this.locked = true; }" Single="true" />
</Listeners>
</ext:ToolTip>
</ToolTips>
</ext:Button>
</Buttons>
</ext:FormPanel>
</Items>
</ext:Panel>
</Items>
</ext:Panel>
</Items>
</ext:Panel>
</Items>
</ext:Viewport>
</form>
</body>
</html>
code:
using System;
using System.Collections.Generic;
using Ext.Net;
namespace ExtSample1
{
[Serializable]
public class AssetCategory : ICloneable, IComparable<AssetCategory>
{
#region Properties
public int? AssetCategoryID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
#endregion
#region Constructor
public AssetCategory()
{
AssetCategoryID = null;
Name = "";
Description = "";
}
#endregion
#region ICloneable Members
public object Clone()
{
return this.MemberwiseClone();
}
#endregion
#region IComparable<AssetCategory> Members
public int CompareTo(AssetCategory other)
{
return SortByName.Compare(this, other);
}
#endregion
#region SortByName
public class Sorter_SortByName : IComparer<AssetCategory>
{
public int Compare(AssetCategory x, AssetCategory y)
{
return x.Name.CompareTo(y.Name);
}
}
public static Sorter_SortByName SortByName { get { return new Sorter_SortByName(); } }
#endregion
}
[Serializable]
public class Asset : ICloneable, IComparable<Asset>
{
#region Properties
public int? AssetID { get; set; }
public int? AssetCategoryID { get; set; }
public DateTime? ExpirationDate { get; set; }
public string Name { get; set; }
public string Description { get; set; }
#endregion
#region Constructor
public Asset()
{
AssetID = null;
AssetCategoryID = null;
ExpirationDate = null;
Name = "";
Description = "";
}
public Asset(int ID, int Category, string aName, string Desc, DateTime? Expiry)
{
AssetID = ID;
AssetCategoryID = Category;
Name = aName;
Description = Desc;
ExpirationDate = Expiry;
}
#endregion
#region ICloneable Members
public object Clone()
{
return this.MemberwiseClone();
}
#endregion
#region IComparable<Asset> Members
public int CompareTo(Asset other)
{
// Default Sort
return SortByName.Compare(this, other);
}
#endregion
#region SortByExpirationDate
private class Sorter_SortByExpirationDate : IComparer<Asset>
{
public int Compare(Asset x, Asset y)
{
if (x.ExpirationDate.HasValue)
{
if (y.ExpirationDate.HasValue)
{
if (x.ExpirationDate.Value == y.ExpirationDate.Value)
{
return x.Name.CompareTo(y.Name);
}
else
{
return x.ExpirationDate.Value.CompareTo(y.ExpirationDate.Value);
}
}
return 1;
}
else
{
if (y.ExpirationDate.HasValue)
{
return -1;
}
else
{
return x.Name.CompareTo(y.Name);
}
}
}
}
public static IComparer<Asset> SortByExpirationDate { get { return new Sorter_SortByExpirationDate(); } }
#endregion
#region SortByCategory
internal class Sorter_SortByCategory : IComparer<Asset>
{
public int Compare(Asset x, Asset y)
{
if (x.AssetCategoryID.HasValue)
{
if (y.AssetCategoryID.HasValue)
{
if (x.AssetCategoryID.Value == y.AssetCategoryID.Value)
{
return x.Name.CompareTo(y.Name);
}
else
{
return x.AssetCategoryID.Value.CompareTo(y.AssetCategoryID.Value);
}
}
return 1;
}
else
{
if (y.AssetCategoryID.HasValue)
{
return -1;
}
else
{
return x.Name.CompareTo(y.Name);
}
}
}
}
public static IComparer<Asset> SortByCategory { get { return new Sorter_SortByCategory(); } }
#endregion
#region SortByName
private class Sorter_SortByName : IComparer<Asset>
{
public int Compare(Asset x, Asset y)
{
return x.Name.CompareTo(y.Name);
}
}
public static IComparer<Asset> SortByName { get { return new Sorter_SortByName(); } }
#endregion
}
public partial class _Default : System.Web.UI.Page
{
#region Page_Load
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
LoadTree();
}
}
#endregion
#region LoadTree
private void LoadTree()
{
TreeNode root = new TreeNode("Categories");
root.Expanded = true;
TreeNavigation.Root.Add(root);
List<AssetCategory> allAssetCategories = new List<AssetCategory>();
AssetCategory cat = new AssetCategory();
cat.AssetCategoryID = 1;
cat.Name = "Events";
cat.Description = "Event Assets";
allAssetCategories.Add(cat);
cat = new AssetCategory();
cat.AssetCategoryID = 2;
cat.Name = "Offices";
cat.Description = "Office Assets";
allAssetCategories.Add(cat);
cat = new AssetCategory();
cat.AssetCategoryID = 3;
cat.Name = "Client Alerts";
cat.Description = "Client Alert Assets";
allAssetCategories.Add(cat);
foreach (AssetCategory category in allAssetCategories)
{
TreeNode categoryNode = new TreeNode(category.Name, Icon.Images);
categoryNode.NodeID = category.AssetCategoryID.Value.ToString();
categoryNode.Listeners.Click.Handler = "Ext.net.DirectMethods.NodeClick(node.id);";
root.Nodes.Add(categoryNode);
}
}
#endregion
#region NodeClick
[DirectMethod]
public void NodeClick(string id)
{
try
{
int categoryID = int.Parse(id);
List<Asset> assets = new List<Asset>();
Asset asset;
switch (categoryID)
{
case 1:
assets.Add(new Asset(2, 1, "Event Home Banner", "Event Home Banner", null));
assets.Add(new Asset(3, 1, "Event Register Button", "Event Register Button", null));
assets.Add(new Asset(4, 1, "2011FYA Splash", "2011FYA Splash", DateTime.Parse("2015-12-31 00:00:00.000")));
break;
case 2:
assets.Add(new Asset(85, 2, "Client Site Asset Main", "Client Site Asset Description", null));
assets.Add(new Asset(86, 2, "Los Angeles Asset Main", "Los Angeles Asset Description", DateTime.Parse("2011-08-02 10:43:01.760")));
assets.Add(new Asset(93, 2, "London Asset Main", "London Asset Description", DateTime.Parse("2011-06-18 10:43:01.873")));
break;
case 3:
assets.Add(new Asset(147, 3, "Expanded Stockholder Rights Regarding Inspection of Books and Records May Increa Asset Main", "Expanded Stockholder Rights Regarding Inspection of Books and Records May Increa Asset Description", DateTime.Parse("2011-07-25 10:46:36.780")));
assets.Add(new Asset(152, 3, "General Counsel Name Latham & Watkins a Top 5 Corporate Law Firm in Corporate Bo Asset Main", "General Counsel Name Latham & Watkins a Top 5 Corporate Law Firm in Corporate Bo Asset Description", DateTime.Parse("2011-06-19 10:46:36.877")));
assets.Add(new Asset(154, 3, "<i>Bollay v. California Office of Administrative Law</i>: State Agency Policies Asset Main", "<i>Bollay v. California Office of Administrative Law</i>: State Agency Policies Asset Description", DateTime.Parse("2011-07-02 10:46:36.910")));
break;
}
assets.Sort(Asset.SortByName);
AssetStore.DataSource = assets;
AssetStore.DataBind();
}
catch (Exception ex)
{
}
finally
{
PanelList.UpdateContent();
// Clear editor form
FormEditor.Hidden = true;
//PanelEditor.UpdateContent();
}
}
#endregion
#region RowClick
[DirectMethod]
public void RowClick(int AssetID)
{
Asset asset = null;
switch (AssetID)
{
case 2: asset = new Asset(2, 1, "Event Home Banner", "Event Home Banner", null);
break;
case 3: asset = new Asset(3, 1, "Event Register Button", "Event Register Button", null);
break;
case 4: asset = new Asset(4, 1, "2011FYA Splash", "2011FYA Splash", DateTime.Parse("2015-12-31 00:00:00.000"));
break;
case 85: asset = new Asset(85, 2, "Client Site Asset Main", "Client Site Asset Description", null);
break;
case 86: asset = new Asset(86, 2, "Los Angeles Asset Main", "Los Angeles Asset Description", DateTime.Parse("2011-08-02 10:43:01.760"));
break;
case 93: asset = new Asset(93, 2, "London Asset Main", "London Asset Description", DateTime.Parse("2011-06-18 10:43:01.873"));
break;
case 147: asset = new Asset(147, 3, "Expanded Stockholder Rights Regarding Inspection of Books and Records May Increa Asset Main", "Expanded Stockholder Rights Regarding Inspection of Books and Records May Increa Asset Description", DateTime.Parse("2011-07-25 10:46:36.780"));
break;
case 152: asset = new Asset(152, 3, "General Counsel Name Latham & Watkins a Top 5 Corporate Law Firm in Corporate Bo Asset Main", "General Counsel Name Latham & Watkins a Top 5 Corporate Law Firm in Corporate Bo Asset Description", DateTime.Parse("2011-06-19 10:46:36.877"));
break;
case 154: asset = new Asset(154, 3, "Bollay v. California Office of Administrative Law: State Agency Policies Asset Main", "Bollay v. California Office of Administrative Law: State Agency Policies Asset Description", DateTime.Parse("2011-07-02 10:46:36.910"));
break;
}
// TODO: Hydrate Form
txtName.Text = asset.Name;
txtDesc.Text = asset.Description;
FormEditor.Hidden = false;
//PanelEditor.UpdateContent();
}
#endregion
#region SubmitForm
[DirectMethod]
public void SubmitForm()
{
ToolTip1.AddScript("this.locked = false;");
ToolTip1.Show();
ToolTip1.AddScript("this.locked = true;");
}
#endregion
}
}