...

View Full Version : appendChild(cloneNode) problem



Kor
10-14-2004, 11:33 AM
I am working on a sortable table (full code in attachment). I solved all the intermediate steps till the end when, to my surprise, appenChild() method inserts some previous cloneNodes in looped rows in a peculiar mode, by leaving the end tags </tr> at the end of the table. So far:

1.- build the cloneNodes of the rows as an array, and each index as a paralel array:

//some needed variables on later
t=document.getElementById('tab');
nr=t.rows;
nc=t.rows[0].cells;

//array of rows and rows indexes
var oRows = new Array()
var iRows = new Array()
for(var i=1;i<nr.length;i++){
oRows[i]=t.rows[i].cloneNode(true);
iRows[i]=t.rows[i].rowIndex;
//so far so good, alert shows me what i needed
alert(oRows[i].innerHTML)
}

2. - build an array with the content of the correspondent cells on column and sort this array. The array is double and keep the genuine row's index for later use as each second element.

q=w.parentNode.cellIndex;
var oCol = new Array()
for(var i=0;i<iRows.length;i++){
oCol[i]=[t.rows[i].cells[q].firstChild.nodeValue,iRows[i]];
}
oCol.shift();
oCol.sort();
// so far so good also

3. Remove the content of the rows

for (var i=1;i<iRows.length;i++){
for(var j=t.rows[i].childNodes.length-1;j>=0;j--){
t.rows[i].removeChild(t.rows[i].childNodes[j])
}
}
alert(t.innerHTML)
//so far so good also, the alert shows me that.

4. Now here's the problem. I try to append the cloneNodes in a sorted order as childs of each blank row, but it seams that the append is incorrect:

for(var i=1;i<oCol.length+1;i++){
t.rows[i].appendChild(oRows[oCol[i-1][1]])
alert(t.innerHTML)
}

Any ideea why? Should have I use another approach?

Kor
10-14-2004, 12:29 PM
Hm... It looks like each cloneNode is a row, after all, so I see now a part of the peoblem... But when I try to append using another reference type

...
oCol.sort();
for (var i=oCol.length;i>0;i--){
t.deleteRow(i);
}
for(var i=1;i<oCol.length+1;i++){
t.childNodes[0].appendChild(oRows[oCol[i-1][1]])
}

Things go well for IE, but Moz says I can not append a node like that. Here's another problem now... Any ideeas?

liorean
10-14-2004, 12:49 PM
Don't delete the rows. Replace them.


oldtablerow.parentNode. // Fix for the table/tbody parent problem
replaceChild(newtablerow,oldtablerow)


I don't know what method is better, really, but I would have sorted the table something like this, had I written the sorter:

// Prepare for sorting
var
oRow,
oRows=table.tBodies.item(0).rows;
// Use a thead for the headers, and a tbody for data cells.
i=0,
aRows=[];
while(oRow=oRows.item(i++))
aRows.push(oRow.cells);
// Note that this contains a dynamic collection of cells inside a given
// table row. If you change the row, you will change the collection.

// Sort
function sortByCol(i,d){
// i is the column index to sort after
// d is the direction, 1 for normal, -1 for reverse
return function(a,b){
var
x=a.item(i).firstChild.data,
y=b.item(i).firstChild.data;
// Assumes all cells are non-empty and have textual contents
// as first child
return x<y?-d:x>y?d:0;
}
}

aRows.sort(sortByCol(columnIndex,1));

// Change to the new, sorted table
i=0;
while(oRow=oRows.item(i++))
oRow.parentNode.replaceChild(aRows[i].item(0).parentNode,oRow);


This code is untested, of course.

Kor
10-14-2004, 01:23 PM
:thumbsup: Tx a lot... I have had tried the replaceChild() method, but I used childNodes[0]childNodes[i] references, thinking that tbody must have been a node common understood both by IE and Moz...

I know that childNodes might give error in at least one of those 2 browsers and I tried to avoid it till the end...

Tx, it works now... I will make the reverse sort also now, but this woun't be a problem.

Do you think that my code is proper aproach to the problem, or it might have been a better/shorter way?

liorean
10-14-2004, 01:45 PM
Do you think that my code is proper aproach to the problem, or it might have been a better/shorter way?I don't know, I seldom work with tables. See my edit of the last post, though, I added how I would have done it. (Based solely on DOM, I haven't tested or anything.)

Kor
10-14-2004, 02:43 PM
Aha... I see that your approach is based on split/recreate rows from cells. I would like to avoid that by split the table on rows.

Here's my final, tested table. It sorts/reverse the rows content depending on column content. Useful to search through a long data tabel containing, say, first name, last name, birth place town, job, company... and so on. User may sort for a beter search upon it's needs.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<style type="text/css">
<!--
td {
background-color: #CCCCCC;
}
-->
</style>
<script language="JavaScript" type="text/JavaScript">
function sortIt(w){
r=document.getElementById('tab').rows;
var oRows = new Array()
var iRows = new Array()
for(var i=1;i<r.length;i++){
oRows[i]=r[i].cloneNode(true);
iRows[i]=r[i].rowIndex;
}
q=w.parentNode.cellIndex;
var oCol = new Array()
var vCol = new Array()
for(var i=0;i<iRows.length;i++){
oCol[i]=[r[i].cells[q].firstChild.nodeValue,iRows[i]];
vCol[i]=[r[i].cells[q].firstChild.nodeValue,iRows[i]];
}
oCol.shift();
vCol.shift();
oCol.sort();
if((vCol.toString()==oCol.toString())==true){oCol.reverse()}
for(var i=1;i<r.length;i++){
r[i].parentNode.replaceChild(oRows[oCol[i-1][1]],r[i])
}
}
</script>
</head>
<body>
<table id="tab" width="400" border="0" cellspacing="2" cellpadding="2">
<tbody>
<tr>
<td><a href="#" onclick="sortIt(this);return false">SORT/REVERSE</a></td>
<td><a href="#" onclick="sortIt(this);return false">SORT/REVERSE</a></td>
<td><a href="#" onclick="sortIt(this);return false">SORT/REVERSE</a></td>
</tr>
<tr>
<td>Banana</td>
<td>darkyellow</td>
<td>40</td>
</tr>
<tr>
<td>Apple</td>
<td>cielblue</td>
<td>20</td>
</tr>
<tr>
<td>Curry</td>
<td>blue</td>
<td>10</td>
</tr>
<tr>
<td>Drops</td>
<td>agreen</td>
<td>30</td>
</tr>
</tbody>
</table>

</body>
</html>


Now my next step will be to insert a inner "search" based upon first (maybe even second) letter of the strings in cells which will select, same on columns, only those rows on which that string begin with that/those letter/group of letters and removes the other rows... Now I am sure that I can esily solve that next step... :thumbsup:

Tx again for your help

liorean
10-14-2004, 02:55 PM
Well, that code didn't quite work (mine, that is). Here's some code that does work except for a minor detail (iew).

liorean
10-14-2004, 03:25 PM
Aha... I see that your approach is based on split/recreate rows from cells. I would like to avoid that by split the table on rows.Nope. I never split cells from their rows. I only overwrite rows with different rows. The cells are only used for sorting.

Kor
10-14-2004, 05:16 PM
Well, that code didn't quite work


I could have swored that it worked some middle testing... I see now you are right, at laest for Moz... I have "shortened" some variables meanwhile, that might be the reason of... I'll check it tommorow...

Kor
10-15-2004, 09:06 AM
except for a minor detail (iew).

Unfortunately :D That minor detail is not convenable for me, as about 80% of the users have IE browsers...

Your script does work only on Moz...

But my script - with the tip you gave it to me, tx - (I tested this morning) works on all browsers I have (NS7, IE6, Firefox, Moz 1.7, Opera5) :thumbsup:

(Yesterday evening I forgot that I have had disabled javascript in Moz, so that I thought my script woun't work... - I see now that it works)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum