Jul 22, 2008, 11:17 AM
Advice / best practice request for custom component development
Hi guys,
Loving Coolite controls... I am busy trying to develop/playing around with some custom controls (some of which are composite controls) and interested in what the best approach for this would be. What I mean by this is at what stage in the Page Lifecycle is it best to do things such as:
- Add Component Controls to the ItemsCollection; OR should we add to the ContentControls (if supported)
- Adding permanent events to a custom control (is it best to add this in the code, or add a javascript resource file to the output)
Below is some sample code to show what I am meaning above (some code has been commented out to show areas where I have tried to add listeners to the custom control in the code - which didnt work by the way....).
using CoolExt = Coolite.Ext.Web;
namespace Coolite.Ext.ux.Samples
{
public class CustomPanel : CoolExt.Panel
{
//some custom div we want to manipulate
private CustomDiv div = new CustomDiv();
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.ConfigCustomPanel();
}
//settings for panel
private void ConfigCustomPanel()
{
//panel settings
this.Width = Unit.Pixel(250);
this.Height = Unit.Pixel(250);
//add custom component to control
div.Html = "testing custom div";
this.ContentControls.Add(this.div);
}
//protected override void OnPreRender(EventArgs e)
//{
// //test function
// string fn = "Ext.Msg.alert('Confirm', String.format('You Clicked {0}', el.id));";
// //add function to custom div
// this.div.AddListener("click", "function(el){" + fn + "}");
// base.OnPreRender(e);
//}
}
public class CustomDiv : CoolExt.Component
{
public string Html
{
get
{
return (string)this.ViewState["Html"] ?? "";
}
set
{
this.ViewState["Html"] = value;
}
}
protected override void RenderContents(HtmlTextWriter writer)
{
if (!string.IsNullOrEmpty(this.Html))
{
writer.Write(this.Html);
}
base.RenderContents(writer);
}
//protected override void OnPreRender(EventArgs e)
//{
// //test function
// string fn = "Ext.Msg.alert('Confirm', String.format('You Clicked {0}', el.id));";
// //add function to div
// this.AddListener("click", "function(el){" + fn + "}");
// base.OnPreRender(e);
//}
}
}
When one of the PreRender code is uncommented, I always get a javascript error after the page has been rendered saying that ctrl_blah (or a specific ID if I specify the ID) has no properties.When reviewing the markup and javascript output by the ScriptManager, I noticed that "_Content", "_Container" is added to the ID for the markup and is dependant on the type of base object of the custom control. However, in the javascript there is no reference to the rendered ID before trying to reference it. This is not the case when adding coolite controls, but not for the custom ones, especially ones which have Component as the base type. (i.e. no "contentEl" property has been added to the javascript output to create the association)
Some sample javascript / html snippets
this.ctl05.on("click",function(el){Ext.Msg.alert('Confirm', String.format('You Clicked {0}', el.id));});
<div id="ctl03_Content"><div id="ctl05_Container">
hello there
Obviously I am missing the point here somewhere.. If I try add the Listener to the ScriptManager after PreRender it doesnt render since I believe the scripts have already been rendered. If I add it when the component is Initialized (i.e. OnInit), then it says that the ScriptManager needs to be added before adding scripts to it....To give you an idea why I am looking at doing everything programmatically, is the creation of a composite control with a "pluggable" interface model for custom modules. This would then be implemented via markup similar to the following:
<ext:InterfaceType ID="InterfaceTypeContainer" runat="server" >
<Content>
<ext:Core id="coreCustomisation" runat="server">
<ext:Informer id="informer" runat="server"
Display="true" AllActions="true">
</ext:Informer>
<ext:CoreModules id="modules" runat="server">
<ext:Module id="core1" runat="server"></ext:Module>
<ext:Module id="core2" runat="server"></ext:Module>
</ext:CoreModules>
</ext:Core>
<ext:Plugins id="pluginComponent" runat="server">
<ext:Plugin id="plugin1" runat="server"></ext:Plugin>
<ext:Plugin id="plugin2" runat="server"></ext:Plugin>
<ext:Plugin id="plugin3" runat="server"></ext:Plugin>
<ext:Plugin id="pluginEtc" runat="server"></ext:Plugin>
</ext:Plugins>
</Content>
</ext:InterfaceType>
i.e. remove the Layout/Structure from the developer and creating a model for developers to add your their own "plugin" type components, which can then interact with each other with a common data layer model... The backend models and how they communicate with each other is not my issue here.. I can see Coolite control UI capabilities as the perfect marriage for such a system. What I am struggling with (probably since I am not a UI developer) at the moment is determining the rendering model for custom controls.Any advice how best to approach the development of custom objects that have custom javascript, CSS and/or markup would help immensely.
thanks,
Conor