Yesterday I need to implement in a quick way a three style checkbox in a project based on asp.net 3.5. The requirements stated that I must not spend too much time designing an entire new control, but the solution should be usable by other people with minimum impact. Here is the result I obtained.
The checkbox can be, selected, not selected, or not used and when it is not used it is blue, like the one in windows forms. This was needed to satisfy a requirement, I need to make possible for the user to specify complex filters, and I have boolean fields on my entities where the user can ask for: filter only the one with field==true or field==false or no filter for that field. To achieve the result you can simply use a standard checkbox.
1: <asp:CheckBox ID="chkCCSignaled" CssClass="threestate" runat="server" />
The only stuff you need is that you need to assign the “threestate†style to the checkbox. (this satisfy the need of the minimuym impact, other developers that want to use that checkbox can simply add that css to a standard checkbox). The dirty work is done by an unobtrusive jquery javascript that gets injected with the masterpage.
1: $(function() {
2: $('span.threestate')
3: .log('checkboxes')
4: .each(function() {
5: var thespan = $(this);
6: var checkbox = $(thespan.children().get(0));
7: var name = checkbox.attr('id') + '_hf';
8:
9: var innerhf = $('<input type="hidden" name="' + name + '" id="' + name + '" />');
10: thespan.prepend(innerhf);
11:
12: var innerslide = $('<div style="width:' + thespan.width() + 'px; height:' + thespan.height() + 'px" class="chboverlay" />')
13: .css('opacity', 0.8)
14: .click(function() {
15: //debugger;
16: if (innerhf.val() == 2) {
17: $(this).css('opacity', 0.0)
18: checkbox.attr('checked', true);
19: innerhf.val(1);
20: } else {
21: if (innerhf.val() == 1) {
22: checkbox.attr('checked', false);
23: innerhf.val(0);
24: } else {
25: $(this).css('opacity', 0.8)
26: checkbox.attr('checked', false);
27: innerhf.val(2);
28: }
29: }
30: });
31: var chkvalue = "2";
32:
33: if (checkbox.parent().attr('threestatevalue') != undefined) {
34: chkvalue = checkbox.parent().attr('threestatevalue');
35: if (chkvalue == "0" || chkvalue == "1") {
36: innerslide.css('opacity', 0.0)
37: }
38: }
39: innerhf.val(chkvalue);
40: thespan.prepend(innerslide);
41: });
The solution is quite simple, I create a new div with a specific class to overlay the checkbox and create the blue layer when the checkbox is in state “undefinedâ€. the tricky part is that I need to manage three possible value for the checkbox and I need to pass that value to the server during a postback, so I create dynamically an hidden input with the same id of the checkbox and the “_hf†string at the end. In that hidden field I store the actual value of the checkbox, 0 not selected, 1 selected and 2 undefined. The rest of the script is needed to manage the transition between states reacting to the click event of the checkbox.
In the server code I need to grab the three state value, so I created a simple extension method.
1: Namespace SiteCode.V2
2: Public Module ThreeStateCheckbox
3:
4: <Extension()> _
5: Public Function GetThreeStateValue(ByVal cb As CheckBox) As Nullable(Of Boolean)
6: Dim value As String = HttpContext.Current.Request.Form(cb.ClientID + "_hf")
7: cb.Attributes("threestatevalue") = value
8: Select Case value
9: Case "0" : Return False
10: Case "1" : Return True
11: Case "2" : Return Nothing
12: End Select
13:
14: End Function
15: End Module
16: End Namespace
This simple method is an extension method for the checkbox control, it simply grab the value of the dynamically generated hidden field from the Request.Form collection. After taking actual value, he add the attribute “threestatevalue†to the checkbox, because the client script should be able to restore the state of the checkbox after a postback. Now you can simply get the value with this code.
1: Public ReadOnly Property IsCCChecked() As Nullable(Of Boolean)
2: Get
3: Return chkCC.GetThreeStateValue()
4: End Get
5: End Property
With this structure the developer can simply add the css (as seen before) and use this extension method to grab the value, this without the need to author a whole new control.
I used this in a user control (that represents a complex filter and gets used in several pages), and this user control exposes the selection status to external control with readonly property that return Nullable(of Boolean). Thanks to extension method I can simply add the css to the checkbox, use GetThreeStateValue to grab the actual status of the checkbox and the game is done.
alk.
Tags: asp.net
Tags: ASP.NET






February 25th, 2010 at 9:58 pm
This appears to be precisely what I need. Unfortunately, I am getting the error “expecting more source characters” when I attempt to include the script on a page. I also get that error from the Visual Studio 2008 developer on the js page where I put the script
Can you tell me what I am doing wrong.
February 26th, 2010 at 8:55 am
This is indeed a strange error, it is a server error (code 500) or it is a javascript error? Have you an example that you can send me by email so I give it a check?
alk.