originally posted by viksi
IE WebControls.exe 2.1x.xx.x - Microsoft.Web.UI.WebControls.dll (1.0.2.xxx) - Framework 1.x.xxxx.x - ?.Net editor?
TREEVIEW:
[PROBLEM]
User needs a treeview control which shows multitiered data with the following business rules :-
1. If a node is checked / unchecked all the child nodes also get checked / unchecked.
2. If all the child nodes of a parent nodes are checked/unchecked (i.e. with the same status) the parent node also gets checked/unchecked.
3. The data has to be retrived from the tree and inserted into the database.
the Microsoft tree view control has a few bugs ..
1. if a client side oncheck event handler is used then no oncheck events are sent to the server.
2. The getAttribute("checked") does not return whether the control is currently checked or not but it returns whether its state has been toggled or not.
3. If checkbox is checked programmatically (i.e. using a script) , no event is generated on the server or the client.
4. The checked state of the node is inconsistant if manual / programmatical checkbox toggling is done.
[SOLUTION]
1.When the page is loaded the code gets a list of all the nodes which were checked via a recursive function which stores the node indexes in a comma seperated list.
2. When a node is checked the code checks whether the node is in the list of initially checked list , if yes then the code toggles the value being sent by the node.getAttribute("checked") method.
3. All child and parent nodes are checked using the above returned value.
4. To send the new values to the server the queueEvent method is used. But we have to send the values of the nodes that were clicked using the script too.
To achieve this a recursive function goes thru the treeview control and picks up the nodes whose state has changed , these nodes are put in the viewstate of the control using the queueEvent("checked",nodeindex) method.
3. when u use a getAttribute("Checked") see if this control was initially checked.. if yes then invert the value you got from the getattribute method.
[unsolved PROBLEM]
One problem that is still unsolved is the problem with the GUI.
Nodes that are already checked at the time of pageload have a problem when valuse are changed via script. If the node is checked manually and again toggled using a script , the node sometimes fails to refresh visibily; which means that even though the node is checked/unchecked the node displays as unchecked. The program reads this node as checked/ unchecked correctly and sends the values back to the server too.
This problem has been posted to microsoft , but microsoft does not support IE webcontrols currently.
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm8.aspx.vb" Inherits="WebApplication6.WebForm8"%>
<%@ Register TagPrefix="iewc" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls, Version=1.0.2.226, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>WebForm5</title>
<script event="oncheck" for="treeview1">
cb=treeview1.getTreeNode(treeview1.clickedNodeIndex);
var nodeid=cb.getNodeIndex();
//isChecked(cb);
//var searchstring=","+ nodeid +",";
if (defaultchecked(cb))// if this node was not in the original checkeds then we use it normally
{
cb.setAttribute("Checked", !cb.getAttribute("Checked"), 0);
}
bChecked=isChecked(cb);
TraverseChildren(cb.getChildren(),bChecked) ;
refreshtree(treeview1.getChildren());
checkParents(cb); // now we get the parents
if (cb.getParent()!=null)
{
if (cb.getParent().getParent()!=null)
{
//alert("getting grandparents");
checkParents(cb.getParent());
}
}
</script>
<script>
///main scripts **************************
var strvals;
function isChecked(Node)
{//alert("inside isChecked");
var oNode=Node;
return oNode.getAttribute("Checked");
}
//following funciton checks if all the siblings of a Checked nodes have the same value is that node
//if yes then it checks the parent
function checkParents(oNode)
{
var ind=oNode.getNodeIndex();
//alert ("node="+ind);
//ind=ind.toString;
//alert(ind.indexOf(".");
var oParent=oNode.getParent();
if (oParent==null)
{
//alert("baap is null");
return ;
}
///alert(oParent.getNodeIndex());
//alert ("node="+isChecked(oNode));
//alert("parent="+isChecked(oParent);
///alert(isChecked(oNode));
///alert(isChecked(oParent));
if (oParent.getAttribute("Checked")==oNode.getAttribute("Checked")) //both have the same value dont bother doing anything
{
alert ("parent and child have the same ischecked")
return ;
}
var siblings = oParent.getChildren();
// alert('siblings= '+siblings.length);
if (siblings.length==1)//only one child go ahed and check the parent
{
//oParent.setAttribute("checked",oNode.getAttribute("checked")) ;
oParent.setAttribute("Checked", !oParent.getAttribute("Checked"), 0);
//alert ("no siblings for this guy ");
}
else
{
var flag=true;
for(t=0;t<siblings.length;t++)
{
if (siblings[t].getAttribute("Checked")!=oNode.getAttribute("Checked"))
flag=false;
}
if (flag)
{
oParent.setAttribute("Checked", !oParent.getAttribute("Checked"), 0);
//alert("setting parent");
}
else
{
//alert("all the siblings do not have similar flags");
}
}
}
// Recursive function that traverses through the tree and checks/unchecks the nodes
function TraverseChildren(oColl, bChecked){
var oChild;
for (var i=0;i<oColl.length;i++){
oChild = oColl[i];
// Check/Uncheck the current node by accessing the setAttribute
(bChecked) ? oChild.setAttribute("Checked", false) : oChild.setAttribute("Checked", true);
if (oChild.getAttribute("Checked")!=bChecked)
{
oChild.setAttribute("Checked", bChecked,0);
}
// If you only want to select 1st level children
// you'll have to comment this line out...
TraverseChildren(oChild.getChildren(), bChecked);
}
}
function refreshtree(oColl)
{
var oChild;
for (var i=0;i<oColl.length;i++)
{
oChild = oColl[i];
oChild.setAttribute("Checked",oChild.getAttribute("Checked"),0);
refreshtree(oChild.getChildren());
}
}
function checkvals(oColl)
{
var oChild;
var nodeindex;
for (var i=0;i<oColl.length;i++)
{
oChild = oColl[i];
nodeindex=oChild.getNodeIndex();
searchstring=","+nodeindex+",";
//alert(searchstring + strvals.indexOf(searchstring));
if (oChild.getAttribute("Checked")&&(strvals.indexOf(searchstring)==-1))
{
treeview1.queueEvent("oncheck",nodeindex);
}
if ((oChild.getAttribute("Checked")==false)&&(strvals.indexOf(searchstring)!=-1))
{
treeview1.queueEvent("oncheck",nodeindex);
}
checkvals(oChild.getChildren());
}
//return false;
}
function defaultchecked(oNode)
{ // this function tells us whether this node was Checked when the page load
var indexid=oNode.getNodeIndex();
var searchstring=","+indexid+",";
if (strvals.indexOf(searchstring)!=-1)
return true;
return false;
}
</script>
<script event="onclick" for="treeview1">
node=treeview1.getTreeNode(treeview1.clickedNodeIndex);
//node.setAttribute("checked",!node.getAttribute("checked"));
var bChecked=node.getAttribute("Checked");
// ( bChecked)?node.setAttribute("Checked",false):node.setAttribute("Checked",true);
//(bChecked) ? oChild.setAttribute("checked", false) : oChild.setAttribute("checked", true);
// modifyNode(node, "checked", bChecked,!bChecked);
window.status=node.getAttribute("Checked");
// alert(node.getAttribute("innerhtml"));
alert(node.getAttribute("outerhtml"));
</script>
<script event="onload" for="window">
strvals=",";
populatestrvals(treeview1.getChildren());
//c.innerHTML=strvals;
function populatestrvals(oColl)
{
var oChild;
for (var i=0;i<oColl.length;i++)
{
oChild = oColl[i];
// Check/Uncheck the current node by accessing the setAttribute
if (oChild.getAttribute("Checked"))
{
strvals=strvals+oChild.getNodeIndex()+",";
}
populatestrvals(oChild.getChildren());
}
}
</script>
<meta content="Microsoft Visual Studio.NET 7.0" name="GENERATOR">
<meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<iewc:treeview id="treeview1" style="Z-INDEX: 101; LEFT: 253px; POSITION: absolute; TOP: 114px" runat="server">
<iewc:TreeNode CheckBox="True" Text="root1" Expanded="True">
<iewc:TreeNode CheckBox="True" Text="document1"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document3"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
</iewc:TreeNode>
<iewc:TreeNode Checked="True" CheckBox="True" Text="folder1" Expanded="True">
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
</iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2"></iewc:TreeNode>
<iewc:TreeNode CheckBox="True" Text="document2">
<iewc:TreeNode CheckBox="True" Text="Node1">
<iewc:TreeNode CheckBox="True" Text="Node1"></iewc:TreeNode>
</iewc:TreeNode>
</iewc:TreeNode>
</iewc:treeview>
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 329px; POSITION: absolute; TOP: 399px" runat="server" Text="sever button"></asp:Button></form>
<div id="c">
</div>
</body>
</HTML>
//*****************************************************
on the pageload event in the code behind file add - where button1 is the server side submit button
button1.Attributes.Add("onclick","return checkvals(treeview1.getChildren())");