需求:用treeview列出所有课程,当用户选择一个大的分类名称,则所有小的分类全部选中,如果再取消一个小分类的选择,同样取消大分类的选择。
实现:
方法一:
后台用treeview控件,设置 ShowCheckBoxes="All",所有节点均显示checkbox,查看微软的msdn可以得知,虽然treeview的OnTreeNodeCheckChanged是在回发的时候执行,但是默认的是不回发的,如果要使用服务器端技术实现此功能,需要自己手动添加回发,代码如下:客户端
function postBackObject()
{
var o = window.event.srcElement;
if (o.type == "checkbox")
{
__doPostBack("","");
}
}
服务器端:在page_load事件里面添加TreeView1.Attributes.Add("onclick", "postBackObject()");
在OnTreeNodeCheckChanged的事件里面写入实现功能的代码。
但是以上方式给用户的体验不好,每选中一个节点都要回发服务器,因此改为客户端用jquery实现。
方法二:
运行当前页面,查看源代码,找出dom结构规律,写客户端代码:
$(document).ready(function(){
$(":checkbox").click(function(){//为页面所有的checkbox添加click事件
//alert($(this).attr("checked"));
if($(this).attr("checked")==true)//不能使用$(this).attr("checked")==“checked”
{
$(this).attr("checked",true);
var $div=$(this).parent().parent().parent().parent().next();
//alert($div.attr("tagName"));
if($div.attr("tagName")=="DIV")//此处用来避免以下情况:一个节点没有子节点
{
$div.find(":checkbox").each(function(){
$(this).attr("checked",true);
});
}
}
else
{
$(this).attr("checked",false);
var $div=$(this).parent().parent().parent().parent().next();
//alert($div.attr("tagName"));
if($div.attr("tagName")=="DIV")
{
$div.find(":checkbox").each(function(){
$(this).removeAttr("checked");
});
}
//如果父节点选中但是取消了某个子节点,则取消父节点
var $table=$(this).parent().parent().parent().parent().parent().prev();
if($table.attr("tagName")=="TABLE")
{
$table.find(":checkbox").each(function(){
$(this).removeAttr("checked");
});
}
}
});
});
这样可以实现需要的功能并且不需要回发服务器。
说明:当点击一个按钮回发服务器时,如果页面存在treeview控件,并且有OnTreeNodeCheckChanged事件,那么先执行事件,再执行button_click事件,即在两次回发服务器的结果判断treeview中checkbox的状态是否改变。