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.cs
public class LocControl: System.Web.UI.Control
{
...
...
public string SqlServer
{
get{ return bSqlServer;}
set{ bSqlServer= value;}
}
public string ComboData
{
get { return CDates;}
set {CDates = value;}
}
public string ConString
{
get{ return scon;}
set{ scon = value;}
}
public string Captions
{
get{ return sCaptions;}
set{ sCaptions = value;}
}
protected override void Render(HtmlTextWriter writer)
{
string htextname = "";
if(CDates == null)
return;
ArrayComboDates = CDates.Split(';');
int comboquantity = ArrayComboDates.Length;
writer.WriteBeginTag("input");
...
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);
writer.WriteBeginTag("table");
...
writer.WriteFullBeginTag("tr");
writer.WriteLine();
if(sCaptions !=null)
capsarray = sCaptions.Split(';');
...
writer.WriteFullBeginTag("tr");
string[] ctrlname = new string[comboquantity];
for(int i=0; i < comboquantity; i++)
{
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);
if(i == 0)
if(bSqlServer == "true")
FillClCombo(i,writer);
else
FillClCombo_uni(i,writer);
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)
{
var baseofname = name.substr(0,name.lastIndexOf("_") + 1);
var number = name.substr(name.lastIndexOf("_")+1,name.length);
var intnumber = parseInt(number) + 1;
var nextcomboname;
for( i=intnumber; i < comboquantity; i++)
{
var n = i+1;
nextcomboname = baseofname + n
eval("document." + frmname + "." + nextcomboname + ".length = 0;");
}
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;
string scrsrc = "<script src=" + apppath +
"/KarControl/script.js></script>";
if(!IsClientScriptBlockRegistered("cSrcript"))
RegisterClientScriptBlock("cScript", scrsrc);
Response.Write("<br>");
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];
string comboname = (fnv.GetValues("comboname"))[0];
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(condata.Length == 3 && condata[1] == "" && condata[2]=="true")
FillComboSql(combotext,icombonum);
else
FillComboUni(combotext,icombonum);
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
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.