PDA

View Full Version : Count List items and then add groups together



gwmbox
07-12-2010, 07:52 AM
I am new to javascript and I have been playing with a script I am trying to get work by reading through and following examples on w3c Schools, which is working well as I can get basics to work. However I feel my noob coding needs to be reduced (tidied up) and I am stuck with a list calculation that will only work if all variables are present.

So I am here for your help.

Here is an example basic list, there are 20 items in this example and this will be the max in any one list, however there can be less than 20 list items.


<ul id="mylist">
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
<li>Text19</li>
<li>Text20</li>
</ul>

I have some code that sets a unique ID to each list item as provided by another DD forum user;


<script type="text/javascript">
/*<![CDATA[*/
function postlist(id,cls){
var ul=document.getElementById(id);
var lis=ul.getElementsByTagName('LI');
for (var z0=0;z0<lis.length;z0++){
lis[z0].id=cls+(z0+1);
}
}
postlist('mylist','item_');
/*]]>*/
</script>

so now each list item has an item_# id assigned to them, # being the incremental number of list items starting from 1

Then I wanted to calculate the first three sets of five list items overall height (which will be variable as the actual text in each list item will differ) as this is used to enable me to place each set in its own column of 5 list items.

So my noob code :P


<script type="text/javascript">
var postHt1 = document.getElementById("item_1").clientHeight;
var postHt2 = document.getElementById("item_2").clientHeight;
var postHt3 = document.getElementById("item_3").clientHeight;
var postHt4 = document.getElementById("item_4").clientHeight;
var postHt5 = document.getElementById("item_5").clientHeight;
var postHt6 = document.getElementById("item_6").clientHeight;
var postHt7 = document.getElementById("item_7").clientHeight;
var postHt8 = document.getElementById("item_8").clientHeight;
var postHt9 = document.getElementById("item_9").clientHeight;
var postHt10 = document.getElementById("item_10").clientHeight;
var postHt11 = document.getElementById("item_11").clientHeight;
var postHt12 = document.getElementById("item_12").clientHeight;
var postHt13 = document.getElementById("item_13").clientHeight;
var postHt14 = document.getElementById("item_14").clientHeight;
var postHt15 = document.getElementById("item_15").clientHeight;
postttl1 = postHt1 + postHt2 + postHt3 + postHt4 + postHt5 - 1;
postttl2 = postHt6 + postHt7 + postHt8 + postHt9 + postHt10;
postttl3 = postHt11 + postHt12 + postHt13 + postHt14 + postHt15 - 1;
document.write("<style>#item_6{margin-top:-");
document.write(postttl1);
document.write("px !important;}</style>");
document.write("<style>#item_11{margin-top:-");
document.write(postttl2);
document.write("px !important;}</style>");
document.write("<style>#item_16{margin-top:-");
document.write(postttl3);
document.write("px !important;}</style>");
</script>

The result is an over-ride style item I need for the layout I am working with, which works for the 20 list items, however if the list is less than 20 items, like only 12 items or even 6 items etc then it does not work. I assume that it is because there is less than 20 list items and the above code is trying to run as if there was 20 items and hence has with nothing to run on, as in there is no item_13 etc if say I only have 6 items.

I hope I make sense and someone can guide and teach me.

Cheers

GW

vwphillips
07-12-2010, 10:16 AM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
</head>

<body>
<ul id="mylist">
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
<li>Text19</li>
<li>Text20</li>
</ul>
<script type="text/javascript">
/*<![CDATA[*/


var lis=document.getElementById('mylist').getElementsByTagName('LI');

for (var h=0,z0=0;z0<lis.length;z0++){
if (z0>0&&z0%5==0){
lis[z0].style.marginTop=-h+'px';
h=0;
}
h+=lis[z0].offsetHeight;
}

/*]]>*/
</script></body>

</html>

gwmbox
07-12-2010, 10:52 AM
Wow, shows I need to learn a whole lot more, very much appreciated.

Thanks

GW

gwmbox
07-12-2010, 11:11 AM
I did some testing and it seems to be taking the height of the whole page to the first list item rather than just from the UL element itself?

Is there a way I can get it to only apply the height calculation from the UL that the list is within?

Also how do I get it to keep the unique id or class for each list item as per the first bit of code above?

Thanks

GW

vwphillips
07-12-2010, 12:42 PM
it is onle using the height of the LIs within UL 'mylist'



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
</head>

<body>
<ul id="mylist">
<li>Text1</li>
<li>Text2<br />Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
<li>Text19</li>
<li>Text20</li>
</ul>
<script type="text/javascript">
/*<![CDATA[*/


var lis=document.getElementById('mylist').getElementsByTagName('LI');

for (var h=0,z0=0;z0<lis.length;z0++){
if (z0>0&&(z0)%5==0){
lis[z0].style.marginTop=-h+'px';
h=0;
}
alert(lis[z0].offsetHeight)
h+=lis[z0].offsetHeight;
}

/*]]>*/
</script></body>

</html>

gwmbox
07-12-2010, 02:37 PM
oops, correct my bad it was a style conflict.

Can I ask one more thing, if there is content below the list it appears to be aligning itself below the last list item, which might just happen to be in a a second or third column. Is there something I can add that will set it below the full UL set? Attached is an image example

http://gmwebfiles.com/files/g/example1.png

Thanks

GW

gwmbox
07-13-2010, 01:45 AM
Can you tell me how I can get the script to work out which set of 5 has the highest height and then use that height as a height style in the UL tag, this will fix the above :)

Cheers

vwphillips
07-14-2010, 08:06 AM
a <br> after the UL seems to work

I cannt look further until tonight at best

gwmbox
07-14-2010, 10:39 AM
Does not work for me?

I was looking at the Math.max option as in Math.max(h) but I am not sure what variable to use or how to get the correct value and then to insert that value as a height style for the UL tag.

I can get all the values of h but not each one on its own - I know I am close but not quite there.

Cheers for your continue help

GW

vwphillips
07-14-2010, 12:02 PM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
</head>

<body>
<ul id="mylist">
<li>Text1</li>
<li>Text2<br />Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
<li>Text19</li>
<li>Text20</li>
</ul>
TEST
<script type="text/javascript">
/*<![CDATA[*/

var ul=document.getElementById('mylist');
var lis=ul.getElementsByTagName('LI');

for (var ary=[],h=0,z0=0;z0<lis.length;z0++){
if (z0>0&&(z0)%5==0){
lis[z0].style.marginTop=-h+'px';
ary.push(h);
h=0;
}
h+=lis[z0].offsetHeight;
}
ary.push(h);
ary=ary.sort(function(a,b){ return b-a; });
alert(ary);
ul.style.height=ary[0]+'px';
/*]]>*/
</script></body>

</html>

gwmbox
07-14-2010, 01:16 PM
Perfect, thank you :)

gwmbox
07-15-2010, 11:27 AM
Ok this is working for me in FF3.x and Chrome but it does not want to work in IE8 correctly, I have not tested in IE7 or IE6 yet.

Here is the styles I am using for testing (plus those created by the js)


<style>
ul {list-style:none;}
ul li {line-height:16px;width:180px;padding:5px;border-bottom:1px solid #ccc;}
#item_1, #item_2, #item_3, #item_4, #item_5 {margin:0;}
#item_6, #item_7, #item_8, #item_9, #item_10 {margin-left:250px;}
#item_11, #item_12, #item_13, #item_14, #item_15 {margin-left:500px;}
#item_16, #item_17, #item_18, #item_19, #item_20 {margin-left:750px;}
</style>


The odd thing is that when I load it in IE that shows it not working, if I go into IE's web developer and select the div, ul or one of the li items and untick any style set, IE then springs into life and shows the desired result as working, but that only happens when I go and untick an item in the web developer screen... this makes it even more odd?

Any ideas?

Oh I made a small modification and put the height max in a div and not the ul, but that is not causing the issue.

So the whole page looks like


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
<style>
ul {list-style:none;}
ul li {line-height:16px;width:180px;padding:5px;border-bottom:1px solid #ccc;}
#item_1, #item_2, #item_3, #item_4, #item_5 {margin:0;}
#item_6, #item_7, #item_8, #item_9, #item_10 {margin-left:250px;}
#item_11, #item_12, #item_13, #item_14, #item_15 {margin-left:500px;}
#item_16, #item_17, #item_18, #item_19, #item_20 {margin-left:750px;}
</style>
</head>

<body>
Some text before the list
<div id="mydiv">
<ul id="mylist">
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
</ul>
</div>
Some text after the list
</body>
<script type="text/javascript">
/*<![CDATA[*/
function postlist(id,cls){
var ul=document.getElementById(id);
var lis=ul.getElementsByTagName('LI');
for (var z0=0;z0<lis.length;z0++){
lis[z0].id=cls+(z0+1);
}
}
postlist('mylist','item_');
/*]]>*/
</script>
<script type="text/javascript">
/*<![CDATA[*/
var div=document.getElementById('mydiv');
var ul=document.getElementById('mylist');
var lis=ul.getElementsByTagName('LI');

for (var ary=[],h=0,z0=0;z0<lis.length;z0++){
if (z0>0&&(z0)%5==0){
lis[z0].style.marginTop=-h+'px';
ary.push(h);
h=0;
}
h+=lis[z0].offsetHeight;
}
ary.push(h);
ary=ary.sort(function(a,b){ return b-a; });
div.style.height=ary[0]+'px';
/*]]>*/
</script>
</html>

Cheers

vwphillips
07-15-2010, 12:48 PM
i do not use IE 8

but try


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
</head>

<body>
<ul id="mylist">
<li>Text1</li>
<li>Text2<br />Text2</li>
<li>Text3</li>
<li>Text4</li>
<li>Text5</li>
<li>Text6</li>
<li>Text7</li>
<li>Text8</li>
<li>Text9</li>
<li>Text10</li>
<li>Text11</li>
<li>Text12</li>
<li>Text13</li>
<li>Text14</li>
<li>Text15</li>
<li>Text16</li>
<li>Text17</li>
<li>Text18</li>
<li>Text19</li>
<li>Text20</li>
</ul>
TEST
<script type="text/javascript">
/*<![CDATA[*/

var ul=document.getElementById('mylist');
var lis=ul.getElementsByTagName('LI');

for (var ary=[],h=0,lft=0,z0=0;z0<lis.length;z0++){
if (z0>0&&(z0)%5==0){
lis[z0].style.marginTop=-h+'px';
ary.push(h);
lft+=250;
h=0;
}
lis[z0].style.marginLeft=lft+'px';
h+=lis[z0].offsetHeight;
}
ary.push(h);
ary=ary.sort(function(a,b){ return b-a; });
alert(ary);
ul.style.height=ary[0]+'px';
/*]]>*/
</script></body>

</html>

gwmbox
07-15-2010, 01:57 PM
I don't use IE either but many do so I needed to make sure it works in that.

Your edit made a difference, I made a final edit and added in the width so the js is (in case anyone else wants this too). Tested in IE8, FF3.x and Chrome 5. I'll further test in other browsers and versions when I get a chance but the main ones are working which is great.


<script type="text/javascript">
/*<![CDATA[*/

var ul=document.getElementById('mylist');
var lis=ul.getElementsByTagName('LI');

for (var ary=[],h=0,lft=0,wdth=180,z0=0;z0<lis.length;z0++){
if (z0>0&&(z0)%5==0){
lis[z0].style.marginTop=-h+'px';
ary.push(h);
lft+=250;
h=0;
}
lis[z0].style.marginLeft=lft+'px';
lis[z0].style.width=wdth+'px';
h+=lis[z0].offsetHeight;
}
ary.push(h);
ary=ary.sort(function(a,b){ return b-a; });
alert(ary);
ul.style.height=ary[0]+'px';
/*]]>*/
</script>

And now it works a treat. Thanks again for all your help.