Table cell/row spinner

T

Tuxedo

I'm attempting to stick together a procedure that determines the number of
cells in all rows of tables, based on a user defined variable of columns.
The variable needs to determine where the </tr>'s and <tr>'s are inserted.

Like for example:

var row_length = 3; // number of cells in all rows, i.e. columns

var gallery = new Array();{
gallery[0] = "entry 1";
gallery[1] = "entry 2";
gallery[2] = "entry 3";
gallery[3] = "entry 4";
gallery[4] = "entry 5";
gallery[5] = "entry 6";
gallery[6] = "entry 7";
gallery[7] = "entry 8";
gallery[8] = "entry 9";
gallery[9] = "entry 10";
gallery[10] = "entry 11";
}

var insert_tr = 1;

document.write('<table border=1><tr>');

for (i = 0; i < gallery.length; i++, insert_tr++){
document.write('<td>'+gallery + '</td>')

if (insert_tr == row_length) {
document.write('</tr><tr>')
insert_tr = 0;
}

}

document.write('</tr></table>');

Although the above will display a 3-column table with all items within, it
generates an incorrect html structure, with the last row having a missing
cell:

<table><tr>
<td>entry 1</td>
<td>entry 2</td>
<td>entry 3</td>
</tr><tr>
<td>entry 4</td>
<td>entry 5</td>
<td>entry 6</td>
</tr><tr>
<td>entry 7</td>
<td>entry 8</td>
<td>entry 9</td>
</tr><tr>
<td>entry 10</td>
<td>entry 11</td>
</tr></table>

Or for example, if the variable at the top is set to "row_length = 11" then
there will be an empty row at the end of the table, as follows:

<table><tr>
<td>entry 1</td>
<td>entry 2</td>
<td>entry 3</td>
<td>entry 4</td>
<td>entry 5</td>
<td>entry 6</td>
<td>entry 7</td>
<td>entry 8</td>
<td>entry 9</td>
<td>entry 10</td>
<td>entry 11</td>
</tr><tr>
</tr></table>

Again, it display's, but not correctly.

Does anyone have a better procedure for generating even tables? One which
can for example add empty cells according to the number of missing cells,
if any.

It needs to be generic in the sense that it should work with any number of
predetermined array entries, while the number of rows, i.e. row_length, may
differ at runtime depending on the variable at the top.

There will never be any spanning, as in rowspan or colspan. If there are 2
cells missing at the end, there could simply be 2 cells added with &nbsp;
inside each one.

The above above code truly sucks!

Any better examples would be greatly appreciated!
 
T

Thomas 'PointedEars' Lahn

Tuxedo said:
I'm attempting to stick together a procedure that determines the number of
cells in all rows of tables, based on a user defined variable of columns.
The variable needs to determine where the </tr>'s and <tr>'s are inserted.

Like for example:

var row_length = 3; // number of cells in all rows, i.e. columns

var gallery = new Array();{
,---------------------------^
This block statement is unnecessary.
gallery[0] = "entry 1";
gallery[1] = "entry 2";
gallery[2] = "entry 3";
gallery[3] = "entry 4";
gallery[4] = "entry 5";
gallery[5] = "entry 6";
gallery[6] = "entry 7";
gallery[7] = "entry 8";
gallery[8] = "entry 9";
gallery[9] = "entry 10";
gallery[10] = "entry 11";
}

The Array constructor can take an arbitrary number of arguments to
initialize the array with its elements (provided the first element is not a
number, there is no ambuiguity as to what it means -- the number of elements
initialized with undefined, or the value of the first element). The above
is not only inefficient and hard to maintain, it is error-prone (because one
has to take special care about the right indexes).
var insert_tr = 1;

document.write('<table border=1><tr>');

for (i = 0; i < gallery.length; i++, insert_tr++){
document.write('<td>'+gallery + '</td>')


ETAGOs ("</"s) must be escaped in HTML `script' element content.
Consecutive calls of document.write() are inefficient.
if (insert_tr == row_length) {
document.write('</tr><tr>')

Writing incomplete HTML elements is error-prone.
insert_tr = 0;
}

}

document.write('</tr></table>');

Although the above will display a 3-column table with all items within, it
generates an incorrect html structure, with the last row having a missing
cell:

There is nothing incorrect about that. However, if you need all rows to be
filled equally with cells, you only need to append as much empty elements as
needed to reach a multiple of the number of cells per row.
[...]
The above above code truly sucks!
Indeed.

Any better examples would be greatly appreciated!

var row_length = 3; // number of cells in all rows, i.e. columns

var gallery = new Array(
"entry 1",
"entry 2",
"entry 3",
"entry 4",
"entry 5",
"entry 6",
"entry 7",
"entry 8",
"entry 9",
"entry 10",
"entry 11");

// fills all rows equally (optional); you may also push "&nbsp;" here
while (gallery.length % row_length) gallery.push("");

var out = new Array('<table border="1">');

for (var i = 0, len = gallery.length; i < len; i++)
{
if (i % row_length == 0) out.push('<tr>');
out.push('<td>' + gallery + '<\/td>');
}

out.push('<\/table>');

document.write(out.join("\n"));

This does not generate a `</tr>' tag, but since that is optional, it is
perfectly valid HTML and works even when the number of total cells equals a
multiple of the number of cells per row (e.g. row_length == 11).


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
var row_length = 3; // number of cells in all rows, i.e. columns

var gallery = new Array(
"entry 1",
"entry 2",
"entry 3",
"entry 4",
"entry 5",
"entry 6",
"entry 7",
"entry 8",
"entry 9",
"entry 10",
"entry 11");

// fills all rows equally (optional); you may also push "&nbsp;" here
while (gallery.length % row_length) gallery.push("");

var out = new Array('<table border="1">');

for (var i = 0, len = gallery.length; i < len; i++)
{
if (i % row_length == 0) out.push('<tr>');
out.push('<td>' + gallery + '<\/td>');
}

out.push('<\/table>');

document.write(out.join("\n"));

This does not generate a `</tr>' tag, but since that is optional, it is
perfectly valid HTML and works even when the number of total cells equals a
multiple of the number of cells per row (e.g. row_length == 11).


And here it is with `</tr>':

// ...

for (var i = 0, len = gallery.length; i < len; i++)
{
if (i % row_length == 0)
{
if (i > 0) out.push('</tr>');
out.push('<tr>');
}

out.push(new Array('<td>', gallery, '<\/td>').join(""));
}

out.push('<\/tr>', '<\/table>');

document.write(out.join("\n"));


PointedEars
 
T

Tuxedo

Thomas said:
Thomas said:
var row_length = 3; // number of cells in all rows, i.e. columns

var gallery = new Array(
"entry 1",
"entry 2",
"entry 3",
"entry 4",
"entry 5",
"entry 6",
"entry 7",
"entry 8",
"entry 9",
"entry 10",
"entry 11");

// fills all rows equally (optional); you may also push "&nbsp;" here
while (gallery.length % row_length) gallery.push("");

var out = new Array('<table border="1">');

for (var i = 0, len = gallery.length; i < len; i++)
{
if (i % row_length == 0) out.push('<tr>');
out.push('<td>' + gallery + '<\/td>');
}

out.push('<\/table>');

document.write(out.join("\n"));

This does not generate a `</tr>' tag, but since that is optional, it is
perfectly valid HTML and works even when the number of total cells
equals a multiple of the number of cells per row (e.g. row_length ==
11).


And here it is with `</tr>':

// ...

for (var i = 0, len = gallery.length; i < len; i++)
{
if (i % row_length == 0)
{
if (i > 0) out.push('</tr>');
out.push('<tr>');
}

out.push(new Array('<td>', gallery, '<\/td>').join(""));
}

out.push('<\/tr>', '<\/table>');

document.write(out.join("\n"));


PointedEars


Thanks for the excellent script, it works like a charm!

Also, I had no idea that these "</" should be escaped in HTML
document.write situations. I've never done that before, as it seems to work
without escapes too.
 
T

Thomas 'PointedEars' Lahn

Tuxedo said:
Thomas said:
[Script to generate an HTML table of fixed number of cells per row
from given cell data]
Thanks for the excellent script, it works like a charm!

You're welcome. But please trim your quotes next time, as recommended
e.g. by the FAQ: http://www.jibbering.com/faq/faq_notes/clj_posts.html
Also, I had no idea that these "</" should be escaped in HTML
document.write situations.

Only if that script code is *content* of a HTML `script' element. You don't
need that for code in includes (script[src]) where the element content
should be empty. However, it is probably not a bad idea to do this always,
so in case the script code of the include is being used in a `script'
element (e.g. for test cases or examples), no adjustment would be needed.
I've never done that before, as it seems to work without escapes too.

The W3C Markup Validator <http://validator.w3.org/> will tell you the markup
is not Valid if you don't escape ETAGOs in CDATA element content, and
rightly so. That is generally considered as a sign of bad quality of the
document, and it can prevent you from finding other, more serious problems
with your markup that make it even less interoperable (in case you think
of that as many other people appear to: trying to comment out the script
element's content with CDO and CDC only makes it worse; it is *CDATA*, _not_
PCDATA).

It is only that many Web browsers are more forgiving when it comes to not
Valid markup; they have built-in error-correction, hence their parsers are
informally called tag-soup parsers (in contrast to SGML parsers). However,
it is unwise to rely on that, because it can break with the next more
standards-compliant user agent.


Regards,

PointedEars
 
T

Tuxedo

Thomas 'PointedEars' Lahn wrote:

[...]
However, it is unwise to rely on that, because it can break with the next
more standards-compliant user agent.

Thanks for the detailed answer. Who knows if it will make a difference in a
real world scenario, but better be safe than sorry, and so I will try and
remember to escape those sequences from now on.

Again, thanks for an excellent script solution!
 
T

Thomas 'PointedEars' Lahn

Tuxedo said:
For example, the following will cause BEFORE and AFTER appear in the right
places of all cells with content, which is intended, but also before and
after any extra cells containing the &nbsp strings, which is not intended:

out.push(new Array('<td>', 'BEFORE'+gallery+'AFTER', '<\/td>').join(""));

I know I didn't fully explain this order to keep the question short, but how
may the existing loop best be adapted to allow the BEFORE and AFTER strings
to surround the content in the gallery populated cells only?


var
sGallery = gallery,
bIsEmpty = (sGallery == ""),
sBefore = (bIsEmpty ? "BEFORE" : "&nbsp;"),
sAfter = (bIsEmpty ? "AFTER" : "");

out.push(new Array('<td>', sBefore, sGallery, sAfter, '<\/td>').join(""));

Testing for the empty string and then use &nbsp; appears to be better, so
you need to change your input data if you want to use the above as is. If
you don't want to, you may move the `&nbsp;' from `sBefore' to `bIsEmpty'
to test for "&nbsp;" instead.


HTH

PointedEars
 
T

Tuxedo

Thomas 'PointedEars' Lahn wrote:

[---]
out.push(new Array('<td>', gallery, '<\/td>').join(""));


While implementing this for an end-purpose I'm trying to enter some
arbitrary html strings within the table cells, which are meant to appear
before and after each gallery entry populated table cells only. This is
proving difficult because the strings also end up in the empty cells, i.e.
in those cells that exceed the number of original array entries surrounding
whatever string may be specified in the gallery.push("&nbsp;") part.

For example, the following will cause BEFORE and AFTER appear in the right
places of all cells with content, which is intended, but also before and
after any extra cells containing the &nbsp strings, which is not intended:

out.push(new Array('<td>', 'BEFORE'+gallery+'AFTER', '<\/td>').join(""));

I know I didn't fully explain this order to keep the question short, but how
may the existing loop best be adapted to allow the BEFORE and AFTER strings
to surround the content in the gallery populated cells only?

Many thanks!
 
T

Tuxedo

Thomas 'PointedEars' Lahn wrote:

[...]
var
sGallery = gallery,
bIsEmpty = (sGallery == ""),
sBefore = (bIsEmpty ? "BEFORE" : "&nbsp;"),
sAfter = (bIsEmpty ? "AFTER" : "");

out.push(new Array('<td>', sBefore, sGallery, sAfter,
'<\/td>').join(""));

Testing for the empty string and then use &nbsp; appears to be better, so
you need to change your input data if you want to use the above as is. If
you don't want to, you may move the `&nbsp;' from `sBefore' to `bIsEmpty'
to test for "&nbsp;" instead.


This gives me the possibility to easily add something before and after
entries in the populated cells, as well as affect possible empty or &nsbp;
entries in placeholder cells in the same way. It is now as configurable as
can be. Many than for the first-class scripting!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top