|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionIn most cases server controls are very useful in ASP.Net web application since they have some valuable events (for example: click event, data binding event, data bound event, etc) and many advance functionality like state management, input validation, etc. In general XSLT produce plain xml or html without any hassle but if we want to create our asp.net server control by using XML and XSLT then we should follow some procedure which will be described below XML has a vast use in web application and when we combine XML and XSLT, it shows its own strength and beauty which can speed up our application very much. One major benefit of using XML is column flexibility. Suppose, there are two types of addresses in our application 1. home address and 2. office address. It can be increase or decrease anytime without changing much code. And using XSLT we will create not only server controls but also define their events which will work like a magic. RequirementsI am assuming that the reader of this article have basic knowledge in XML, XSLT and ASP.Net. Using the codeWe will follow the following steps to get the things done:
Consider the following XML <root>
<Employee Id="1">
<Address Caption="Address">
<Home Caption="Home 1">
<Street Caption="Street 1" Type="Text">Road# 27, House# 13, Banani</Street>
<Street Caption="Street 2" Type="Text">
</Street>
<City Caption="City" Type="Text" Required="yes">Dhaka</City>
<Zip Caption="Zip" Type="Text">1213</Zip>
<Country Caption="Country" Type="CountryDDL">BD</Country>
</Home>
<Home Caption="Home 2">
<Street Caption="Street 1" Type="Text">Sector- 10</Street>
<Street Caption="Street 2" Type="Text">Uttara</Street>
<Street Caption="Street 3" Type="Text">
</Street>
<City Caption="City" Type="Text" Required="yes">Dhaka</City>
<Zip Caption="Zip" Type="Text">1230</Zip>
<Country Caption="Country" Type="CountryDDL">BD</Country>
</Home>
</Address>
</Employee>
<Employee Id="2">
<Address Caption="Address">
<Home Caption="Home 1">
<Street Caption="Street 1" Type="Text">J-13, Road 27</Street>
<Street Caption="Street 2" Type="Text">Banani</Street>
<City Caption="City" Type="Text">Dhaka</City>
<Zip Caption="Zip" Type="Text">1213</Zip>
<Country Caption="Country" Type="CountryDDL">BD</Country>
</Home>
<Home Caption="Home 2">
<Street Caption="Street 1" Type="Text">Michigan Avenue</Street>
<Street Caption="Street 2" Type="Text">Suite 2800</Street>
<Street Caption="Street 3" Type="Text">
</Street>
<City Caption="City" Type="Text">Chicago</City>
<Zip Caption="Zip" Type="Text">60601</Zip>
<Country Caption="Country" Type="CountryDDL">USA</Country>
</Home>
</Address>
</Employee>
</root>
We have to show the addresses like below:
Since there are multiple employee’s data in our XML document, we have to select the requested employee’s data among them. For this purpose, we have to create argument list and need to pass the employee id through xslt parameter.
//create argument list
XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("employeeId", "", ddlEmployee.SelectedValue);
//load the data
XPathDocument xdoc = new XPathDocument(Server.MapPath("Address.xml"));
//load Xslt
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(Server.MapPath("DynamicControls.xslt"));
StringWriter sw = new StringWriter();
//transform it
transform.Transform(xdoc, xslArg, sw);
And we will receive the argument from xslt like below
<!--<xsl:param name="employeeId"/>-->
<xsl:param name="employeeId"/>
If we see our XML then we will find that there are a ‘Caption’ attribute in each node. This is the caption of each value while show the output. On the other hand, to give input some time it is better to show a dropdown list rather than a traditional textbox. Suppose, when user will choose country it is more meaningful to show a country list rather than a textbox. To fulfill this purpose, we have a similar attribute named ‘type’ in some xml node. And by inspecting this attribute we have to render the appropriate aspnet server control from XSLT
<xsl:choose>
<xsl:when test="translate($varType,$up,$lo)='countryddl'">
<asp:DropDownList id="{concat('ddlCountry',$rowindex)}" runat="server"
DataTextField="Text" DataValueField="Value">
<asp:ListItem value="{.}">
<xsl:value-of select="."/>
</asp:ListItem>
</asp:DropDownList>
</xsl:when>
<xsl:otherwise>
<asp:TextBox ID="{$varId}" runat="server" Text="{.}" width="205px" ></asp:TextBox>
<xsl:if test="translate($isRequired,$up,$lo)='yes'">
<asp:RequiredFieldValidator ErrorMessage=" Required Field" runat="server"
ControlToValidate="{$varId}" />
</xsl:if>
</xsl:otherwise>
</xsl:choose>
At last, we must have to declare a button to save the inputted data in xslt
<asp:Button ID="btnSaveAddress" runat="server" BackColor="White"
BorderColor="DeepSkyBlue" BorderStyle="Solid" BorderWidth="1px"
Font-Names="Tahoma" Font-Size="10pt" Text="Save Data" />
Now we have to set event handler for this button from the code behind. ParseControl function will make our work very easy by parsing the XML string to asp.net server control. To get a reference of newly created controls we have to call the FindControl method. As soon as we get the reference of the control we can set event handler for that control. One thing is very important to know that the event handler adding process should be after parsing the control. Because before parsing, the control will not be available. Also Parsing should be in Page_Init event so that the controls will be found in the rest of the life cycle.
//parse control
Control ctrl = Page.ParseControl(result);
phEmployeeAddress.Controls.Add(ctrl);
//find control to add event handler
Button btnSaveAddress = (Button)phEmployeeAddress.FindControl("btnSaveAddress");
btnSaveAddress.Click += new EventHandler(btnSaveAddress_Click);
We have almost covered everything. The most interesting thing is, using XSLT our ASPX page will become very simple and clear look. Here is the full aspx source
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!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>Dynamic ASP.net Controls Using Xslt</title>
</head>
<body>
<form id="form1" runat="server">
<div style="float: right; background-color: Yellow">
<asp:Label ID="lblMessage" runat="server" Text="Label"></asp:Label>
</div>
<div>
<asp:Label ID="Label1" runat="server" Text="Choose Employee"></asp:Label>
<asp:DropDownList ID="ddlEmployee" runat="server" Width="128px">
<asp:ListItem Value="1">Ehsan</asp:ListItem>
<asp:ListItem Value="2">Ashraf</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnLoadData" runat="server" BackColor="White"
BorderColor="DeepSkyBlue" BorderStyle="Solid" BorderWidth="1px"
Font-Names="Tahoma" Font-Size="10pt" Text="Load Data"
OnClick="btnLoadData_Click" /><br />
<br />
<asp:PlaceHolder ID="phEmployeeAddress" runat="server"></asp:PlaceHolder>
</div>
</form>
</body>
</html>
All the XSLT controls will be extracted to PlaceHolder and here is the entire XSLT used to render the html and server controls
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:asp="remove">
<xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="yes"/>
<!--<xsl:param name="employeeId"/>-->
<xsl:param name="employeeId"/>
<xsl:template match="/root">
<xsl:for-each select="Employee">
<xsl:if test="@Id = $employeeId">
<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF">
<tbody>
<tr>
<td>
<xsl:apply-templates select="Address">
<!--<xsl:with-param name="count" select="$count"/>-->
</xsl:apply-templates>
</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td align="right">
<span style="margin-right:20%">
<asp:Button ID="btnSaveAddress" runat="server" BackColor="White"
BorderColor="DeepSkyBlue" BorderStyle="Solid" BorderWidth="1px"
Font-Names="Tahoma" Font-Size="10pt" Text="Save Data" />
</span>
<span> </span>
</td>
</tr>
</tbody>
</table>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="HomeAddress" match="/root/Employee/Address">
<table width="100%">
<tr>
<td height="30" colspan="2" align="left">
<strong>
<xsl:value-of select="@Caption"/>
</strong>
</td>
</tr>
<tr>
<td height="2" colspan="2" align="left" bgcolor="#CCCC99"></td>
</tr>
<tr>
<td width="50%" height="30" align="left" valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="4" height="4"></td>
</tr>
<tr>
<xsl:for-each select="child::*">
<xsl:variable name="rowindex" select="position()"></xsl:variable>
<td align="left" valign="top">
<table cellpadding="4">
<tr>
<td colspan="4" height="28" align="left" valign="top">
<strong>
<xsl:value-of select="@Caption"/>
</strong>
</td>
</tr>
<xsl:for-each select="child::*">
<xsl:variable name="varType" select="@Type"></xsl:variable>
<xsl:variable name="isRequired" select="@Required"></xsl:variable>
<xsl:variable name="varId"
select="translate(concat(concat(concat(@Caption,'_'),$rowindex),position()),' ','_')"></xsl:variable>
<xsl:variable name="up" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lo" select="'abcdefghijklmnopqrstuvwxyz'"/>
<tr>
<td height="28" align="left" valign="top">
<xsl:value-of select="@Caption"/>
</td>
<td colspan="3" align="left" valign="top" height="28">
<xsl:choose>
<xsl:when test="translate($varType,$up,$lo)='countryddl'">
<asp:DropDownList id="{concat('ddlCountry',$rowindex)}"
runat="server" DataTextField="Text" DataValueField="Value">
<asp:ListItem value="{.}">
<xsl:value-of select="."/>
</asp:ListItem>
</asp:DropDownList>
</xsl:when>
<xsl:otherwise>
<asp:TextBox ID="{$varId}" runat="server" Text="{.}"
width="205px" ></asp:TextBox>
<xsl:if test="translate($isRequired,$up,$lo)='yes'">
<asp:RequiredFieldValidator ErrorMessage="
Required Field" runat="server" ControlToValidate="{$varId}" />
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:for-each>
</table>
</td>
</xsl:for-each>
</tr>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
SummaryAsp.net server controls are very powerful in web application without any doubt and by combining XML and XSLT with it we can make web application more powerful, easier, efficient and re-usable. Also by using XML and XSLT the application UI script will look clean and will be easier to maintain. I hope this will be great start for those who wants to make their site more dynamic and structured using XML and XSLT with the great power of ASP.Net controls. Enjoy!
|
|||||||||||||||||||||||||||||||||||