Dynamically linked comboboxes set for ASP.NET






3.06/5 (7 votes)
Aug 10, 2004
2 min read

67293

1668
Creating and using Custom Control in ASP.NET
Introduction
If you frequently create comboboxes range bounded with database and have tired to write the same code repeatedly this article is for you. During enter or searching process on the web site, you often need to use selected element in first combobox for filling up from a second combobox from database, selected element in second combo for filling up third combo and so forth. At the same time it might be to page refresh without submit as well.
Realization
I attempt to solve this problem by realizing Custom control idea implemented
in ASP .NET and well explained in Jeff Prosize’s book “Programming Microsoft
.NET”. To realize refreshing w/o submit I organized my aspx file in frameset
with one hidden frame and this one pumps all data from database and fills up
comboboxes in visible frame without submitting it. This realization must do the
job on all browsers supporting carrying over OPTION
object of
SELECT
tag between frames (in particular IE 5.5 and higher).
Source code
Control’s server source is in LocControl.cs, hidden frame’s code-behind in
HiddenFrm.aspx.cs. In both have been realized two functions for filling up
comboboxes by SQL or OLE DB data Provider. For activate SQL data provider it is
necessary to add attribute SqlServer=”true”
, otherwise control will
use OLE DB provider and developer must apply appropriate Connection string.
Client side code is in scripts.js.
Let us describe outline of program’s job.
- Custom control begin his job from source provided in Loccontrol.cs rendering needed HTML code to container aspx file at the time of it’s loading and filling up first combobox.
- Where user select item in filled combo client code ( OnChange() from scripts.js) carries out needed data for fill next combo in HiddenFrm.aspx and submit it.
- Server code in HiddenFrm.aspx.cs fill next combo.
- Client code in HiddenFrmOnLoad() fill up combo in container page where is comboboxes set.
When user continue his selects the program carries out the step 2.
Fragments of LocControl.cspublic class LocControl: System.Web.UI.Control { ... ... public string SqlServer // if this attribute value = true than // custom will use SQL Data Provider, otherwize OLE DB Provider { get{ return bSqlServer;} set{ bSqlServer= value;} } public string ComboData // String separated by ";" for each combobox. // Between ";" write // data needed for fill OPTION elements of // SELECT tag separated by space ' '. // // For First element will be three parameters // First parameter: Table name from assigned in // ConString data source // Second paramente: Field name of Table that will // be text value of combobox // Third parameter: Field name of Table that wiil be value // for combobox item and will use for seek in // following combobox // For Follwing comboboxes will be four parameters: // First three parameters have same meaning that was for First combobox. // Fourth parameter point out the key field in the Table // where you select data for this combobox. { get { return CDates;} set {CDates = value;} } public string ConString // set connection string for appropriate provider { get{ return scon;} set{ scon = value;} } public string Captions //comboboxes captions { get{ return sCaptions;} set{ sCaptions = value;} } protected override void Render(HtmlTextWriter writer) // fill custom control HTML code on page // { string htextname = ""; //check ComboData attribute for empty if(CDates == null) return; ArrayComboDates = CDates.Split(';'); //separate ComboData attribute's data int comboquantity = ArrayComboDates.Length; // hidden textbox for save ComboData attribute of control writer.WriteBeginTag("input"); ... // hidden textbox for save connection string writer.WriteBeginTag("input"); writer.WriteAttribute("type","hidden"); string hconnection = UniqueID+"_sconn"; writer.WriteAttribute("name",hconnection); if(bSqlServer == "true") writer.WriteAttribute("value", scon + "??" + "true"); else writer.WriteAttribute("value",scon ); writer.Write(HtmlTextWriter.TagRightChar); // begin <table tag where arrange control's elements writer.WriteBeginTag("table"); ... // print Captions for each combobox writer.WriteFullBeginTag("tr"); writer.WriteLine(); if(sCaptions !=null) capsarray = sCaptions.Split(';'); ... // print SELECT tags for each combobox writer.WriteFullBeginTag("tr"); string[] ctrlname = new string[comboquantity]; for(int i=0; i < comboquantity; i++) { //begin td writer.WriteBeginTag("td"); writer.WriteAttribute("align","center"); writer.Write(HtmlTextWriter.TagRightChar); writer.WriteLine(); writer.WriteBeginTag("select"); ctrlname[i] = string.Format("{0}_{1}",this.UniqueID,i+1); writer.WriteAttribute("name", ctrlname[i]); if(i != (comboquantity - 1)) writer.Write( "OnChange=\"OnChange(this.options[this.selectedIndex].value, this.name,this.form.name," + comboquantity.ToString() + "," + htextname + "," + hconnection + ")\""); if(ID!=null) writer.WriteAttribute("id",this.ClientID); writer.Write(HtmlTextWriter.TagRightChar); // fill up first combobox if(i == 0) if(bSqlServer == "true") FillClCombo(i,writer); // fill up by Sql provider else FillClCombo_uni(i,writer); // fill up by OLE DB provider writer.Write("</select>"); writer.WriteEndTag("td"); writer.WriteLine(); } writer.WriteEndTag("tr"); writer.Write("</Table>"); }
When user selects item in combo appropriate data are transferred from your
aspx file to hidden frame(HiddenFrm.aspx ) by OnChange()
function
from subscript.js file
JavaScript source code
void function OnChange(combovalue,name,frmname,
comboquantity,htext,hconnection)
{
// get general base of combobox names using active combobox name
var baseofname = name.substr(0,name.lastIndexOf("_") + 1);
var number = name.substr(name.lastIndexOf("_")+1,name.length);
var intnumber = parseInt(number) + 1;
var nextcomboname;
//clean up subsequent comboboxes
for( i=intnumber; i < comboquantity; i++)
{
var n = i+1;
nextcomboname = baseofname + n
eval("document." + frmname + "." + nextcomboname + ".length = 0;");
}
//passing data from active page to Hidden form(HiddenFrm.aspx)
eval("var cfrm = document." + frmname);
eval("parent.bottomFrame.document.HiddenFrm.combotext.value=" + combovalue);
parent.bottomFrame.document.HiddenFrm.comboname.value=frmname + "." + name;
parent.bottomFrame.document.HiddenFrm.TextCDatas.value = htext.value;
parent.bottomFrame.document.HiddenFrm.TextConnection.value =
hconnection.value;
parent.bottomFrame.document.HiddenFrm.submit();
}
Come back to server side and look at HiddenFrm.aspx.cs. Job continue here.
Fragments from HiddenFrm.aspx.cs
namespace HiddenFrm_ns
{
public class HiddenFrm : System.Web.UI.Page
{
...
...
private void Page_Load(object sender, System.EventArgs e)
{
string apppath =Context.Request.ApplicationPath;
//register script block
string scrsrc = "<script src=" + apppath +
"/KarControl/script.js></script>";
if(!IsClientScriptBlockRegistered("cSrcript"))
RegisterClientScriptBlock("cScript", scrsrc);
Response.Write("<br>");
// Get filled from active page data and fill up the intermediate combo
NameValueCollection fnv = Request.Form;
if(fnv.Count !=0)
{
string[] condata = (Request.Form.GetValues(
"TextConnection")[0]).Split('?');
con = condata[0];
string combotext = fnv.GetValues("combotext")[0];
//key value for filter data from
//next table in database
string comboname = (fnv.GetValues("comboname"))[0];
//name of combo that initiate submit in
// active page
// get name of next combo
char[] d = {'_'};
int ind = comboname.LastIndexOfAny(d);
string cnum = comboname.Substring(ind+1,comboname.Length -(ind + 1));
int icombonum =(int)Convert.ChangeType(cnum,ind.GetType());
icombonum = icombonum + 1;
string ctrlname = comboname.Substring(0,ind+1);
string nextcombo = ctrlname + icombonum.ToString();
// if after connection string is ; and "true" word this is SqlServer mode
if(condata.Length == 3 && condata[1] == "" && condata[2]=="true")
FillComboSql(combotext,icombonum); // fill combo by SQL Provider
else
FillComboUni(combotext,icombonum); //fill combo by OLE DB provider
this.comboname.Text = nextcombo;
}
}
...
...
}
}
Back stream of data to your active page provides
HiddenFrmOnLoad()
function from subscript.js file.
JavaScript source code from scropt.js
//send filled up combobox’s data from
// HiddenFrm.aspx to your active page
void function HiddenFrmOnLoad()
{
var op;
var text;
if(document.HiddenFrm.comboname.value != "")
{
text = "var mcombo = parent.mainFrame.document." +
HiddenFrm.comboname.value;
eval(text);
mcombo.options[0]= new Option("","");
for(i=0; i < document.HiddenFrm.hcombo.length; i++)
{
op = document.HiddenFrm.hcombo.options[i];
mcombo.options[i+1] = new Option(op.text,op.value);
}
mcombo.length = document.HiddenFrm.hcombo.length + 1;
}
}
Using the code
Don’t need to save LocControl.cs and HiddenFrm.aspx.cs files in your project, their compiled code is in LocControl.dll. If you want to change this sources apply this command line:
- csc /t:library /out:LocControl.dll LocControl.cs HiddenFrm.aspx.cs.
Manual for applying for this custom control is in Readme.txt.