vouzamo
04-02-2009, 05:55 AM
Hi,
I have made a recursive ASP function to write a nested collapsable list in tabular form from a database of categories (parents and children).
The function encounters a problem when it has completed and the outer function should resume... the Object Required error is thrown so rather than the outer function continue, the process stops. I have included my code below (with the connection string masked) and the output can be viewed at http://www.vouzamo.co.uk/category/category.asp
<html>
<head>
<script type="text/javascript">
var selectedCategories = '';
var flag = false;
<%
table = "var categories=["
set db = server.createobject("adodb.connection")
connection = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db.open (connection)
set rs = server.createobject("adodb.recordset")
sql = "SELECT * FROM categories"
set rs = db.execute(sql)
if not rs.EOF then
while not rs.EOF
id = rs("id")
parent = rs("parent")
table = table & "['" & id & "'],['" & parent & "'],"
rs.movenext()
wend
end if
table = left(table,(len(table) - 1))
table = table & "];"
%>
<%= table %>
function category(id)
{
var e = document.getElementById(id);
if(e.src.match(/^(.*)on\.png$/) === null)
{
document.getElementById(id).setAttribute('src','on.png');
selectedCategories = selectedCategories + ',' + id;
selectChild(id);
selectParent(id);
}
else
{
document.getElementById(id).setAttribute('src','off.png');
selectedCategories = selectedCategories.replace(',' + id,'');
unselectChild(id);
unselectParent(id);
}
}
function getChild(id)
{
var children = '';
for(var x = 0; x < categories.length; x++)
{
if(categories[x][1] == id)
{
if(children == '')
{
children = children + categories[x][0];
}
else
{
children = children + ',' + categories[x][0];
}
}
}
return children;
}
function getParent(id)
{
var parent = '';
for(var x = 0; x < categories.length; x++)
{
if(categories[x][0] == id)
{
parent = categories[x][1];
}
}
return parent;
}
function selectChild(id)
{
if(getChild(id) != '')
{
var children = getChild(id).split(',');
for(var x = 0; x < children.length; x++)
{
document.getElementById(children[x]).setAttribute('src','on.png');
selectedCategories = selectedCategories + ',' + children[x];
selectChild(children[x]);
}
}
}
function selectParent(id)
{
if(getParent(id) != '')
{
var parent = getParent(id);
var children = getChild(parent).split(',');
var flag = true;
for(var x = 0; x < children.length; x++)
{
var e = document.getElementById(children[x]);
if(e.src.match(/^(.*)on\.png$/) === null)
{
flag = false;
}
}
if(flag)
{
document.getElementById(parent).setAttribute('src','on.png');
}
else
{
document.getElementById(parent).setAttribute('src','part.png');
}
selectedCategories = selectedCategories + ',' + parent;
selectParent(parent);
}
}
function unselectChild(id)
{
if(getChild(id) != '')
{
var children = getChild(id).split(',');
for(var x = 0; x < children.length; x++)
{
document.getElementById(children[x]).setAttribute('src','off.png');
selectedCategories = selectedCategories.replace(',' + children[x],'');
unselectChild(children[x]);
}
}
}
function unselectParent(id)
{
if(getParent(id) != '')
{
var parent = getParent(id);
var children = getChild(parent).split(',');
var flag = false;
for(var x = 0; x < children.length; x++)
{
var e = document.getElementById(children[x]);
if(e.src.match(/^(.*)off\.png$/) === null)
{
flag = true;
}
}
if(!flag)
{
document.getElementById(parent).setAttribute('src','off.png');
}
else
{
document.getElementById(parent).setAttribute('src','part.png');
}
selectedCategories = selectedCategories.replace(',' + parent,'');
unselectParent(parent);
}
}
</script>
</head>
<body>
<table width="500">
<%
indent = 0
function categories(parent)
set db = server.createobject("adodb.connection")
connection = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db.open (connection)
set rs = server.createobject("adodb.recordset")
sql = "SELECT * FROM categories WHERE parent = '" & parent & "' ORDER BY name"
set rs = db.execute(sql)
if not rs.EOF then
while not rs.EOF
id = rs("id")
name = rs("name")
width = 460 - (indent * 20)
hasChild = false
set db2 = server.createobject("adodb.connection")
connection2 = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db2.open (connection2)
set rs2 = server.createobject("adodb.recordset")
sql2 = "SELECT * FROM categories WHERE parent = '" & id & "' LIMIT 1"
set rs2 = db2.execute(sql2)
if not rs2.EOF then
while not rs2.EOF
hasChild = true
rs2.movenext()
wend
end if
rs2.close
set rs2 = nothing
db2.close
set db2 = nothing
%>
<tr>
<%
x = 1
if(indent > 0) then
for x = 1 to indent step 1
%>
<td width="20"></td>
<%
next
end if
if(hasChild) then
if(parent = "") then
%>
<td width="20"><img id="<%= id %>_toggle" src="minus.gif" onClick="toggle('<%= id %>');"></td>
<%
else
%>
<td width="20"><img id="<%= id %>_toggle" src="plus.gif" onClick="toggle('<%= id %>');"></td>
<%
end if
else
%>
<td width="20"><img src="bullet.gif"></td>
<%
end if
%>
<td width="<%= width %>"><%= name %></td>
<td width="20"><img id="<%= id %>" src="off.png" onClick="category('<%= id %>');"></td>
</tr>
<%
if(hasChild) then
if(parent = "") then
%>
<tr id="<%= id %>_container" class="show">
<%
else
%>
<tr id="<%= id %>_container" class="hide">
<%
end if
%>
<td width="500">
<table width="500" cellpadding="0" cellspacing="0">
<%
indent = indent + 1
categories(id)
indent = indent - 1
%>
</table>
</td>
</tr>
<%
end if
rs.movenext()
wend
end if
rs.close
set rs = nothing
db.close
set db = nothing
end function
categories("")
%>
</table>
</body>
</html>
Note: the javascript is for a secondary function which allows the parents to inherit selection from the children client-side. It does not affect the ASP code.
Images used in this code can be found in the .zip file attached.
I have made a recursive ASP function to write a nested collapsable list in tabular form from a database of categories (parents and children).
The function encounters a problem when it has completed and the outer function should resume... the Object Required error is thrown so rather than the outer function continue, the process stops. I have included my code below (with the connection string masked) and the output can be viewed at http://www.vouzamo.co.uk/category/category.asp
<html>
<head>
<script type="text/javascript">
var selectedCategories = '';
var flag = false;
<%
table = "var categories=["
set db = server.createobject("adodb.connection")
connection = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db.open (connection)
set rs = server.createobject("adodb.recordset")
sql = "SELECT * FROM categories"
set rs = db.execute(sql)
if not rs.EOF then
while not rs.EOF
id = rs("id")
parent = rs("parent")
table = table & "['" & id & "'],['" & parent & "'],"
rs.movenext()
wend
end if
table = left(table,(len(table) - 1))
table = table & "];"
%>
<%= table %>
function category(id)
{
var e = document.getElementById(id);
if(e.src.match(/^(.*)on\.png$/) === null)
{
document.getElementById(id).setAttribute('src','on.png');
selectedCategories = selectedCategories + ',' + id;
selectChild(id);
selectParent(id);
}
else
{
document.getElementById(id).setAttribute('src','off.png');
selectedCategories = selectedCategories.replace(',' + id,'');
unselectChild(id);
unselectParent(id);
}
}
function getChild(id)
{
var children = '';
for(var x = 0; x < categories.length; x++)
{
if(categories[x][1] == id)
{
if(children == '')
{
children = children + categories[x][0];
}
else
{
children = children + ',' + categories[x][0];
}
}
}
return children;
}
function getParent(id)
{
var parent = '';
for(var x = 0; x < categories.length; x++)
{
if(categories[x][0] == id)
{
parent = categories[x][1];
}
}
return parent;
}
function selectChild(id)
{
if(getChild(id) != '')
{
var children = getChild(id).split(',');
for(var x = 0; x < children.length; x++)
{
document.getElementById(children[x]).setAttribute('src','on.png');
selectedCategories = selectedCategories + ',' + children[x];
selectChild(children[x]);
}
}
}
function selectParent(id)
{
if(getParent(id) != '')
{
var parent = getParent(id);
var children = getChild(parent).split(',');
var flag = true;
for(var x = 0; x < children.length; x++)
{
var e = document.getElementById(children[x]);
if(e.src.match(/^(.*)on\.png$/) === null)
{
flag = false;
}
}
if(flag)
{
document.getElementById(parent).setAttribute('src','on.png');
}
else
{
document.getElementById(parent).setAttribute('src','part.png');
}
selectedCategories = selectedCategories + ',' + parent;
selectParent(parent);
}
}
function unselectChild(id)
{
if(getChild(id) != '')
{
var children = getChild(id).split(',');
for(var x = 0; x < children.length; x++)
{
document.getElementById(children[x]).setAttribute('src','off.png');
selectedCategories = selectedCategories.replace(',' + children[x],'');
unselectChild(children[x]);
}
}
}
function unselectParent(id)
{
if(getParent(id) != '')
{
var parent = getParent(id);
var children = getChild(parent).split(',');
var flag = false;
for(var x = 0; x < children.length; x++)
{
var e = document.getElementById(children[x]);
if(e.src.match(/^(.*)off\.png$/) === null)
{
flag = true;
}
}
if(!flag)
{
document.getElementById(parent).setAttribute('src','off.png');
}
else
{
document.getElementById(parent).setAttribute('src','part.png');
}
selectedCategories = selectedCategories.replace(',' + parent,'');
unselectParent(parent);
}
}
</script>
</head>
<body>
<table width="500">
<%
indent = 0
function categories(parent)
set db = server.createobject("adodb.connection")
connection = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db.open (connection)
set rs = server.createobject("adodb.recordset")
sql = "SELECT * FROM categories WHERE parent = '" & parent & "' ORDER BY name"
set rs = db.execute(sql)
if not rs.EOF then
while not rs.EOF
id = rs("id")
name = rs("name")
width = 460 - (indent * 20)
hasChild = false
set db2 = server.createobject("adodb.connection")
connection2 = "driver={MySql ODBC 3.51 Driver};server=mysql11.streamline.net;uid=*********;pwd=*******;database=vouzamoco"
db2.open (connection2)
set rs2 = server.createobject("adodb.recordset")
sql2 = "SELECT * FROM categories WHERE parent = '" & id & "' LIMIT 1"
set rs2 = db2.execute(sql2)
if not rs2.EOF then
while not rs2.EOF
hasChild = true
rs2.movenext()
wend
end if
rs2.close
set rs2 = nothing
db2.close
set db2 = nothing
%>
<tr>
<%
x = 1
if(indent > 0) then
for x = 1 to indent step 1
%>
<td width="20"></td>
<%
next
end if
if(hasChild) then
if(parent = "") then
%>
<td width="20"><img id="<%= id %>_toggle" src="minus.gif" onClick="toggle('<%= id %>');"></td>
<%
else
%>
<td width="20"><img id="<%= id %>_toggle" src="plus.gif" onClick="toggle('<%= id %>');"></td>
<%
end if
else
%>
<td width="20"><img src="bullet.gif"></td>
<%
end if
%>
<td width="<%= width %>"><%= name %></td>
<td width="20"><img id="<%= id %>" src="off.png" onClick="category('<%= id %>');"></td>
</tr>
<%
if(hasChild) then
if(parent = "") then
%>
<tr id="<%= id %>_container" class="show">
<%
else
%>
<tr id="<%= id %>_container" class="hide">
<%
end if
%>
<td width="500">
<table width="500" cellpadding="0" cellspacing="0">
<%
indent = indent + 1
categories(id)
indent = indent - 1
%>
</table>
</td>
</tr>
<%
end if
rs.movenext()
wend
end if
rs.close
set rs = nothing
db.close
set db = nothing
end function
categories("")
%>
</table>
</body>
</html>
Note: the javascript is for a secondary function which allows the parents to inherit selection from the children client-side. It does not affect the ASP code.
Images used in this code can be found in the .zip file attached.