Dynamic ADC controls, master-child nested ADC controls
The AJAX Data Controls (ADC) created by www.dotnetslackers.com are a set of server controls using ASP .net AJAX and JavaScript library, it closely mirrors the functionalities of the pure server side ASP .net data controls such as gridview, datalist and repeater.
To create a ASP .net server control dynamically, we need to do so on the server side, in the code behind of page_init method. For example, to create a dynamic textbox control:
override protected void OnInit(EventArgs e)
{
// Create dynamic controls here.
// Use "using System.Web.UI.WebControls;"
TextBox1 = new TextBox();
TextBox1.ID = "TextBox1";
TextBox1.Style["Position"] = "Absolute";
TextBox1.Style["Top"] = "25px";
TextBox1.Style["Left"] = "100px";
Form1.Controls.Add(TextBox1);
TextBox2 = new TextBox();
TextBox2.ID = "TextBox2";
TextBox2.Style["Position"] = "Absolute";
TextBox2.Style["Top"] = "60px";
TextBox2.Style["Left"] = "100px";
Form1.Controls.Add(TextBox2);
this.TextBox1.TextChanged += new System.EventHandler(this.TextBox_TextChanged);
this.TextBox2.TextChanged += new System.EventHandler(this.TextBox_TextChanged);
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
Recently I discovered that It is possible to create dynamic ADC controls too, however on the client side, using the following syntax:
- $create(controlName,
- {},
- {},
- {},
- null);
For example, to create a repeater dynamically,
$create(AjaxDataControls.Repeater, {'itemTemplate': '<li><span id=\"spnProductName\"></span></li>'}, {'itemDataBound': onChildItemDataBound}, null, ulProducts);
In life, relationship is everything, parallel, hierarchical. Sometimes in data representation, we need to dynamically reflect data hierarchy too.
With asp .net, we can define the nested relationship among datatables in a dataset, then in a web form, we can set the relationship between a gridview and datalist as parent-child.
With ADC controls, is it possible to implement nested structures between two controls?
It turns out, Yes (this is my one of my recent discoveries). It turns out, it is pretty easy too.
The secret lies in the capacity of creating dynamic controls in the RowDataBoundEvent event of each parent row/item. The following is a dummy sample of nested gridview.
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="GridView Basic" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="Server">
<h3>
Supplier Information</h3>
<AjaxData:GridView ID="GridView1" runat="server" CssClass="DataWebControlStyle" CellSpacing="0"
CellPadding="3" RowDataBoundEvent="RowDataBound" DataKeyName="ID">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<Columns>
<AjaxData:GridViewBoundColumn DataField="Company" HeaderText="Company">
</AjaxData:GridViewBoundColumn>
<AjaxData:GridViewTemplateColumn>
<ItemTemplate>
<a id="lnk" >show this</a><br />
<table id="ulProducts" style="display:none"></table>
</ItemTemplate>
</AjaxData:GridViewTemplateColumn>
</Columns>
<EmptyDataTemplate>
There is no records available.
</EmptyDataTemplate>
<EmptyDataRowStyle HorizontalAlign="Center" />
</AjaxData:GridView>
<script type="text/javascript">
var rIndex;
function RowDataBound(sender, e) {
var row = e.get_row(); //.get_rowIndex()
if (row.get_isDataRowType()) {
rIndex = row.get_rowIndex();
var ulProducts = row.findControl('ulProducts');
if (ulProducts) {
var childRepeaterID = ulProducts.id;
// alert(childRepeaterID);
var childRepeater = $find(childRepeaterID);
if (childRepeater) {
//There is a previous instance so we need to remove it.
Sys.Application.removeComponent(childRepeater);
}
childRepeater = $create(AjaxDataControls.GridView,
{ }, { },
null, ulProducts);
var data = new Array();
data[0] = { Id: 1, Name: "Sonu Kapoor" };
data[1] = { Id: 2, Name: "Xun Ding" };
data[2] = { Id: 3, Name: "Gabriel" };
data[3] = { Id: 3, Name: "Onur" };
childRepeater.set_dataSource(data);
childRepeater.dataBind();
}
var id = GridView1.get_dataKeys()[rIndex];
var context = { tablename: ulProducts };
var callback = Function.createCallback(showNested, context);
// alert(rIndex);
var lnk = row.findControl('lnk');
if (lnk) {
// alert("agag");
$addHandler(lnk, "click", callback);
}
}
}
function onChildItemDataBound(sender, e) {
}
function showNested(evt, context) {
var table = context.tablename;
if (table.style.display == "none")
table.style.display = "block";
else
table.style.display = "none";
}
function pageLoad(sender, e) {
Pager1.set_recordCount(100);
DataService.GetAllSupplier(onLoadSuccess);
}
function onLoadSuccess(result) {
GridView1.set_dataSource(result);
GridView1.dataBind();
}
</script>
</asp:Content>