How to read the content of an object

S

Stefan Mueller

I'm using the following code to sort a html table:
...
var_table = this.sorttable_tbody;

for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
var_table.appendChild(row_array[rowcounter][1]);
}

The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast. However, the rows in my html table look like
<tr class = "tableentry_odd">...
<tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.

If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.

Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?
 
J

Jason Carlton

I'm using the following code to sort a html table:
    ...
    var_table = this.sorttable_tbody;

    for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
      var_table.appendChild(row_array[rowcounter][1]);
    }

The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast. However, the rows in my html table look like
  <tr class = "tableentry_odd">...
  <tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.

If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.

Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?


Are you only trying to alternate the background color? If so,
something like this might be easier:

var bgcolor="#FFFFFF";

for (rowcounter = 0; rowcounter < row_array.length; rowcounter++) {
if (rowcounter/2 == parseInt(rowcounter/2) bgcolor="#000000";
}

There's probably a better way than that, it's just what came
immediately to mind.
 
R

RobG

I'm using the following code to sort a html table:
...
var_table = this.sorttable_tbody;

It would make more sense to me to call that variable tbody or similar.

for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)

It is more efficient to get row_array.length once and store the value.
It is also more conventional to use i, j, k etc. for internal counters
(you may have other reasons for using "rowcounter" though):

for (var i=0, iLen=row_array.length; i<iLen; i++)

{
var_table.appendChild(row_array[rowcounter][1]);

Here is your opportunity to update the row's class property. Store a
reference to the row and then update the class based on the row index
before adding it to the tbody:

var row = row_array[1];
if (i%2) {
row.className = 'tableentry_odd';
} else {
row.className = 'tableentry_even';
}
var_table.appendChild(row);
}

The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast.

You may find it faster to make a shallow clone of the tbody element,
add the new rows to that, then when the append loop has finished,
replace the (now empty) tbody with the (now sorted) cloned tbody.
Testing will reveal if it's worthwhile.

However, the rows in my html table look like
<tr class = "tableentry_odd">...
<tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.

See above.

My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.

I'll guess that row_array is actually an array, and that row_array
[row_counter][1] is a reference to a DOM table row element. You don't
want to read the row's content, you just want to modify one of its
properties - see above where the className property is modified (the
DOM className property is equivalent to the HTML class attribute).

If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.

row_array[rowcounter][1] is (I've assumed) a reference to a DOM table
row element. Passing it as an argument to alert calls its toString
method, and that's what gets put in the alert dialog. I guess you're
using IE, Firefox (and others) will show "object HTMLTableRowElement".

PS. It was claimed here recently that HTML 5 specifies the behaviour
of DOM 0 methods. Does it specify what window.alert does? I don't see
the toString method of DOM object specified anywhere either.
 
R

RobG

Here is your opportunity to update the row's class property. Store a
reference to the row and then update the class based on the row index
before adding it to the tbody:

var row = row_array[1];
if (i%2) {
row.className = 'tableentry_odd';
} else {
row.className = 'tableentry_even';
}


Some one else will likely mention it so I'll get in first. The
if..else block can also be written:

row.className = (i%2)? 'tableentry_odd' : 'tableentry_even';

I wrote it the long way for two reasons:

1. It should be easier to maintain - someone with a minimal grasp of
ECMAScript should be able to work out what it does.

2. I thought it would be faster as an if..else block rather than a
ternary expression. However, testing in IE 6 and Firefox 3.5 shows the
difference in speed to be negligible and likely inconsequential in the
decision of which pattern to use. Results may be different in other
browsers.

var_table.appendChild(row);



You may find it faster to make a shallow clone of the tbody element,
add the new rows to that, then when the append loop has finished,
replace the (now empty) tbody with the (now sorted) cloned tbody.
Testing will reveal if it's worthwhile.

I should also mention that the cloned tbody element will lose any
listeners added to the element by assigning to its on<event> property
and those added using the W3C addEventListener method, but not those
added inline in the HTML or by the IE proprietary attachEvent method
(in IE at least).
 
T

Thomas 'PointedEars' Lahn

RobG said:
Here is your opportunity to update the row's class property. Store a
reference to the row and then update the class based on the row index
before adding it to the tbody:

var row = row_array[1];
if (i%2) {
row.className = 'tableentry_odd';
} else {
row.className = 'tableentry_even';
}


That has become unnecessary for many (but apparently not yet most) browsers,
though, because of the implementation of the corresponding feature of CSS3
Selectors (WD).
Some one else will likely mention it so I'll get in first. The
if..else block can also be written:

row.className = (i%2)? 'tableentry_odd' : 'tableentry_even';

I wrote it the long way for two reasons:

1. It should be easier to maintain - someone with a minimal grasp of
ECMAScript should be able to work out what it does.

"Easier to maintain" is a double-edged sword, though. It may be easier to
read at first, but when you have to rename something, maintainance does not
become easier but harder as you need to rename it at least twice. Regarding
maintenance, the if-statment approach has the advantage of being a bit more
flexible as each branch can contain statements, not only expressions.

Besides, someone with "a minimal grasp of ECMAScript" should know its
operators, whereas ?: is one of them. Then again, the person you describe
is not likely to be qualified for the job anyway.


PointedEars
 
J

JR

I'm using the following code to sort a html table:
    ...
    var_table = this.sorttable_tbody;

    for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
      var_table.appendChild(row_array[rowcounter][1]);
    }

The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast. However, the rows in my html table look like
  <tr class = "tableentry_odd">...
  <tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.

If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.

Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?

Check this out:
http://www.jrfaq.com.br/sortable.htm

Cheers,
JR
 
D

David Mark

I'm using the following code to sort a html table:
    ...
    var_table = this.sorttable_tbody;
    for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
      var_table.appendChild(row_array[rowcounter][1]);
    }
The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast. However, the rows in my html table look like
  <tr class = "tableentry_odd">...
  <tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.
If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.
Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?

Check this out:http://www.jrfaq.com.br/sortable.htm

Okay.

getInnerText : function (el) {
/* Code is optimized for IE7 because of its slower performance.
innerText -> innerText is an IE 6 and 7 proprietary spec;
textContent -> DOM Level 3 - FF, Safari, etc., except IE
innerHTML -> at last we'll try the sluggish innerHTML. */
var re = /^\s+|\s+$/g;
if (typeof el.innerText !== 'undefined') { return
el.innerText.replace(re, ''); }
if (typeof el.textContent !== 'undefined') { return
el.textContent.replace(re, ''); }
if (typeof el.innerHTML === 'string') {
return el.innerHTML.replace(/^\s+<[^<>]+>|\s+$/g, '');
}
},

Now, what possessed you to re-invent this particular wheel? I see you
added trimming. Lose that last fork as it isn't close. Loop through
the text nodes instead. Search the archive or see the example in My
Library for more efficient one-off examples.

// Look for tables which className contains 'sortable' and prepare
them for sorting.
var isMSIE = /*@cc_on!@*/false; // Dean Edwards' browser sniff.

You know you have gone down a wrong path when you start pasting in his
BS. ;) This ain't 2005 you know?

this.arrows = { // Adapted by JR from Stuart Langridge's idea.
up : (isMSIE ? '&nbsp<font face="webdings">5</font>' :
'&nbsp;▴'),
down : (isMSIE ? '&nbsp<font face="webdings">6</font>' :
'&nbsp;▾')
};

Stuart Langridge had a very bad idea. Why copy it?

Don't have time to look at the rest. It would be disallowed anyway
due to the above. Did seem to work in FF3 anyway. But I am hesitant
to endorse it on the basis of this observation. ;)
 
D

Dr J R Stockton

In comp.lang.javascript message <df181f02-a4fc-4cc5-b0e2-b8b24c78f8ef@g2
7g2000yqn.googlegroups.com>, Tue, 1 Dec 2009 17:19:14, Jason Carlton
for (rowcounter = 0; rowcounter < row_array.length; rowcounter++) {
if (rowcounter/2 == parseInt(rowcounter/2) bgcolor="#000000";
}

Or ... if (rowcounter%2) ...

Or for (R=0, B=0 ; R<L ; R++, B^=1) {
if (B) ...

The OP might find it easier to create the ill-coloured table and after
that to scan it assigning an appropriate class name to every TR element.
 
S

Stefan Mueller

Many thanks for your help. It works great!

for (var i=0; ilen=row_arraylength; i<ilen; i++) {
var row = row_array[1];

if (i % 2) {
row.className = "tableentry_odd";
}
else {
row.className = "tableentry_even";
}
var_table.appendChild(row_array[1]);
}

Because each row is initial define with
<tr class = "tableentry_odd"
onMouseover = "className = 'tableentry_active'"
onMouseout = "className = 'tableentry_odd'">
I also need to set 'onMouseover' and 'onMouseout'.

Does someone know if I can also set 'onMouseover' and 'onMouseout'
within the for loop (same way as row.className = "tableentry_odd";)?

Stefan
 
S

SAM

Le 12/4/09 1:12 AM, Stefan Mueller a écrit :
Many thanks for your help. It works great!

for (var i=0; ilen=row_arraylength; i<ilen; i++) {
var row = row_array[1];


row.className = (1%2)? "tableentry_odd" : "tableentry_even";
row.state = row.className;

var_table.appendChild(row);
}

Because each row is initial define with
<tr class = "tableentry_odd"
onMouseover = "className = 'tableentry_active'"
onMouseout = "className = 'tableentry_odd'">
I also need to set 'onMouseover' and 'onMouseout'.

Does someone know if I can also set 'onMouseover' and 'onMouseout'
within the for loop (same way as row.className = "tableentry_odd";)?

Add a property to the row seen as an object
(ie 'state' with the class as shown above)

then

<tr class="tableentry_odd"
onmouseover="this.className='tableentry_active';"
onmouseout="this.className=this.state">


Or then make a toggle function

function react(what) {
what.className = what.className=='tableentry_active'?
what.state :
'tableentry_active';
}

and do :

<tr onmouseover="react(this)" onmouseout="react(this)"
class="tableentry_odd">
....
<tr onmouseover="react(this)" onmouseout="react(this)"
class="tableentry_even">
 
R

RobG

Many thanks for your help. It works great!

  for (var i=0; ilen=row_arraylength; i<ilen; i++) {
    var row = row_array[1];

    if (i % 2) {
      row.className = "tableentry_odd";
    }
    else {
      row.className = "tableentry_even";
    }
    var_table.appendChild(row_array[1]);
  }

Because each row is initial define with
  <tr class = "tableentry_odd"
  onMouseover = "className = 'tableentry_active'"
  onMouseout = "className = 'tableentry_odd'">
I also need to set 'onMouseover' and 'onMouseout'.

Does someone know if I can also set 'onMouseover' and 'onMouseout'
within the for loop (same way as row.className = "tableentry_odd";)?


Yes. You can just add the extra class, then remove it - there is no
need to add and remove the odd and even classes at the same time
provided the new active class name is added after the others.

Search the archives, there are plenty of add and remove class
functions.
 
J

JR

I'm using the following code to sort a html table:
    ...
    var_table = this.sorttable_tbody;
    for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
      var_table.appendChild(row_array[rowcounter][1]);
    }
The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works great an
very fast. However, the rows in my html table look like
  <tr class = "tableentry_odd">...
  <tr class = "tableentry_even">...
I use this so that each second row has a different background color.
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.
If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.
Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?

Okay.

getInnerText : function (el) {
/* Code is optimized for IE7 because of its slower performance.
         innerText -> innerText is an IE 6 and 7 proprietary spec;
         textContent -> DOM Level 3 - FF, Safari, etc., except IE
         innerHTML -> at last we'll try the sluggish innerHTML.*/
                var re = /^\s+|\s+$/g;
                if (typeof el.innerText !== 'undefined') { return
el.innerText.replace(re, ''); }
                if (typeof el.textContent !== 'undefined') { return
el.textContent.replace(re, ''); }
                if (typeof el.innerHTML === 'string') {
                        return el.innerHTML.replace(/^\s+<[^<>]+>|\s+$/g, '');
                }
        },

Now, what possessed you to re-invent this particular wheel?  I see you
added trimming.  Lose that last fork as it isn't close.  Loop through
the text nodes instead.  Search the archive or see the example in My
Library for more efficient one-off examples.

The getInnerText() method mentioned above is not a generic function.
Instead, it's tailored specifically for sorting a table containing
simple data, like cells of a data sheet.
// Look for tables which className contains 'sortable' and prepare
them for sorting.
var isMSIE = /*@cc_on!@*/false; // Dean Edwards' browser sniff.

You know you have gone down a wrong path when you start pasting in his
BS.  ;)  This ain't 2005 you know?

IE sniffing is only necessary because of the next lines.
this.arrows = { // Adapted by JR from Stuart Langridge's idea.
up : (isMSIE ? '&nbsp<font face="webdings">5</font>' :
'&nbsp;▴'),
down : (isMSIE ? '&nbsp<font face="webdings">6</font>' :
'&nbsp;▾')
                };

Stuart Langridge had a very bad idea.  Why copy it?

What's your problem with the brits?
Don't have time to look at the rest.  It would be disallowed anyway
due to the above.  Did seem to work in FF3 anyway.  But I am hesitant
to endorse it on the basis of this observation.  ;)

That code works in FF3, IE7/8, Safari3 and Opera9.64 as expected.

Cheers,
JR
 
D

David Mark

I'm using the following code to sort a html table:
    ...
    var_table = this.sorttable_tbody;
    for (rowcounter = 0; rowcounter < row_array.length; rowcounter++)
{
      var_table.appendChild(row_array[rowcounter][1]);
    }
The 'appendChild' method moves each row of my existing html table in a
sorted manner to the end of the html table. That really works greatan
very fast. However, the rows in my html table look like
  <tr class = "tableentry_odd">...
  <tr class = "tableentry_even">...
I use this so that each second row has a different background color..
But after I've sorted the html table the background colors get mixed
up.
My intention is now to read the content of 'row_array[rowcounter][1]'
and to adjust '<tr class = "tableentry_...">...' so that each second
row has a different background color again. However, I've no idea how
to read and modify the content of 'row_array[rowcounter][1]'.
If I do 'alert(row_array[rowcounter][1]);' the output always shows
'[object]'.
Does someone know how to read the content of 'row_array[rowcounter]
[1]' and if my intention to modify the content of 'row_array
[rowcounter][1]' makes sense so that each second row has a different
background color even after the html table got sorted?
Check this out:http://www.jrfaq.com.br/sortable.htm

getInnerText : function (el) {
/* Code is optimized for IE7 because of its slower performance.
         innerText -> innerText is an IE 6 and 7 proprietary spec;
         textContent -> DOM Level 3 - FF, Safari, etc., except IE
         innerHTML -> at last we'll try the sluggish innerHTML. */
                var re = /^\s+|\s+$/g;
                if (typeof el.innerText !== 'undefined') { return
el.innerText.replace(re, ''); }
                if (typeof el.textContent !== 'undefined') { return
el.textContent.replace(re, ''); }
                if (typeof el.innerHTML === 'string') {
                        return el.innerHTML.replace(/^\s+<[^<>]+>|\s+$/g, '');
                }
        },
Now, what possessed you to re-invent this particular wheel?  I see you
added trimming.  Lose that last fork as it isn't close.  Loop through
the text nodes instead.  Search the archive or see the example in My
Library for more efficient one-off examples.

The getInnerText() method mentioned above is not a generic function.
Instead, it's tailored specifically for sorting a table containing
simple data, like cells of a data sheet.

It certainly is not.
IE sniffing is only necessary because of the next lines.

IE sniffing is not necessary.
What's your problem with the brits?

I don't have a problem with "the brits". That code is complete BS.
Do you think MSHTML implies that the Webdings font is available? I
assure you it doesn't and that using that font in a Web page is the
sort of thing you would have seen in 1990's "best viewed in IE" page.
That code works in FF3, IE7/8, Safari3 and Opera9.64 as expected.

So?
 
D

Dr J R Stockton

In comp.lang.javascript message <20d385d6-fb91-4d9e-a869-dd630d641de2@b2
g2000yqi.googlegroups.com>, Thu, 3 Dec 2009 16:12:09, Stefan Mueller
if (i % 2) {
row.className = "tableentry_odd";
}
else {
row.className = "tableentry_even";
}

More elegantly written as

row.className = i%2 ? "tableentry_odd" : "tableentry_even"

or even

row.className = "tableentry_" + (i%2 ? "odd" : "even")

Unless paid by the yard, it is well to minimise the amount of duplicated
code.
 
S

Stefan Mueller

Sam, your solution works great.

row.state = row.className;

...

<tr class="tableentry_odd"
onmouseover="this.className='tableentry_active';"
onmouseout="this.className=this.state">

Many thanks!

May I ask why you put a ';' to the second last position of the
following line?
onmouseover="this.className='tableentry_active';"

Is it really necessary and if yes why didn't you also put a ';' at the
third last position of the following line?
onmouseout="this.className=this.state;">
 
O

Osmo Saarikumpu

Stefan Mueller kirjoitti:
May I ask why you put a ';' to the second last position of the
following line?
onmouseover="this.className='tableentry_active';"

It's just a statement separator. Many add it automatically, needed or not.
Is it really necessary and if yes why didn't you also put a ';' at the
third last position of the following line?
onmouseout="this.className=this.state;">

It's not necessary, but it's there waiting just in case we decide to add
more statements to the event, e.g. (forced):

onmouseover="this.className='tableentry_active';alert(this.className)"

(Reference to window omitted for the sake of brevity.)

An analogy to CSS:

h1 {
color:#000;
background-color:#fff;
}

The second semicolon is not needed, but I tend to add it anyways.
 
O

optimistx

Osmo said:
onmouseover="this.className='tableentry_active';alert(this.className)"

(Reference to window omitted for the sake of brevity.)
Yes, that is an excellent idea. Very brief now.
 

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

No members online now.

Forum statistics

Threads
474,438
Messages
2,571,699
Members
48,796
Latest member
Greg L.
Top