Ordering rows in a table

  • Thread starter Brendan.Collins
  • Start date
B

Brendan.Collins

Hi

I have a javascript problem that has been annoying me for two days now
and thought that a javascript expert might have the magic solution.

I am populating a table dynamically from the database and I am trying
to allow the user to order the rows in the table using up and down
arrows.

The function I am using is:

function moveContactRow(direction)
{
var tempVal; //stores temporary value while swapping hidden values
rowIndex =
parseInt(window.event.srcElement.parentElement.parentElement.index);
if((rowIndex == 0 && direction > 0) || (rowIndex ==
id_listTable.rows.length - 1 && direction < 0) || (rowIndex > 0 &&
rowIndex < id_listTable.rows.length - 1))
{
if(id_listTable.rows[rowIndex].cells[0].swapNode)
{
id_listTable.rows[rowIndex +
direction].cells[0].swapNode(id_listTable.rows[rowIndex].cells[0]);
id_listTable.rows[rowIndex +
direction].cells[1].swapNode(id_listTable.rows[rowIndex].cells[1]);
id_listTable.rows[rowIndex +
direction].cells[2].swapNode(id_listTable.rows[rowIndex].cells[2]);
tempVal = document.all('hidID' + rowIndex).value;
document.all('hidID' + rowIndex).value = document.all('hidID' +
[rowIndex + direction]).value;
document.all('hidID' + [rowIndex + direction]).value = tempVal;
document.all('hid' + rowIndex).value = rowIndex + direction;
document.all('hid' + [rowIndex + direction]).value = rowIndex;
}
}
}


To call the function the arrows have the following code:

upArrow - onclick="moveContactRow(-1)
DownArrow - onclick="moveContactRow(1)

The good thing is that the table rows move correctly, but the values
written to the hidden fields (prefixed with hid or hidID) aren't always
correct.

Any ideas on whats happening?

Any help is greatly appreciated.

Thanks

Brendan
 
J

Jim Davis

Andrew Scott said:
(e-mail address removed) wrote:

Hi Brendan,

I wouldn't have used swapNodes to handle the re-ordering, instead I would
have an array that represents the table and then used the "sort" function
of array to re index the array and then redraw the table from the array.

I agree - getting into the DOM for this is nasty work. ;^)

Instead load your data into an abstracted element (like an array) and
rewrite the table each time - it's very fast on the client and sooo much
simpler.

Andrews code will work just fine (and a lot of people may prefer it) but if
you're interested I've got an abstraction component that might help. It
maintains an ordered set of objects (essentially abstracting Andrews array
into an object and providing management and sorting methods). Sorry, long
URL coming:

<
http://www.depressedpress.com/depre...t/Extensions/DP_ObCollectionOrdered/Index.cfm >

There's an example on that page of sorting a table using the component.

Using this Andrews original code might look like this:

// This creates a new ordered collection and makes the "ID" field the
key
MyData = new DP_ObCollectionOrdered("id", Object);
// Add the data - you need to name the properties if you want to sort
them here (Andrew's is less verbose in that respect).
MyData.add( {id: "1", name:"First Name", address:"First Address",
phone:"First Phone" } );
MyData.add( {id: "2", name:"Second Name", address:"Second Address",
phone:"Second Phone" } );
MyData.add( {id: "3", name:"Third Name", address:"Third Address",
phone:"Third Phone" } );

You could then sort the data by any property like this:

MyData.sortByProp('id', 'Numeric', 'asc');

MyData.sortByProp('address', 'AlphaNoCase', 'asc');

MyData.sortByProp('name', 'Alpha', 'desc');

And so forth.

You also get all sorts of "rank" (position in the collection) methods - you
can swap elements, move them up or down one or more steps or just move them
around using only a method call.

Also, before you pull your hair out: IE won't let you write into a tbody
tag... it's a damn pain in that respect. It doesn't even give a good error
(just an "unknown exception" or some such). Andrew's code will work
perfectly fine in FireFox but will error in IE on the
eTableBody.innerHTML=""; (well... at least it does for me).

Because of this it's usually simpler to just write the whole table (with the
header) into a <div> (the example on my site does this and works in both IE
and FireFox). It's not elegant, but it works.

Jim Davis
 
R

RobG

Hi

I have a javascript problem that has been annoying me for two days now
and thought that a javascript expert might have the magic solution.

I am populating a table dynamically from the database and I am trying
to allow the user to order the rows in the table using up and down
arrows.

If all you are doing is moving rows up or down based on whether the up
or down arrow is clicked, I think you can do this much more easily.

Your use of document.all will prevent your code from working in a good
number of browsers. Use of window.event will restrict usage almost
entirely to IE.

Solutions for the document.all issue are on the group FAQ:

<URL:http://jibbering.com/faq/#FAQ4_15>

Solutions for window.event are here:

<URL:http://www.quirksmode.org/js/introevents.html>

Here is a simple script for moving rows up or down. The buttons could be
added using an onload function to reduce code bloat and users without
JavaScript would not see the buttons at all.

<script type="text/javascript">

function moveR( el, x )
{
while ( el.parentNode && 'tr' != el.nodeName.toLowerCase() ){
el = el.parentNode;
}
var t = el.parentNode;
var i = el.rowIndex + x;

if ( i < 0 ) i += t.rows.length;
if ( i == t.rows.length ) i = 0;

t.removeChild(el);
var nRow = t.insertRow( i );
t.replaceChild(el, nRow);
}

</script>

<table>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 0</td>
</tr>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 1</td>
</tr>
<tr>
<td>
<input type="button" value="Move up" onclick="moveR(this, -1);">
<input type="button" value="Move down" onclick="moveR(this, 1);">
</td>
<td>row 2</td>
</tr>
</table>

[...]
 
R

RobG

RobG wrote:
[...]
Here is a simple script for moving rows up or down. The buttons could be
added using an onload function to reduce code bloat and users without
JavaScript would not see the buttons at all.

Had a bit more of a play, the following is more concise but maybe more
difficult to maintain as a result:

function moveR( el, x )
{
while ( el.parentNode && 'tr' != el.nodeName.toLowerCase() ){
el = el.parentNode;
}
var t = el.parentNode;
var i = (el.rowIndex + +x)% t.rows.length;
t.replaceChild(t.removeChild(el), t.insertRow(i));
}

The extra '+' in '(el.rowIndex + +x)' ensures that x is a number even if
passed as a string.


[...]
 
R

RobG

Andrew Scott wrote:
[...]
I have to Admit I've never actually tried writing to innerHTML of a
tbody element.

Don't, it will fail in IE. Microsoft say don't use innerHTML on tables.

tbody element. I try to avoid innerHTML as much as possible (just out
of habit). I probably would have done this :

while( eTableBody.firstChild ) { eTableBody.removeNode(
eTableBody.firstChild ); }

or

eTableBody = eTableBody.replaceNode( eTableBody.cloneNode( false ) );

That's cool, the above iterative method will slow as the number of rows
increases, but this method should not.

[...]
 

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
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top