|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
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
Introduction
I was recently given a website to make changes on. The HTML was already
done and signed off by the client, and could thus not be changed. My SolutionThe first thing to do is to make the HTML Table accessible by adding
an Id and the "runat='server'" attribute. Now we can transverse the
table, and access it's child controls from the CodeBehind. <asp:CheckBox group="1" ID="CheckBox1" runat="server" Text="Option 1" />
Now we can look at the server side code: /// <summary>
/// Recursively find a set of controls in a container
/// </summary>
/// <param name="type">The type of control to find.</param>
/// <param name="container">The container to search in.</param>
/// <param name="controls">The list of found controls</param>
private void FindControls(Type type, Control container, ref System.Collections.Generic.List<Control> controls) {
foreach (Control c in container.Controls) {
if (c.GetType() == type) controls.Add(c);
FindControls(type, c, ref controls);
}
}
Now when the page loads we can get a list of the CheckBox controls and add some JavaScript to them to simulate the RadioButtonList behaviour. System.Collections.Generic.List<Control> controls = new System.Collections.Generic.List<Control≶(); // List of the checkboxes
FindControls(typeof(CheckBox), tblOptions, ref controls); // get the checkboxes
// a list of the checkbox groups and their related checkboxes to help with js generation.
System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<CheckBox>> chkGroups = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<CheckBox>>();
// get the controls
foreach (Control c in controls) {
CheckBox chk = (c as CheckBox);
// build the checkbox group list
if (null != chk.Attributes["group"] && string.Empty != chk.Attributes["group"]) {
if (chkGroups.ContainsKey(chk.Attributes["group"])) {
chkGroups[chk.Attributes["group"]].Add(chk);
} else {
chkGroups.Add(chk.Attributes["group"], new System.Collections.Generic.List<CheckBox>());
chkGroups[chk.Attributes["group"]].Add(chk);
}
}
}
// generate the checkbox js to simmulate option groups
foreach (string k in chkGroups.Keys) {
foreach (CheckBox cb in chkGroups[k]) {
string js = "javascript:if(this.checked){";
foreach (CheckBox cb2 in chkGroups[k]) {
if (cb.ID == cb2.ID) continue;
js += "document.getElementById('" + cb2.ClientID + "').checked=false;";
}
js += "};";
cb.Attributes.Add("onclick", js);
}
}
Try out the result: CheckBoxOptionGroups_demo.zip (extract and open CheckBoxOptionGroups.html) Following that wonderful philosophy "Less is More", I've decided to
store all the selections in just one field in the db using Flags. In
this example we'll just use a Cookie. <asp:CheckBox bit="1" group="1" ID="CheckBox1" runat="server" Text="Option 1" />
Now when the user has made his selection, we can check for the checked CheckBox controls and add up their Flag values. private void UpdateOptionFlags() {
long optionFlags = 0;
System.Collections.Generic.List<Control> controls = new System.Collections.Generic.List<Control>(); // List of the checkboxes
FindControls(typeof(CheckBox), tblOptions, ref controls); // get the checkboxes
// iterate the list of checkboxes and get the set flags
foreach (Control c in controls) {
CheckBox chk = (c as CheckBox);
if (null == chk.Attributes["bit"]) continue; //if not one of the flag checkboxes try the next one.
long bit = 0;
if (!long.TryParse(chk.Attributes["bit"], out bit)) continue; //if no workable flag try the next one.
if (chk.Checked) optionFlags += bit;
}
// Set selected options value
Response.Cookies.Clear();
Response.Cookies.Add(new HttpCookie("OptionFlags", Convert.ToString(optionFlags)));
}
All that's left now is to read the selected flags and set the checked value of the relevant CheckBox controls. Here is the completed method to simulate the RadioButtonList behaviour and to read the selected values. private void LoadOptionFlags() {
System.Collections.Generic.List<Control> controls = new System.Collections.Generic.List<Control≶(); // List of the checkboxes
FindControls(typeof(CheckBox), tblOptions, ref controls); // get the checkboxes
// a list of the checkbox groups and their related checkboxes to help with js generation.
System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<CheckBox>> chkGroups = new System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<CheckBox>>();
// get the controls
foreach (Control c in controls) {
CheckBox chk = (c as CheckBox);
CheckBox chk = (c as CheckBox);
if (null == chk.Attributes["bit"]) continue; //if not one of the flag checkboxes try the next one.
long bit = 0;
if (!long.TryParse(chk.Attributes["bit"], out bit)) continue; //if no workable bit try the next one.
// check to see if the bit was set
chk.Checked = ((bit & optionFlags) != 0);
// build the checkbox group list
if (null != chk.Attributes["group"] && string.Empty != chk.Attributes["group"]) {
if (chkGroups.ContainsKey(chk.Attributes["group"])) {
chkGroups[chk.Attributes["group"]].Add(chk);
} else {
chkGroups.Add(chk.Attributes["group"], new System.Collections.Generic.List
Using the CodeJust extract to a local directory, open the website with Visual Studio 2005/2008 and run. History28 June 2008
|
|||||||||||||||||||||||||||||||||||