最近在改之前很早的一个项目,用的还是WebForm开发的。追加功能之后,有个地方是弹出层来填写表单信息,然后保存到datagrid中。需要通过js获取CheckBoxList的值然后保存到列表中。CheckBoxList控件的数据源是从数据库中获取的,在后台绑定的。一切都很顺利,但是到了保存弹出表单的时候,发现js获取不到CheckBoxList的值。在我的印象中很早之前解决过这个问题,但是没有单独写一篇博客来记录,导致了浪费了一些查询时间。
目的很简单就是保留所有CheckBoxList的原有功能,在不影响原功能使用的前提下,能够通过js来获取CheckBoxList的选中的Value和Text。
js获取控件的值属于前端的操作,个人比较喜欢Google的Chrome浏览器,对于调试分析前端,包括js、css等非常的方便。
回正题,首先通过查看前端的源代码来看一下CheckBoxList生成的html。
原始的页面html代码:
<div>
<asp:CheckBoxList ID="cklCoreProduct" runat="server" RepeatDirection="Horizontal" RepeatLayout="Flow" RepeatColumns="6" >
</asp:CheckBoxList>
<asp:TextBox ID="tbCoreProductOther" runat="server" Style="width: 150px; height: 24px; border-bottom: 1px solid; float: right; margin: -30px 30px 10px;" class="easyui-validatebox" data-options="required:false,validType:'length[1,40]'"></asp:TextBox>
</div>
后台绑定值
if (dt != null && dt.Rows.Count > 0)
{
cklCoreProduct.DataSource = dt;
cklCoreProduct.DataValueField = "Code";
cklCoreProduct.DataTextField = "Description";
cklCoreProduct.DataBind();
}
页面中生成的html代码
<div>
<span id="cklCoreProduct">
<input id="cklCoreProduct_0" type="checkbox" name="cklCoreProduct$0" checked="checked"><label for="cklCoreProduct_0">基础软件</label>
<input id="cklCoreProduct_1" type="checkbox" name="cklCoreProduct$1" checked="checked"><label for="cklCoreProduct_1">支撑软件</label>
<input id="cklCoreProduct_2" type="checkbox" name="cklCoreProduct$2"><label for="cklCoreProduct_2">应用软件</label>
<input id="cklCoreProduct_4" type="checkbox" name="cklCoreProduct$4"><label for="cklCoreProduct_4">信息安全软件</label>
<input id="cklCoreProduct_5" type="checkbox" name="cklCoreProduct$5"><label for="cklCoreProduct_5">软件定制服务</label>
<input id="cklCoreProduct_6" type="checkbox" name="cklCoreProduct$6"><label for="cklCoreProduct_6">信息系统集成服务</label>
<input id="cklCoreProduct_7" type="checkbox" name="cklCoreProduct$7"><label for="cklCoreProduct_7">信息技术咨询服务</label>
<input id="cklCoreProduct_9" type="checkbox" name="cklCoreProduct$9"><label for="cklCoreProduct_9">其他</label></span>
</div>
可以看到生成的每个checkbox上根本就不存在value值。但是后台可以通过获取此控件获取到每一个的值,经过研究发现微软是通过viewstate来绑定值。来回传递。这样通过js获取选中项的value值时,只会得到一个on值。
微软的webform控件,都可以通过后台自由指定Attribute属性。这样可以使绑定的每一个ListItem上追加一个Attribute属性来保存Value值。
改造后台代码
// 为了js 获取CheckBoxList的各项的值
foreach (DataRow row in dt.Rows)
{
ListItem li = new ListItem();
li.Text = row["Description"].ToString();
li.Value = row["Code"].ToString();
li.Attributes.Add("myValue", row["Code"].ToString());
cbl.Items.Add(li);
}
生成的页面代码
<div>
<span id="cklCoreProduct">
<span myvalue="01">
<input id="cklCoreProduct_0" type="checkbox" name="cklCoreProduct$0" checked="checked">
<label for="cklCoreProduct_0">基础软件</label>
</span>
<span myvalue="02">
<input id="cklCoreProduct_1" type="checkbox" name="cklCoreProduct$1" checked="checked">
<label for="cklCoreProduct_1">支撑软件</label>
</span>
<span myvalue="03">
<input id="cklCoreProduct_2" type="checkbox" name="cklCoreProduct$2">
<label for="cklCoreProduct_2">应用软件</label>
</span>
...
</span>
</div>
可以看到在每一组checkbox和label上层又增加了一个span元素,并且里面有我们在后台指定的myvalue的属性。这样我们就可以通过js来获取值了。
// 获取选中的checkboxlist的值和文本
var types = [];
var typeNames = [];
$("#detail_Type input:checked").each(function(){
//alert($(this).parent("span").attr("myValue"));
types.push($(this).parent("span").attr("myValue"));
typeNames.push($(this).next().html());
});
经过验证,此方法指定的Attribute名称不能是value。第一次尝试走了弯路。特提醒大家