472,958 Members | 2,319 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,958 software developers and data experts.

Swapping table columns

VA
I got the following function to swap table columns from somewhere on
the Internet

function swapColumns (table, colIndex1, colIndex2) {
if (table && table.rows && table.insertBefore && colIndex1 !=
colIndex2) {
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
var cell1 = row.cells[colIndex1];
var cell2 = row.cells[colIndex2];
var siblingCell1 = row.cells[Number(colIndex1) + 1];
row.insertBefore(cell1, cell2);
row.insertBefore(cell2, siblingCell1);
}
}
}

where "table" is a Table object and colIndex1 and colIndex2 are
integers representing the column numbers to swap.

Problem is...it doesnt do anything. No errors in Firefox Javascript
console, but it just doesnt do a thing!

I checked a few basic things using the JS shell from squarefree.com
like rows.length, made sure it is entering the loop, etc. But the
insertBefore doesnt seem to be doing anything.

Help? Thanks

Nov 1 '05 #1
10 12645


VA wrote:
I got the following function to swap table columns from somewhere on
the Internet

function swapColumns (table, colIndex1, colIndex2) {
if (table && table.rows && table.insertBefore && colIndex1 !=
colIndex2) {
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
var cell1 = row.cells[colIndex1];
var cell2 = row.cells[colIndex2];
var siblingCell1 = row.cells[Number(colIndex1) + 1];
row.insertBefore(cell1, cell2);
row.insertBefore(cell2, siblingCell1);
}
}
}


Is "somewhere" FAQTs
<http://www.faqts.com/knowledge_base/view.phtml/aid/32355/fid/192>?
There is a test case included, does that really not work for you? Then
please provide a URL where the code does not work, make sure it is a
test case with a table and script but not some long page with lots of
stuff irrelevant to the code.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 1 '05 #2
VA
Martin: Thanks for replying, yes that is indeed where I got the
function from, thanks for writing it.

When I save the entire HTML document to a local file, open it in
Firefox, and click on the Swap Columns button, it works fine.

But when I use it in my own code, it doesnt work.

I did make sure that I pass in a Table object and 2 valid column
indexes to your function. I also used the JS shell to do
print(mytable.rows[0].cells[0].innerHTML) for a bunch of subscripts to
make sure I was navigating the right table. It just doesnt swap the
columns!

How can I troubleshoot this?

Thanks

Nov 1 '05 #3

VA wrote:
But when I use it in my own code, it doesnt work.


Consider putting a sample online and posting the URL here, that way we
can check what goes wrong.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 1 '05 #4
VA
Here is my stripped down example that does not work.

Thanks for any help.

<html lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>reorder columns</title>
</head>
<body ><form action="dummy" >
<script type="text/javascript">
function doSomething(pThis)
{
alert('About to swap columns...');
swapColumns(document.getElementById("mytable"),1,2 );
}

function swapColumns (table, colIndex1, colIndex2) {
if (table && table.rows && table.insertBefore && colIndex1 !=
colIndex2) {
alert('in swapColumns, rows='+table.rows.length);
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
var cell1 = row.cells[colIndex1];
var cell2 = row.cells[colIndex2];
var siblingCell1 = row.cells[Number(colIndex1) + 1];
row.insertBefore(cell1, cell2);
row.insertBefore(cell2, siblingCell1);
}
}
}
</script>
<input type="button" value="Swap" onClick="doSomething(this)"></td>

<table id="mytable" cellpadding="0" border="0" cellspacing="0"
summary="0">
<tr><th id="JOB">JOB</th><th id="MGR">MGR</th><th
id="ENAME">ENAME</th><th id="EMPNO">EMPNO</th></tr>
<tr><td>null</td><td>null</td><td>null</td><td>7839</td></tr>
<tr><td>MANAGER</td><td>7839</td><td>BLAKE</td><td>7698</td></tr>
<tr><td>MANAGER</td><td>7839</td><td>CLARK</td><td>7782</td>
</tr>
<tr><td>MANAGER</td><td>7839</td><td>JONES</td><td>7566</td></tr>
<tr><td>ANALYST</td><td>7566</td><td>SCOTT</td><td>7788</td></tr>
<tr><td>CLERK</td><td>null</td><td>DOE</td><td>8000</td></tr>
<tr><td>null</td><td>null</td><td>Jane Doe</td><td>9000</td></tr>
<tr><td>null</td><td>null</td><td>Batman</td><td>1234</td></tr>
<tr><td>null</td><td>null</td><td>Superman</td><td>3333</td></tr>
<tr><td>null</td><td>null</td><td>J Doe</td><td>101</td></tr>
<tr><td>SALESMAN</td><td>7698</td><td>TURNER</td><td>7844</td></tr>
<tr><td>CLERK</td><td>7788</td><td>ADAMS</td><td>7876</td></tr>
<tr><td>null</td><td>null</td><td>asdfasdfad</td><td>5678</td></tr>
<tr><td>null</td><td>null</td><td>test</td><td>1000</td></tr>
<tr><td>null</td><td>null</td><td>Nothing</td><td>7733</td></tr>
</table>
</form>
</body>
</html>

Nov 1 '05 #5
VA wrote:
Here is my stripped down example that does not work.

Thanks for any help.

<html lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>reorder columns</title>
</head>
<body ><form action="dummy" >
<script type="text/javascript">
function doSomething(pThis)
{
alert('About to swap columns...');
swapColumns(document.getElementById("mytable"),1,2 );
}

function swapColumns (table, colIndex1, colIndex2) {
The logic below is dependent on colIndex1 being the lower number, so I'd
add:

if (!colIndex1 < colIndex2){
var t = colIndex1;
colIndex1 = colIndex2;
colIndex2 = t;
}
if (table && table.rows && table.insertBefore && colIndex1 !=
colIndex2) {
alert('in swapColumns, rows='+table.rows.length);
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
var cell1 = row.cells[colIndex1];
var cell2 = row.cells[colIndex2];
var siblingCell1 = row.cells[Number(colIndex1) + 1];
row.insertBefore(cell1, cell2);


The logic here will only work if the cells to be swapped aren't
adjacent. It swaps cell1 with the cell immediately before cell2, which
(if they're adjacent) is cell1. Swap cell2 (the higher index) first:

for (var i=0, len=table.rows.length; i<len; ++i) {
var row = table.rows[i];
var cell1 = row.cells[colIndex1];
var cell2 = row.cells[colIndex2];
row.insertBefore(cell2, cell1);
row.insertBefore(cell1, row.cells[colIndex2]);
}

The above will work with any column indexes, adjacent or otherwise.

[...]

--
Rob
Nov 2 '05 #6
VA
Thanks.

One more question:

How can I extend this concept to, say, take in a list of column indexes
(or TH ids) and re-order the columns according to that order?

Thanks

Nov 2 '05 #7
VA wrote:
Thanks.

One more question:

How can I extend this concept to, say, take in a list of column indexes
(or TH ids) and re-order the columns according to that order?

Thanks


There was an error in my earlier script, this line:

row.insertBefore(cell1, row.cells[colIndex2]);

should be:

row.insertBefore(cell1, row.cells[colIndex2].nextSibling);

The nextSibling bit is important when swapping non-adjacent rows.
Ordering columns is a fish of a different feather.

You first must decide which columns to swap, then swap them. Here are
some general solutions (if RC is reading this, I make no apologies for
qualifying 'solution'):

1. Determine which columns need to be swapped and do that - probably
more than one swap will be required and hopefully you have an
algorithm that lets you do it in as few as possible

2. Break the table into fragments and re-construct it in the new order

3. Clone the cells of the existing table, add them to a new table in
the new order then replace the existing table with the new one

4. Inspect the new order, wherever a column is out of order, move it to
its new position.

Which one is more efficient than the other will likely depend on the
situation, I think the last is the best as a general solution (i.e. will
work in all situations and it is sufficiently fast in most).

For example, if the columns are in the order ABCD and you are given the
order ACDB, you can do two swaps or one move. To get ACBD requires one
swap or one move, and DCBA requires two swaps or 3 moves.

Fragmenting/cloning will take the same amount of time every time, those
methods may come into their own if the tables are large and the
re-ordering is extensive.

The difference in time taken for one method compared to another may be
significant and probably varies depending on the browser and internal
algorithm for each method - e.g. DOM move versus some innerHTML/text
munging method.

Will the user want re-order the columns manually (say moving individual
columns left or right)? Will they want to prescribe the new order then
press a button to 'make it so'.

Below is a script that uses keys for the old order and the new order,
e.g. for a four column table, changing ABCD to ADBC requires 2 moves.

The maximum number of moves ever required is one less that the number of
columns (I think). It only searches through the keys, so even if a large
number of columns need lots of changes, the number of moves should be
kept close to the minimum number (though likely not often *the* minimum
number) required.

I've left out feature detection etc. The use of concat, splice etc.
means JavaScript 1.2 or better is required. It needs DOM anyway, so
what the heck. Not all browsers support the cells collection properly
(e.g. Safari 1.0.3 but fixed thereafter).

There is also very little error detection or correction, you may want to
add some.

<html><head>
<title>reorder columns</title>
</head>
<body >

<script type="text/javascript">

// Re-order table
function reorderColumn(table, order0, order1)
{
// Turn order keys into arrays
order0 = order0.split('');
order1 = order1.split('');

// Check arrays are same length
if (order0.length != order1.length) return;

// Check arrays have same elements
var x = order0.concat().sort().join('');
var y = order1.concat().sort().join('');
if (x != y) return;

// Re-order the columns
var j, k = i = order0.length;
while (i--) { // Compare each key
if (order0[i] != order1[i]){ // If one out of order
j = newIdx(order0[i], order1) // Find new spot
moveColumn(table, i, j); // Move the column
moveEl(order0, i, j); // Move the key
i = k; // Start key comparison again
}
}
}

// returns the position of element el in array ar
// Assumes el is in ar
function newIdx(el, ar)
{
var i = ar.length;
while( ar[--i] != el){}
return i;
}

// Move a column of table from start index to finish index
// Assumes there are columns at sIdx and fIdx
function moveColumn(table, sIdx, fIdx)
{
var row, cA;
var i=table.rows.length;
while (i--){
row = table.rows[i]
var x = row.removeChild(row.cells[sIdx]);
row.insertBefore(x, row.cells[fIdx]);
}
}

// Move element in array ar from index i to index j
// Assumes array has indexes i and j
function moveEl(ar, i, j)
{
var x = ar.splice(i,1);
ar.splice(j,0,x);
return ar; // Not needed, handy for debug
}

</script>

<input type="button" value="re-order ABCD to DCBA" onClick="
reorderColumn(document.getElementById('tableA'),'A BCD','DCBA');
"><br>

<table id="tableA" cellpadding="5" border="1"
cellspacing="5">
<tr><th>HC0</th><th>HC1</th><th>HC2</th><th>HC3</th></tr>
<tr><td>R0 C0</td><td>R0 C1</td><td>R0 C2</td><td>R0 C3</td></tr>
<tr><td>R1 C0</td><td>R1 C1</td><td>R1 C2</td><td>R1 C3</td></tr>
<tr><td>R2 C0</td><td>R2 C1</td><td>R2 C2</td><td>R2 C3</td></tr>
<tr><td>R3 C0</td><td>R3 C1</td><td>R3 C2</td><td>R3 C3</td></tr>
</table>

</body>
</html>
--
Rob
Nov 2 '05 #8
RobG wrote:
<snip>
You first must decide which columns to swap, then swap them.
Here are some general solutions (if RC is reading this, I
make no apologies for qualifying 'solution'):

<snip>

It is not qualifying 'solution', as such, that I have an issue with. To
say a solution may be best, better, worse, worst, adequate, etc, etc is
just admitting that there are usually numerous solutions to any one
problem and that some criteria may be applied to choosing between them.
The solution is not more or less of a solution for the use of that type
of qualifier. My issue is with qualifiers that modify the meaning of
'solution' and are used to hide a failure to solve behind something that
still sounds positive. Using such qualifiers is dishonest, disingenuous
and demonstrates contempt for intelligence of the people on the
receiving end. It is the sort of thing you find in marketing (where
contempt for the intelligence of others is normal (and sometime
justified)) but it can only get in the way of discussions about
programming.

Richard.
Nov 2 '05 #9
VA
Thanks a lot, it works fine in FF, but in IE, it throws an error when
fIdx is equal to the last column in the table.

Any idea why?

Thanks

Nov 7 '05 #10
VA
Also, in IE, after a few iterations, IE starts to drop cells from the
last row in the table!

Nov 7 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Christopher Jeris | last post by:
Please help me understand the differences, in semantics, browser support and moral preferredness, between the following three methods of swapping content in and out of a page via JavaScript. I...
61
by: Toby Austin | last post by:
I'm trying to replace <table>s with <div>s as much as possible. However, I can't figure out how to do the following… <table> <tr> <td valign="top" width="100%">some data that will...
3
by: foldface | last post by:
Hi This works but is a bit long-winded. Is there a better way? ta F <style> ..Header { background-color: gray;
7
by: Bing Wu | last post by:
Hi Folks, I have a very large table containing 170 million rows of coordinats: CREATE TABLE "DB2ADMIN"."COORDINATE" ( "FID" INTEGER NOT NULL , "AID" INTEGER NOT NULL , "X" REAL NOT NULL ,...
4
by: maricel | last post by:
I have the following base table structure - DDL: CREATE TABLE "ADMINISTRATOR"."T1" ( "C1" INTEGER NOT NULL ) IN "TEST_TS" ; ALTER TABLE "ADMINISTRATOR"."T1" ADD PRIMARY KEY
1
by: kingster | last post by:
Hi, I have a regular dataset and all i want to do is make a pivot table display in a browser with the datasource of the pivot table to be this dataset and then the end-user will be able to do...
4
by: Hemant Shah | last post by:
Folks, Our client has a program that browses whole table from begining to end. The table has 1 million rows in it. REORGCHK does not show any problems. It has unique index defined on KEY0...
5
by: wugon.net | last post by:
question: db2 LUW V8 UNION ALL with table function month() have bad query performance Env: db2 LUW V8 + FP14 Problem : We have history data from 2005/01/01 ~ 2007/05/xx in single big...
7
by: TG | last post by:
hi! I am trying to create a sql server table from an excel sheet. Here is the code I have: 'This procedure the xlsx file and dumps it to a table in SQL Server
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.