Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Javascript (http://www.velocityreviews.com/forums/f68-javascript.html)
-   -   Collapsable list where text is in columns with headers (like a forum for example) (http://www.velocityreviews.com/forums/t932965-collapsable-list-where-text-is-in-columns-with-headers-like-a-forum-for-example.html)

Mark 09-25-2007 10:48 AM

Collapsable list where text is in columns with headers (like a forum for example)
 
Hi

I'm looking to create a colapsable list like what we see in a news reader or
on a forum.

- Basically, any number of levels up to 10 (i.e. more than whats likely to
be needed)

- Able to expand/collapse each branch independantly

- 3 columns, where columns 2 and 3 are fixed width and aligned at all levels
with column headers (this is where it could get ugly as there may not be
room for column 1 if the record is more than a few levels deep.

I looked at bodging a tree control (namely
http://www.dynamicdrive.com/dynamicindex1/navigate1.htm) by dropping a 3x1
table within each li tag but a) the columns don't line up and b) I'm pretty
sure that was a really stupid idea ;o)

Anyone got an example or pointer to something similar?

Thanks

Mark



pr 09-25-2007 02:30 PM

Re: Collapsable list where text is in columns with headers (likea forum for example)
 
Mark wrote:
> I'm looking to create a colapsable list like what we see in a news reader or
> on a forum.
>
> - Basically, any number of levels up to 10 (i.e. more than whats likely to
> be needed)
>
> - Able to expand/collapse each branch independantly
>
> - 3 columns, where columns 2 and 3 are fixed width and aligned at all levels
> with column headers (this is where it could get ugly as there may not be
> room for column 1 if the record is more than a few levels deep.


Fun programming challenge :-)

The only way I could think of to line up cols 2 and 3 was to use a SPAN
for each and a CSS style per nesting level to counteract the indent of
each DIV. In a 'real' version you could stop columns overflowing by
setting a max width in CSS for the appropriate SPAN class(es) and using
overflow: hidden.

Anyway have a play:

<html>
<head>
<title>tree</title>
<style type="text/css">
.visible { display: block; }
.hidden { display : none; }
.closed { color: blue; }

div { position: relative; left: 1em; }
div:hover { cursor: pointer; }

.l1c1 { position: relative; left: 0; }
.l1c2 { position: relative; left: 15em; }
.l1c3 { position: relative; left: 25em; }

.l2c1 { position: relative; left: 0; }
.l2c2 { position: relative; left: 14em; }
.l2c3 { position: relative; left: 24em; }

.l3c1 { position: relative; left: 0; }
.l3c2 { position: relative; left: 13em; }
.l3c3 { position: relative; left: 23em; }
</style>

<script type="text/javascript">
function clicked(ev) {
var n, obj, c, visible = -1;

var isDOM2 = ev && (n = ev.target);
var isIE = window.event && (ev = window.event) &&
(n = ev.srcElement);

if (!n)
return true;

while (n && n.nodeName != "DIV") {
n = n.parentNode;
if (n.nodeType == 9)
return true;
}

if ((obj = n)) {
c = obj.firstChild;
while (c) {
if (c.nodeName == "DIV") {
if (visible < 0)
visible = (c.className != 'hidden');
c.className = (visible ? 'hidden' : 'visible');
}
c = c.nextSibling;
}
obj.className = (visible ? 'closed' : '');
if (isDOM2)
ev.stopPropagation();
else
ev.cancelBubble = true;
return false;
}
return true;
}

if (document.addEventListener)
document.addEventListener("click", clicked, false);
else if (document.onclick != "undefined")
document.onclick = clicked;
</script>
</head>
<body>
<div>
<span id="col1" class="l1c1">column 1</span>
<span id="col2" class="l1c2">column 2</span>
<span id="col3" class="l1c3">column 3</span>

<div>
<span id="col1" class="l2c1">column 1</span>
<span id="col2" class="l2c2">column 2</span>
<span id="col3" class="l2c3">column 3</span>
</div>

<div>
<span id="col1" class="l2c1">column 1</span>
<span id="col2" class="l2c2">column 2</span>
<span id="col3" class="l2c3">column 3</span>

<div>
<span id="col1" class="l3c1">column 1</span>
<span id="col2" class="l3c2">column 2</span>
<span id="col3" class="l3c3">column 3</span>
</div>

<div>
<span id="col1" class="l3c1">column 1</span>
<span id="col2" class="l3c2">column 2</span>
<span id="col3" class="l3c3">column 3</span>
</div>
</div>
</div>
</body>
</html>

Mark 09-25-2007 03:06 PM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
Wow, thanks pr, I'll have a play indeed and let you know ho wit goes.

Thanks again


Mark

"pr" <pr@porl.globalnet.co.uk> wrote in message
news:cY8Ki.301$ao.208@newsfe7-win.ntli.net...
> Mark wrote:
>> I'm looking to create a colapsable list like what we see in a news reader
>> or on a forum.
>>
>> - Basically, any number of levels up to 10 (i.e. more than whats likely
>> to be needed)
>>
>> - Able to expand/collapse each branch independantly
>>
>> - 3 columns, where columns 2 and 3 are fixed width and aligned at all
>> levels with column headers (this is where it could get ugly as there may
>> not be room for column 1 if the record is more than a few levels deep.

>
> Fun programming challenge :-)
>
> The only way I could think of to line up cols 2 and 3 was to use a SPAN
> for each and a CSS style per nesting level to counteract the indent of
> each DIV. In a 'real' version you could stop columns overflowing by
> setting a max width in CSS for the appropriate SPAN class(es) and using
> overflow: hidden.
>
> Anyway have a play:
>
> <html>
> <head>
> <title>tree</title>
> <style type="text/css">
> .visible { display: block; }
> .hidden { display : none; }
> .closed { color: blue; }
>
> div { position: relative; left: 1em; }
> div:hover { cursor: pointer; }
>
> .l1c1 { position: relative; left: 0; }
> .l1c2 { position: relative; left: 15em; }
> .l1c3 { position: relative; left: 25em; }
>
> .l2c1 { position: relative; left: 0; }
> .l2c2 { position: relative; left: 14em; }
> .l2c3 { position: relative; left: 24em; }
>
> .l3c1 { position: relative; left: 0; }
> .l3c2 { position: relative; left: 13em; }
> .l3c3 { position: relative; left: 23em; }
> </style>
>
> <script type="text/javascript">
> function clicked(ev) {
> var n, obj, c, visible = -1;
>
> var isDOM2 = ev && (n = ev.target);
> var isIE = window.event && (ev = window.event) &&
> (n = ev.srcElement);
>
> if (!n)
> return true;
>
> while (n && n.nodeName != "DIV") {
> n = n.parentNode;
> if (n.nodeType == 9)
> return true;
> }
>
> if ((obj = n)) {
> c = obj.firstChild;
> while (c) {
> if (c.nodeName == "DIV") {
> if (visible < 0)
> visible = (c.className != 'hidden');
> c.className = (visible ? 'hidden' : 'visible');
> }
> c = c.nextSibling;
> }
> obj.className = (visible ? 'closed' : '');
> if (isDOM2)
> ev.stopPropagation();
> else
> ev.cancelBubble = true;
> return false;
> }
> return true;
> }
>
> if (document.addEventListener)
> document.addEventListener("click", clicked, false);
> else if (document.onclick != "undefined")
> document.onclick = clicked;
> </script>
> </head>
> <body>
> <div>
> <span id="col1" class="l1c1">column 1</span>
> <span id="col2" class="l1c2">column 2</span>
> <span id="col3" class="l1c3">column 3</span>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
> </div>
> </div>
> </body>
> </html>




David Mark 09-26-2007 08:26 PM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
On Sep 25, 10:30 am, pr <p...@porl.globalnet.co.uk> wrote:
> Mark wrote:
> > I'm looking to create a colapsable list like what we see in a news reader or
> > on a forum.

>
> > - Basically, any number of levels up to 10 (i.e. more than whats likely to
> > be needed)

>
> > - Able to expand/collapse each branch independantly

>
> > - 3 columns, where columns 2 and 3 are fixed width and aligned at all levels
> > with column headers (this is where it could get ugly as there may not be
> > room for column 1 if the record is more than a few levels deep.

>
> Fun programming challenge :-)
>
> The only way I could think of to line up cols 2 and 3 was to use a SPAN
> for each and a CSS style per nesting level to counteract the indent of
> each DIV. In a 'real' version you could stop columns overflowing by
> setting a max width in CSS for the appropriate SPAN class(es) and using
> overflow: hidden.


Or you can use a table for what is clearly tabular data.

>
> Anyway have a play:
>
> <html>
> <head>
> <title>tree</title>
> <style type="text/css">
> .visible { display: block; }
> .hidden { display : none; }
> .closed { color: blue; }
>
> div { position: relative; left: 1em; }
> div:hover { cursor: pointer; }
>
> .l1c1 { position: relative; left: 0; }
> .l1c2 { position: relative; left: 15em; }
> .l1c3 { position: relative; left: 25em; }
>
> .l2c1 { position: relative; left: 0; }
> .l2c2 { position: relative; left: 14em; }
> .l2c3 { position: relative; left: 24em; }
>
> .l3c1 { position: relative; left: 0; }
> .l3c2 { position: relative; left: 13em; }
> .l3c3 { position: relative; left: 23em; }
> </style>
>
> <script type="text/javascript">
> function clicked(ev) {
> var n, obj, c, visible = -1;
>
> var isDOM2 = ev && (n = ev.target);
> var isIE = window.event && (ev = window.event) &&
> (n = ev.srcElement);


Don't use object inferences.

>
> if (!n)
> return true;
>
> while (n && n.nodeName != "DIV") {
> n = n.parentNode;
> if (n.nodeType == 9)
> return true;
> }
>
> if ((obj = n)) {
> c = obj.firstChild;
> while (c) {
> if (c.nodeName == "DIV") {
> if (visible < 0)
> visible = (c.className != 'hidden');
> c.className = (visible ? 'hidden' : 'visible');
> }
> c = c.nextSibling;
> }


I tested this and it didn't work as you might have hoped.

> obj.className = (visible ? 'closed' : '');
> if (isDOM2)
> ev.stopPropagation();
> else
> ev.cancelBubble = true;


Detect the stopPropagation method. Don't rely on the above-mentioned
inferences.

> return false;
> }
> return true;
> }
>
> if (document.addEventListener)
> document.addEventListener("click", clicked, false);
> else if (document.onclick != "undefined")


Missing typeof.

> document.onclick = clicked;
> </script>
> </head>
> <body>
> <div>
> <span id="col1" class="l1c1">column 1</span>
> <span id="col2" class="l1c2">column 2</span>
> <span id="col3" class="l1c3">column 3</span>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
> </div>
> </div>
> </body>
> </html>


This also has accessibility issues. Showing all nodes expanded from
the start helps with that but hinders usability.

Here's a basic example. In production code you probably wouldn't
define the hierarchy based on element ID's and you would use
background images for the +/- indicators (IE does not support content
added with CSS.) It was tested briefly with the usual suspects.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Collapsible Posts</title>
<style type="text/css" media="all">
table.posts { border:none;width:100%;border-collapse:collapse }
table.posts td { width:33%;white-space:nowrap }
table.posts th { text-align:left }
table.posts th, table.posts tr:hover, table.posts tr:hover a
{ background-color:#DDDDDD;color:black }
table.posts tr.shownParent:hover, table.posts tr.shownParent:hover a
{ background-color:#0000DD;color:white }
td.indent1 { padding-left:1em }
td.indent2 { padding-left:2em }
td.indent3 { padding-left:3em }
a.open:before { content: "- " }
a.closed:before { content: "+ " }
tr.shown, tr.shownParent { display:block;display:table-row }
tr.hidden { display:none }
</style>
<style type="text/css" media="handheld">
td.indent1 { padding-left:.5em }
td.indent2 { padding-left:1em }
td.indent3 { padding-left:2em }
</style>
<script type="text/javascript">
var global = this;
if (this.document && this.document.getElementsByTagName &&
this.document.getElementById) {
(function() {
var html = global.document.getElementsByTagName('html');
if (html && html[0] && html[0].style &&
typeof(html[0].style.visibility) == 'string') { document.write('<style
type="text/css" media="all">#mydiscussion { visibility:hidden }<\/
style>'); }
})();

this.onload = function() {
var doc = global.document;
var el, anchors, postId, posts, i, l;

function findPosts(postId) {
var j = 1;
var childPosts = [];
var elChild = doc.getElementById(postId + 'p' + j);
while (elChild) {
childPosts.push(elChild);
elChild = doc.getElementById(postId + 'p' + (++j));
}
return childPosts;
}

function showPosts(posts, b, cascade) {
var j = 0;
var m = posts.length;
var title, childPosts;
while (j < m) {
posts[j].className = (b)?'shown':'hidden';
childPosts = findPosts(posts[j].id);
if (childPosts.length) {
if (b) { posts[j].className = 'shownParent'; }
title = document.getElementById(posts[j].id + 'Title');
if (title) {
if (title.className == 'open' || cascade) {
showPosts(childPosts, b, cascade);
}
if (cascade) { title.className = (b)?'open':'closed'; }
}
}
j++;
}
}

el = document.getElementById('mydiscussion');
if (el && el.style && typeof(el.style.display) == 'string') {
anchors = el.getElementsByTagName('a');
i = 0;
l = anchors.length;
while (i < l) {
if (anchors[i].id && typeof(anchors[i].href) != 'unknown' && !
anchors[i].href) {
postId = anchors[i].id.substring(0, anchors[i].id.length - 5);
posts = findPosts(postId);
if (posts.length) {
var elPost = document.getElementById(postId);
if (elPost) {
if (anchors[i].className != 'closed') {
showPosts(posts, false, true);
anchors[i].className = 'closed';
}
anchors[i].href = '#';
anchors[i].tabIndex = 0;
if (!elPost.className) { elPost.className = 'shownParent'; }
elPost.style.cursor = 'pointer';
elPost.onclick = anchors[i].onclick = (function(posts, el)
{ var b; return function(e) { e = e || global.event; b = (el.className
== 'closed'); el.className = (b)?'open':'closed'; showPosts(posts, b);
if (e.stopPropagation) { e.stopPropagation(); } e.cancelBubble = true;
return false; }; })(posts, anchors[i]);
}
}
}
i++;
}
el.style.visibility = 'visible';
}
};
}
</script>
</head>
<body>
<table id="mydiscussion" class="posts">
<tbody>
<tr><th>Heading 1</th><th>Heading 2</th><th>Heading 3</th></tr>
<tr id="p1"><td><a id="p1Title">Column 1</a></td><td>Column 2</
td><td>Column 3</td></tr>
<tr id="p1p1"><td class="indent1"><a id="p1p1Title">Column 1</a></
td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2"><td class="indent1"><a id="p1p2Title">Column 1</a></
td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2p1"><td class="indent2"><a id="p1p2p1Title">Column 1</a></
td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2p2"><td class="indent2"><a id="p1p2p2Title">Column 1</a></
td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2p2p1"><td class="indent3"><a id="p1p2p2p1Title">Column 1</
a></td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2p3"><td class="indent2"><a id="p1p2p3Title">Column 1</a></
td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p1p2p3p1"><td class="indent3"><a id="p1p2p1p1Title">Column 1</
a></td><td>Column 2</td><td>Column 3</td></tr>
<tr id="p2"><td><a id="p2Title">Column 1</a></td><td>Column 2</
td><td>Column 3</td></tr>
</tbody>
</table>
</body>
</html>


David Mark 09-27-2007 01:54 AM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
On Sep 26, 4:26 pm, David Mark <dmark.cins...@gmail.com> wrote:

Oops. Left out the memory leak cleanup.

global.onunload = function() {
i = 0;
l = anchors.length;
while (i < l) { anchors[i++].onclick = null; }
};

Goes right before this line:

el.style.visibility = 'visible';



Mark 09-27-2007 06:33 AM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
Thanks Mark

I'll take a look today. I had given up on the idea of column alignment for
columns 2 and 3 as there were issues with overflow text etc.

Thanks for the memory cleanup bit as well. I've been programming for years
but rarely for the web so I would have missed that one till it bit me on the
backside.

Thanks again

Mark

"David Mark" <dmark.cinsoft@gmail.com> wrote in message
news:1190858083.811309.191870@d55g2000hsg.googlegr oups.com...
> On Sep 26, 4:26 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> Oops. Left out the memory leak cleanup.
>
> global.onunload = function() {
> i = 0;
> l = anchors.length;
> while (i < l) { anchors[i++].onclick = null; }
> };
>
> Goes right before this line:
>
> el.style.visibility = 'visible';
>
>




Mark 09-27-2007 06:35 AM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
Hi

For the record, if anyones trying to do something similar, I made the
position properties of the styles for columns 2 and 3 absolute in order to
keep them aligned when column 1 had different length strings.

Mark


"pr" <pr@porl.globalnet.co.uk> wrote in message
news:cY8Ki.301$ao.208@newsfe7-win.ntli.net...
> Mark wrote:
>> I'm looking to create a colapsable list like what we see in a news reader
>> or on a forum.
>>
>> - Basically, any number of levels up to 10 (i.e. more than whats likely
>> to be needed)
>>
>> - Able to expand/collapse each branch independantly
>>
>> - 3 columns, where columns 2 and 3 are fixed width and aligned at all
>> levels with column headers (this is where it could get ugly as there may
>> not be room for column 1 if the record is more than a few levels deep.

>
> Fun programming challenge :-)
>
> The only way I could think of to line up cols 2 and 3 was to use a SPAN
> for each and a CSS style per nesting level to counteract the indent of
> each DIV. In a 'real' version you could stop columns overflowing by
> setting a max width in CSS for the appropriate SPAN class(es) and using
> overflow: hidden.
>
> Anyway have a play:
>
> <html>
> <head>
> <title>tree</title>
> <style type="text/css">
> .visible { display: block; }
> .hidden { display : none; }
> .closed { color: blue; }
>
> div { position: relative; left: 1em; }
> div:hover { cursor: pointer; }
>
> .l1c1 { position: relative; left: 0; }
> .l1c2 { position: relative; left: 15em; }
> .l1c3 { position: relative; left: 25em; }
>
> .l2c1 { position: relative; left: 0; }
> .l2c2 { position: relative; left: 14em; }
> .l2c3 { position: relative; left: 24em; }
>
> .l3c1 { position: relative; left: 0; }
> .l3c2 { position: relative; left: 13em; }
> .l3c3 { position: relative; left: 23em; }
> </style>
>
> <script type="text/javascript">
> function clicked(ev) {
> var n, obj, c, visible = -1;
>
> var isDOM2 = ev && (n = ev.target);
> var isIE = window.event && (ev = window.event) &&
> (n = ev.srcElement);
>
> if (!n)
> return true;
>
> while (n && n.nodeName != "DIV") {
> n = n.parentNode;
> if (n.nodeType == 9)
> return true;
> }
>
> if ((obj = n)) {
> c = obj.firstChild;
> while (c) {
> if (c.nodeName == "DIV") {
> if (visible < 0)
> visible = (c.className != 'hidden');
> c.className = (visible ? 'hidden' : 'visible');
> }
> c = c.nextSibling;
> }
> obj.className = (visible ? 'closed' : '');
> if (isDOM2)
> ev.stopPropagation();
> else
> ev.cancelBubble = true;
> return false;
> }
> return true;
> }
>
> if (document.addEventListener)
> document.addEventListener("click", clicked, false);
> else if (document.onclick != "undefined")
> document.onclick = clicked;
> </script>
> </head>
> <body>
> <div>
> <span id="col1" class="l1c1">column 1</span>
> <span id="col2" class="l1c2">column 2</span>
> <span id="col3" class="l1c3">column 3</span>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l2c1">column 1</span>
> <span id="col2" class="l2c2">column 2</span>
> <span id="col3" class="l2c3">column 3</span>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
>
> <div>
> <span id="col1" class="l3c1">column 1</span>
> <span id="col2" class="l3c2">column 2</span>
> <span id="col3" class="l3c3">column 3</span>
> </div>
> </div>
> </div>
> </body>
> </html>




Mark 09-27-2007 07:10 AM

Re: Collapsable list where text is in columns with headers (like a forum for example)
 
Hello again

This works great (thanks), the only issue I got though is that in firefox
long strings don't wrap, i.e. the cell height remains constant and the table
gets wider. I even tried fixing the widths of the table and cells (in
pixels), still doesn't wrap) and then dropped the whole table inside another
fixed width table and it still gets wider rather than wrapping.

Work fine in IE6 though, will keep plugging at the firefox issue.

Cheers

Mark


"David Mark" <dmark.cinsoft@gmail.com> wrote in message
news:1190838386.409008.324650@57g2000hsv.googlegro ups.com...
> On Sep 25, 10:30 am, pr <p...@porl.globalnet.co.uk> wrote:
>> Mark wrote:
>> > I'm looking to create a colapsable list like what we see in a news
>> > reader or
>> > on a forum.

>>
>> > - Basically, any number of levels up to 10 (i.e. more than whats likely
>> > to
>> > be needed)

>>
>> > - Able to expand/collapse each branch independantly

>>
>> > - 3 columns, where columns 2 and 3 are fixed width and aligned at all
>> > levels
>> > with column headers (this is where it could get ugly as there may not
>> > be
>> > room for column 1 if the record is more than a few levels deep.

>>
>> Fun programming challenge :-)
>>
>> The only way I could think of to line up cols 2 and 3 was to use a SPAN
>> for each and a CSS style per nesting level to counteract the indent of
>> each DIV. In a 'real' version you could stop columns overflowing by
>> setting a max width in CSS for the appropriate SPAN class(es) and using
>> overflow: hidden.

>
> Or you can use a table for what is clearly tabular data.
>
>>
>> Anyway have a play:
>>
>> <html>
>> <head>
>> <title>tree</title>
>> <style type="text/css">
>> .visible { display: block; }
>> .hidden { display : none; }
>> .closed { color: blue; }
>>
>> div { position: relative; left: 1em; }
>> div:hover { cursor: pointer; }
>>
>> .l1c1 { position: relative; left: 0; }
>> .l1c2 { position: relative; left: 15em; }
>> .l1c3 { position: relative; left: 25em; }
>>
>> .l2c1 { position: relative; left: 0; }
>> .l2c2 { position: relative; left: 14em; }
>> .l2c3 { position: relative; left: 24em; }
>>
>> .l3c1 { position: relative; left: 0; }
>> .l3c2 { position: relative; left: 13em; }
>> .l3c3 { position: relative; left: 23em; }
>> </style>
>>
>> <script type="text/javascript">
>> function clicked(ev) {
>> var n, obj, c, visible = -1;
>>
>> var isDOM2 = ev && (n = ev.target);
>> var isIE = window.event && (ev = window.event) &&
>> (n = ev.srcElement);

>
> Don't use object inferences.
>
>>
>> if (!n)
>> return true;
>>
>> while (n && n.nodeName != "DIV") {
>> n = n.parentNode;
>> if (n.nodeType == 9)
>> return true;
>> }
>>
>> if ((obj = n)) {
>> c = obj.firstChild;
>> while (c) {
>> if (c.nodeName == "DIV") {
>> if (visible < 0)
>> visible = (c.className != 'hidden');
>> c.className = (visible ? 'hidden' : 'visible');
>> }
>> c = c.nextSibling;
>> }

>
> I tested this and it didn't work as you might have hoped.
>
>> obj.className = (visible ? 'closed' : '');
>> if (isDOM2)
>> ev.stopPropagation();
>> else
>> ev.cancelBubble = true;

>
> Detect the stopPropagation method. Don't rely on the above-mentioned
> inferences.
>
>> return false;
>> }
>> return true;
>> }
>>
>> if (document.addEventListener)
>> document.addEventListener("click", clicked, false);
>> else if (document.onclick != "undefined")

>
> Missing typeof.
>
>> document.onclick = clicked;
>> </script>
>> </head>
>> <body>
>> <div>
>> <span id="col1" class="l1c1">column 1</span>
>> <span id="col2" class="l1c2">column 2</span>
>> <span id="col3" class="l1c3">column 3</span>
>>
>> <div>
>> <span id="col1" class="l2c1">column 1</span>
>> <span id="col2" class="l2c2">column 2</span>
>> <span id="col3" class="l2c3">column 3</span>
>> </div>
>>
>> <div>
>> <span id="col1" class="l2c1">column 1</span>
>> <span id="col2" class="l2c2">column 2</span>
>> <span id="col3" class="l2c3">column 3</span>
>>
>> <div>
>> <span id="col1" class="l3c1">column 1</span>
>> <span id="col2" class="l3c2">column 2</span>
>> <span id="col3" class="l3c3">column 3</span>
>> </div>
>>
>> <div>
>> <span id="col1" class="l3c1">column 1</span>
>> <span id="col2" class="l3c2">column 2</span>
>> <span id="col3" class="l3c3">column 3</span>
>> </div>
>> </div>
>> </div>
>> </body>
>> </html>

>
> This also has accessibility issues. Showing all nodes expanded from
> the start helps with that but hinders usability.
>
> Here's a basic example. In production code you probably wouldn't
> define the hierarchy based on element ID's and you would use
> background images for the +/- indicators (IE does not support content
> added with CSS.) It was tested briefly with the usual suspects.
>
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
> TR/html4/strict.dtd">
> <html>
> <head>
> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
> <title>Collapsible Posts</title>
> <style type="text/css" media="all">
> table.posts { border:none;width:100%;border-collapse:collapse }
> table.posts td { width:33%;white-space:nowrap }
> table.posts th { text-align:left }
> table.posts th, table.posts tr:hover, table.posts tr:hover a
> { background-color:#DDDDDD;color:black }
> table.posts tr.shownParent:hover, table.posts tr.shownParent:hover a
> { background-color:#0000DD;color:white }
> td.indent1 { padding-left:1em }
> td.indent2 { padding-left:2em }
> td.indent3 { padding-left:3em }
> a.open:before { content: "- " }
> a.closed:before { content: "+ " }
> tr.shown, tr.shownParent { display:block;display:table-row }
> tr.hidden { display:none }
> </style>
> <style type="text/css" media="handheld">
> td.indent1 { padding-left:.5em }
> td.indent2 { padding-left:1em }
> td.indent3 { padding-left:2em }
> </style>
> <script type="text/javascript">
> var global = this;
> if (this.document && this.document.getElementsByTagName &&
> this.document.getElementById) {
> (function() {
> var html = global.document.getElementsByTagName('html');
> if (html && html[0] && html[0].style &&
> typeof(html[0].style.visibility) == 'string') { document.write('<style
> type="text/css" media="all">#mydiscussion { visibility:hidden }<\/
> style>'); }
> })();
>
> this.onload = function() {
> var doc = global.document;
> var el, anchors, postId, posts, i, l;
>
> function findPosts(postId) {
> var j = 1;
> var childPosts = [];
> var elChild = doc.getElementById(postId + 'p' + j);
> while (elChild) {
> childPosts.push(elChild);
> elChild = doc.getElementById(postId + 'p' + (++j));
> }
> return childPosts;
> }
>
> function showPosts(posts, b, cascade) {
> var j = 0;
> var m = posts.length;
> var title, childPosts;
> while (j < m) {
> posts[j].className = (b)?'shown':'hidden';
> childPosts = findPosts(posts[j].id);
> if (childPosts.length) {
> if (b) { posts[j].className = 'shownParent'; }
> title = document.getElementById(posts[j].id + 'Title');
> if (title) {
> if (title.className == 'open' || cascade) {
> showPosts(childPosts, b, cascade);
> }
> if (cascade) { title.className = (b)?'open':'closed'; }
> }
> }
> j++;
> }
> }
>
> el = document.getElementById('mydiscussion');
> if (el && el.style && typeof(el.style.display) == 'string') {
> anchors = el.getElementsByTagName('a');
> i = 0;
> l = anchors.length;
> while (i < l) {
> if (anchors[i].id && typeof(anchors[i].href) != 'unknown' && !
> anchors[i].href) {
> postId = anchors[i].id.substring(0, anchors[i].id.length - 5);
> posts = findPosts(postId);
> if (posts.length) {
> var elPost = document.getElementById(postId);
> if (elPost) {
> if (anchors[i].className != 'closed') {
> showPosts(posts, false, true);
> anchors[i].className = 'closed';
> }
> anchors[i].href = '#';
> anchors[i].tabIndex = 0;
> if (!elPost.className) { elPost.className = 'shownParent'; }
> elPost.style.cursor = 'pointer';
> elPost.onclick = anchors[i].onclick = (function(posts, el)
> { var b; return function(e) { e = e || global.event; b = (el.className
> == 'closed'); el.className = (b)?'open':'closed'; showPosts(posts, b);
> if (e.stopPropagation) { e.stopPropagation(); } e.cancelBubble = true;
> return false; }; })(posts, anchors[i]);
> }
> }
> }
> i++;
> }
> el.style.visibility = 'visible';
> }
> };
> }
> </script>
> </head>
> <body>
> <table id="mydiscussion" class="posts">
> <tbody>
> <tr><th>Heading 1</th><th>Heading 2</th><th>Heading 3</th></tr>
> <tr id="p1"><td><a id="p1Title">Column 1</a></td><td>Column 2</
> td><td>Column 3</td></tr>
> <tr id="p1p1"><td class="indent1"><a id="p1p1Title">Column 1</a></
> td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2"><td class="indent1"><a id="p1p2Title">Column 1</a></
> td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2p1"><td class="indent2"><a id="p1p2p1Title">Column 1</a></
> td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2p2"><td class="indent2"><a id="p1p2p2Title">Column 1</a></
> td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2p2p1"><td class="indent3"><a id="p1p2p2p1Title">Column 1</
> a></td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2p3"><td class="indent2"><a id="p1p2p3Title">Column 1</a></
> td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p1p2p3p1"><td class="indent3"><a id="p1p2p1p1Title">Column 1</
> a></td><td>Column 2</td><td>Column 3</td></tr>
> <tr id="p2"><td><a id="p2Title">Column 1</a></td><td>Column 2</
> td><td>Column 3</td></tr>
> </tbody>
> </table>
> </body>
> </html>
>




pr 09-27-2007 11:31 AM

Re: Collapsable list where text is in columns with headers (likea forum for example)
 
David Mark wrote:
[a sample application]

Good one.

pr 09-27-2007 11:38 AM

Re: Collapsable list where text is in columns with headers (likea forum for example)
 
Mark wrote:
> This works great (thanks), the only issue I got though is that in firefox
> long strings don't wrap, i.e. the cell height remains constant and the table
> gets wider. I even tried fixing the widths of the table and cells (in
> pixels), still doesn't wrap) and then dropped the whole table inside another
> fixed width table and it still gets wider rather than wrapping.


Comment out or remove 'white-space:nowrap' from the 'table.posts td' CSS.


All times are GMT. The time now is 09:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.