ASP.Net CheckBoxes should be able to have values
The ASP.Net CheckBox and CheckBoxList control don’t allow for the use of the full W3C HTML standard. For some reason Microsoft decided to implement a reduced functionality version that creates more work for the programmer. Come on Microsoft why can’t you follow even the simplest of standards? In this case it would make coding the .Net framework easier for you not to mention us!
The W3C HTML 4.01 specification specifically states for the value attribute to:
– Specify for radio buttons and checkboxes –
W3C HTML 4.01 Specification – INPUT Element
To me this quote reads as a strong recommendation to specify the value attribute rather than leave it up to the browsers default (generally "On"). Microsoft decided to not even allow the value attribute to be set. They went so far as to have a validation message built into Visual Studio that says:
Attribute ‘Value’ is not a valid attribute of element ‘CheckBox’
If you ignore the warning and run the page, the value attribute is missing. I have even tried circumventing the ASP.Net HTML-izer by adding value to the attributes collection with no success. Microsoft intentionally strips it, so I can only assume they have some reasoning behind this behavior and I imagine they will say something about security in defense.
There is one way to circumvent the behavior but it requires not using ASP.Net controls. Simply insert traditional input type=”checkbox” elements into your page and collect their values using Request.Form.
Sub Page_Load ()
Dim value As String
value = Request.Form("chkItem")
End Sub
…
<input type="checkbox" id="chkItem" name="chkItem" />
<label for="chkItem">CheckBox Item Text</label>
I made a big deal out of this issue simply because to me it doesn’t make any sense. You can get around the issue and still use ASP.Net controls but it requires extra coding.
Sub Page_Load ()
Dim value As String
If chkItem.Checked Then
value = "Some Value"
Else
value = "Some Other Value"
End If
End Sub
…
<asp:CheckBox ID="chkItem" Text="CheckBox Item Text" runat="server" />
When using the CheckBoxList control you will notice ASP.Net uses tables to layout the list. To keep it from doing this you simply need to add a few attributes. It should then use much more standards compliant code. I also show how to access which boxes are checked after postback in a CheckBoxList.
Sub Page_Load ()
' Find out which boxes were checked
Dim value As String = ""
For Each item As ListItem In cblTest.Items
If item.Selected Then
value &= item.Value
End If
Next
End Sub
…
<asp:CheckBoxList ID="cblList" RepeatLayout="Flow" RepeatDirection="Horizontal" runat="server">
<asp:ListItem Text="Item 1" Value="1" />
<asp:ListItem Text="Item 2" Value="2" />
<asp:ListItem Text="Item 3" Value="3" />
</asp:CheckBoxList>
As always let me know if you have any questions.
Could you let me know how to collect checked values from a checkboxlist and store them in a database? [C#}
I am working on a survey using VS 2005, connected to a MS SQL 2005 database. The survey consists of textbox and checkboxlist. Using a submit button, “SqlDataSource1.Insert(); ” is run. Individual collected fields are matched to their corresponding fields in to be stored in the database.
The checkboxlist look like this…
a
b
c
Could you tell me how to put store these values? (there are fields in the database for these).
Database
ID
Name
Q1a
Q1b
Q1c
I have discovered that you can render the “value” attribute. You add the following code to your inherited checkbox custom control class:
protected override void AddAttributesToRender(HtmlTextWriter writer) { writer.AddAttribute(HtmlTextWriterAttribute.Value, this.DataSource.ToString()); base.AddAttributesToRender(writer); }What about the following?
Dim chkTest As New CheckBox
chkTest.InputAttributes(“value”) = “my custom value”
When the page renders, if you look at the source the value attribute is there as declared. I hope this helps.
I agree they should have included it. Easy to get around however:
public class CheckBoxWithValue : CheckBox { public string Value { get { return ViewState["Value"] as string; } set { ViewState["Value"] = value; } } }Ryan, your custom class doesn’t work. The value attribute is STILL not rendered in the final HTML on the page. It may be in the viewstate, but the tag doesn’t have it. If I ever find a solution, I’ll post it.
Here’s the solution:
Use the InputAttributes property rather than the Attributes property of the CheckBox class.
cb.InputAttributes["value"] = “foo”;
Works like a charm.
Found this on Dave Parslow’s blog:
http://www.daveparslow.com/2007/08/assigning-value-to-aspnet-checkbox.html
The “Value” attribute shows in my browser.
In my ASPX page:
Rendered HTML:
Family
So, the value shows in HTML for me. I’m using ASP.Net 2.0, and I do get the Validation Warning on Visual Studio. However, I’m ignoring it, as the attribute is rendered. Just wanted to share.
There is a similar problem with the name attribute. I’d like to render checkbox controls for use with client side scripts.
Although ChkBox.InputAttributes["name"] = “customName”; does add the name attribute to the HTML page. ASP makes this usless as it also puts in it’s duplicate name attribute.
I think Ryan’s custom class is the way to go, and as heared 100 times before we can just use InputAttributes to render the property to html:
public class CheckBoxWithValue : CheckBox { public string Value { get { return ViewState["Value"] as string; } set { ViewState["Value"] = value; } } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); this.InputAttributes["value"] = this.Value; } }I managed to sort this out by using the CheckedChanged event handler. All you need to do is programmatically change the checked value, then you can reference the checkbox.checked value directly because it fires before the page load event
like so….
protected void yourcheckbox_CheckedChanged(object sender, EventArgs e) { if (yourcheckbox.Checked == true) { yourcheckbox.Checked = false; } else { yourcheckbox.Checked = true; } }Hope this helps. :-)
I found an almost decent way of doing this:
Declare your checkbox:
Then you can programatically add any values by looping through your controls, looking for checkboxes, and doing this:
Control.InputAttributes.Add(“value”, Control.Attributes(“value”))
It will complain that value is not a valid attribute on the asp:checkbox tag, but it works.
Sorry, it stripped out my asp code:
asp:CheckBox runat=”server” value=”04″ id=”control”
I took what Ryan and WUZ provided and created a server control. This will appear in the toolbox.
I had to convert it to VB for this web application.
Option Strict On Option Explicit On Imports System Imports System.Collections.Generic Imports System.ComponentModel Imports System.Text Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Namespace UI.WebControls <ToolboxData("")> _ Public Class CheckBoxWithValue Inherits System.Web.UI.WebControls.CheckBox Property Value() As String Get Dim s As String = CStr(ViewState("Value")) If s Is Nothing Then Return String.Empty Else Return s End If End Get Set(ByVal value As String) ViewState("Value") = value End Set End Property Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) MyBase.OnPreRender(e) Me.InputAttributes("Value") = Me.Value End Sub Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter) writer.Write(Text) End Sub End Class End NamespaceOption Strict On
Option Explicit On
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace UI.WebControls
_
Public Class CheckBoxWithValue
Inherits System.Web.UI.WebControls.CheckBox
Property Value() As String
Get
Dim s As String = CStr(ViewState(“Value”))
If s Is Nothing Then
Return String.Empty
Else
Return s
End If
End Get
Set(ByVal value As String)
ViewState(“Value”) = value
End Set
End Property
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
MyBase.OnPreRender(e)
Me.InputAttributes(“Value”) = Me.Value
End Sub
Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
writer.Write(Text)
End Sub
End Class
End Namespace
and then and then i cut a fart
What about assigning a runat attribute to traditional type=”checkbox” element? This way you do not have to use Request.Form.